가장 많이 사용되어지는 Annotation Tools 인것 같으며, 저장되는 형식은 XML이며 Pascal VOC 와 YOLO로 구분되어 저장가능하다.
LabelImg 설치방법 및 소스
https://github.com/tzutalin/labelImg
- LabelImg Download 및 필요 Package 설치
$ cd /works/custom $ git clone https://github.com/tzutalin/labelImg.git $ cd labelImg
$ sudo apt install pyqt5-dev-tools $ sudo pip3 install -r requirements/requirements-linux-python3.txt $ make qt5py3
소스기반으로 설치한 이유는 직접소스에서 HotKey를 변경하기 위해서 상위와 같이 설치
만약 쉽게설치하고 싶다면 pip install 로도 설치가능
참고
https://eehoeskrap.tistory.com/331
- Source 에서 직접 아래와 같이 HotKey 변경
소스를 보면 python으로 작성이 되어있어 쉽게 이해가능하므로, 소스로 설치하여 본인이 원하는 곳을 고치자.
$ vi labelImg.py 212 openNextImg = action(getStr('nextImg'), self.openNextImg, 213 # 'd', 'next', getStr('nextImgDetail')) 214 'f', 'next', getStr('nextImgDetail')) .... 216 openPrevImg = action(getStr('prevImg'), self.openPrevImg, 217 # 'a', 'prev', getStr('prevImgDetail')) 218 's', 'prev', getStr('prevImgDetail')) .... 223 save = action(getStr('save'), self.saveFile, 224 # 'Ctrl+S', 'save', getStr('saveDetail'), enabled=False) 225 'a', 'save', getStr('saveDetail'), enabled=False) .... 240 createMode = action(getStr('crtBox'), self.setCreateMode, 241 # 'w', 'new', getStr('crtBoxDetail'), enabled=False) 242 'e', 'new', getStr('crtBoxDetail'), enabled=False) .. 246 create = action(getStr('crtBox'), self.createShape, 247 # 'w', 'new', getStr('crtBoxDetail'), enabled=False) 248 'e', 'new', getStr('crtBoxDetail'), enabled=False)
Hotkey
w Create a rect box : e 변경
d Next image : f 변경
a Previous image : s 변경
Ctrl + s Save : a 변경
상위와 같이 변경한 이유는 한 손에 전부 넣어 빨리 편집하기위해서 Hot Key를 변경
- LabelImg 실행 (Args는 옵션)
2nd Arg : Annotation 할때 붙여지는 Class 정의된 File을 직접 선택가능
$ python3 labelImg.py
$ python3 labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
- 실행하면 좌측에 메뉴
- OpenDir : Image 위치설정
- Change Save Dir : Xml 저장위치설정
실행시 이전에 저장되어진 Xml 저장위치 기준으로 XML를 가져와서 BBOX를 표시를 해준다.
https://tensorflow-object-detection-api-tutorial.readthedocs.io/en/latest/training.html#annotating-images
1.1 파일이름 변경 방법
본인이 원하는 DATA Image들을 다운을 받고 여러 파일들을 한꺼 번에 이름을 변경하고자 할때 많을 것 같다.
아래와 같이 rename 명령어를 사용하거나 간단하게 Shell script를 이용하여 만들어서 이를 해결하자
- rename 명령어를 이용하여 파일이름 변경
$ ls image_01.jpg image_02.jpg image_10.jpg $ rename 's/image/image_test/' *.jpg image_test_01.jpg image_test_02.jpg image_test_10.jpg
rename 명령어로 특정 Pattern이 있는 것을 찾아 이름을 변경을 해보자.
만약 특정 Pattern이 없다면 아래와 같이 Shell Script를 사용해서 본인이 원하는 대로 변경하자
- rename.sh shell script 작성(rename 명령어로 한계가 있어 Shell Script 직접작성함)
- rename.sh shell script 실행
$ cd ~/works/custom/data/images $ chmod +x rename.sh $ ./rename.sh // *.jpg 파일들을 찾아 image_xx.jpg로 변경 or $ ./rename.sh Image_data .png // *.png 파일들을 찾아 image_data_xx.png 로 변경
1.2 DATA SET 구성 과 Annotation 진행
- DATA SET 구성
$ cd ~/works/fire/data $ mkdir -p images/train $ mkdir -p images/test $ mkdir -p annotation/train $ mkdir -p annotation/test $ tree -L 2 . ├── annotation │ ├── test // test xml (pascal voc type) │ └── train // train xml (pascal voc type) └── images ├── test // test image (eval) └── train // train image
- LabelImg class 정의
$ cd /works/custom/labelImg $ vi data/fire_classes.txt fire smoke
주의
상위 정의된 이름과 label_map.pbtxt에 정의된 이름이 완전히 동일해야 한다.
XML에서 이름만 가지고 찾아 찾기 때문에
- labelImg (train)
좌측 Change Save Dir 로 XML 저장장소 ~/work/fire/data/annotation/train 변경
$ python3 labelImg.py ~/works/fire/data/images/train data/fire_classes.txt
- labelImg (test)
좌측 Change Save Dir 로 XML 저장장소 ~/work/fire/data/annotation/test 변경
변경을 하자마자 바로 적용이 안되므로 Prev Image / Next Image 로 Refresh
$ python3 labelImg.py ~/works/fire/data/images/test data/fire_classes.txt
1.3 label map file 생성 및 정의
본인이 원하는 item을 정하여 각각의 name id를 정의해서 넣자
- lable map 만들기
$ cd ~/works/fire/data // 상위 이름과 동일 $ vi label_map.pbtxt item { id: 1 name: 'fire' } item { id: 2 name: 'smoke' }
https://tensorflow-object-detection-api-tutorial.readthedocs.io/en/latest/training.html#creating-label-map
1.4 TF Record File 변환
TF Record 는 기본으로 Tensorflow가 설치가 되어야 가능하므로 이전에 설치진행 혹은 Docker에서 진행
Tensorflow Manual
https://tensorflow-object-detection-api-tutorial.readthedocs.io/en/latest/training.html#creating-tensorflow-records
- Tensorflow 실행 및 준비
$ docker run --gpus all --rm -it \ --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 \ -p 8888:8888 -p 6006:6006 \ -v /home/jhlee/works/fire/data:/data \ --ipc=host \ --name nvidia_ssd \ nvidia_ssd root@3aac229c45c3:/workdir/models/research# pip install lxml //XML를 위해 필요 root@3aac229c45c3:/workdir/models/research# vi create_pascal_tf_record.py //아래의 소스로 작성
- Pascal SET 을 TF Record 생성
왜냐하면 아래의 소스를 보면 --data_dir 과 XML의 folder로 찾아 넣는다.
root@3aac229c45c3:/workdir/models/research# python create_pascal_tf_record.py \ --data_dir=/data/images \ --annotations_dir=/data/annotation/train \ --label_map_path=/data/label_map.pbtxt \ --output_path=/data/train.record /workdir/models/research/object_detection/utils/dataset_util.py:75: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead. if not xml: root@3aac229c45c3:/workdir/models/research# python create_pascal_tf_record.py \ --data_dir=/data/images \ --annotations_dir=/data/annotation/test \ --label_map_path=/data/label_map.pbtxt \ --output_path=/data/test.record /workdir/models/research/object_detection/utils/dataset_util.py:75: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead. if not xml:
2. create_pascal_tf_record.py 소스 분석
create_pascal_tf_record.py를 간단히 분석을 해보면, XML 기반으로 JPEG Image를 넣어 TF Record를 만들어 넣는다.
https://github.com/vijendra1125/Tensorflow_Object_detection_API-Custom_Faster_RCNN/blob/master/extra/create_pascal_tf_record.py