매직코드
article thumbnail

#object_detection #image_labeling #polygon #CVAT #json #bbox #bounding_box_visualization

#bbox_label_visualization

> how to make bounding box(bbox) and polygon with CVAT?

> how to visualized bbox and polygon?

 

컴퓨터비전의 아주 기초단계에는 이미지 라벨징 구축이 있다.

대부분 라벨링을 하고 학습을 시키기 때문에 시각화를 하는건 옵션사항일 수도 있는데, 컴퓨터비전을 처음 배우는 나로써는 하나씩 모든 것을 다 경험해보고 싶은 마음이다.

 

목표

1. 이미지에 직접 라벨링, 폴리곤을 만들기

2. bbox 예측을 포함한 시각화

 

 

1. 이미지 준비

일단은 실습이니까 인터넷에서 스타벅스 이미지를 10개정도 다운받았다.

내가 원하는건 동그라미 형태의 로고와 STARBUCKS라고 써있는 글씨를 구분하는 것이다.

 

starbucks.zip
1.80MB

 

다른 실습용 데이터셋들은 라벨링도 예쁘게 되어있는데 지금 다운받은 스타벅스 이미지들은 라벨링이고 뭐고 아무것도 없는 이미지들이다.

이미지 디텍션을 하기 전에 라벨, 바운딩박스, 폴리곤을 만들어줘야한다.

직접 설정해주는 노가다....이기 때문에 시간이 좀 걸린다.

내가 이용한 바운딩박스, 폴리곤 만들어주는 사이트는 CVAT(Computer Vision Annotation Tool)이다.

 

이 사이트는 유료는 아니고 회원가입은 필요한 사이트라서 goole로 로그인하기 했다.

https://cvat.org/

 

Computer Vision Annotation Tool

 

cvat.org

 

위 사이트에 들어가서 직접 작업해준다.

메인화면 우측 상단에 있는 create a new task를 눌러서 아래 화면이 나오면

Name 적어주고, Labels에 Add label 박스 눌러서 logo, letter 두개를 설정해줬다.

더 추가하고 싶은 사람은 더 추가해줘도 된다.

 

Select files에 드래그앤 드랍으로 내 이미지 파일들을 올려주면 되는데,

파일이 몇개가 올라가 있는지는 10 files selected 라는 문구를 통해 알 수 있다. 시각적으로 딱 보이지 않아서 조금 불편한듯..

 

모든 이미지를 올렸으면 좌측 하단에 submit을 누르고 좀 기다려준다.

언제까지? task가 server에 올라갔다는 안내 팝업이 뜰 때 까지!

submit하고나서 task가 잘 만들어졌는지 모르겠으면 메뉴에 Tasks에 가보면 생성된 리스트가 있다.

Tasks에서 open을 눌러서 job으로 들어간다.

 

job으로 들어가면 해야하는 일들이 나오는데 stage에 annotation을 수행한다고 설정하고 job #308399를 눌러서 작업파일로 들어간다.

바운딩박스를 만들고 폴리곤을 만드는 방법도 있지만, 바로 폴리곤 작업을 수행하면 바운딩박스 좌표는 자동으로 폴리곤의 가장 바깥쪽 좌표로 가져오게 된다. 그래서 나는 바로 폴리곤부터 만들었다.

 

폴리곤을 만드는 작업창은 오각형 모양의 도형이고, 그 위에 마우스를 올려두면 (클릭 아님!) 옆에 창이 뜨는데 거기서 Label을 선택하고, Shape를 누른다. 이제 내가 원하는 시작점부터 하나씩 클릭하면서 만들어도 되고, Shift키를 누르고 마우스만 움직이면 자동으로 포인트들을 찍어준다.

 

모든 포인트를 다 찍었다면 키보드 n을 누르면 작업중인 폴리곤은 끝마치게 되고 새로운 폴리곤을 찍을 수 있게 변한다.

 

각각 polygon shape으로 지정되는 것을 확인할 수 있고, label 역시 내가 정한 라벨로 지정이 되었다.

이렇게 10장을 모두 라벨링 해준다.

 

cvat 폴리곤 영역 변경

한번에 다 잘 만들수는 없는 법인데, 이미 만들어진 폴리곤의 한 포인트 위에 마우스를 올리면 그 포인트에 검은색 테두리가 생긴다.

shift를 누르고 클릭! 하면 그 포인트 색이 회색으로 변하면서 연장선이 마우스를 따라온다.

기존에 폴리곤을 그리던것처럼 원하는 모양으로 클릭클릭 하면서 만들어주고 마지막에 원래 있던 폴리곤의 포인트와 연결해주면 폴리곤 영역이 자동으로 추가된다.

 

모든 이미지에 라벨링을 마쳤으면 좌측 상단에 save를 해준다.

그리고 나서 메뉴에 있는 Tasks를 눌러 다시 task화면으로 돌아온다.

 

tasks에 있는 나의 starbucks 오른쪽 하단에 Actions 옆에 있는 메뉴표시를 눌러서 Export task dataset를 해준다.

여기서 많은 사람들이 사용하는 annotaion 파일은 COCO.json과 PASCAL VOC 파일인데 나는 COCO.json을 사용하려고 한다.

 

Export format을 원하는 형식으로 정해준다음 OK를 누르면 다운이 된다.

여기까지가 이미지 디텍션을 위한 이미지 준비과정이었다.

 

 

 

 

2. 패키지 준비 (Yolov5, convert2Yolo)

이미지가 준비되었다면 사용할 패키지를 설치해보자.

터미널에서 내가 사용할 가상환경을 활성화 시켜주고 거기서 설치하면 된다.

 

# 새로운 가상환경 만들기
conda create -n 가상환경이름
conda activate 가상환경이름

 

필요한 패키지 설치

# yolov5 설치
git clone https://github.com/ultralytics/yolov5  # clone
cd yolov5
pip install -r requirements.txt  # install

# convert2Yolo 설치
cd ..
git clone https://github.com/ssaru/convert2Yolo.git
cd convert2Yolo
pip3 install -r requirements.txt

 

패키지를 설치했으면 가상환경상에 이미지와 json 파일을 올려준다.

쥬피터에 zip파일로 올려도 되고, 하나하나 업로드해도 된다.

나는 zip파일로 올렸다.

 

import zipfile
zipfile.ZipFile('zip경로/파일이름.zip).extractall()

 

현재 가상환경에 올라가있는 파일 리스트들은 아래와 같다.

-가 하나 증가하면 폴더 안쪽에 해당함을 의미한다.

 

(폴더) convert2Yolo

(폴더) yolov5

(폴더) starbucks

    - (파일) class.names (아래서 만듦)

    - (파일) labels.json 

    - (폴더) data

        -- (폴더) images

        -- (폴더) labels (변환된 파일을 저장하기 위해 미리 폴더 생성)

starbucks.zip

 

 

3. label 준비 (.names 와 convert2Yolo / .yaml)

위에서 COCO.json 파일로 labels을 다운받았는데, Yolo에서 이 라벨들을 사용하려면 각 이미지에 해당하는 txt파일이 필요하다.

무슨말이냐면 우리는 지금 10개의 스타벅스 이미지에 대해서 1개의 라벨파일을 가지게 되었는데, Yolo는 10개의 이미지에 대해서 10개의 라벨파일을 매칭하여 가지고 있어야 한다는 뜻이다.

 

하나의 json파일을 10개의 txt 파일로 변환해주는 패키지가 convert2Yolo다.

그런데 conver2Yolo를 사용하려면 우리는 클래스를 구분해둔 class.names파일도 필요하다.

 

3-1. class.names파일 만들기

메모장이나 파이참으로 새 파일을 만들어서 저장할 때 확장자를 .names로 저장하면 된다.

안에 내용은 내가 분류하고자 하는 라벨의 이름을 한줄씩 적어서 저장하면 된다.

 

# class.names 파일 내용

logo
letter

 

너무너무 간단하니깐 그냥 호로록 만들어버리면 된다.

 

3-2. 하나의 json 파일을 이미지에 맞는 10개의 txt 파일로 변환

여기서 convert2Yolo가 사용된다.

 

# convert2Yolo로 이동
cd convert2Yolo/

# json 파일 txt로 변환
'''
python3 example.py \
--datasets 가지고있는 labels 포맷 \
--img_path 이미지 경로 \
--label jason파일 경로 \
--convert_output_path 변환한 txt파일 저장 경로 \
--img_type 이미지타입 \
--manifest_path 해당사항이 없지만 이 옵션을 뺄 수 없어서 기본값 ./ 로 작성
--cls_list_file 위에서 만든 .names파일 경로
'''

python3 example.py \
--datasets COCO \
--img_path ../starbucks/data/images \
--label ../starbucks/labels.json \
--convert_output_path ../starbucks/data/labels \
--img_type ".jpeg" \
--manifest_path ./ \
--cls_list_file ../starbucks/class.names

 

 

이런식으로 complete가 뜨면 잘 변환이 되었다.

convert_output_path에 입력했던 경로로 가서 txt파일이 10개인지 확인해보면 된다.

 

3-3. .yaml 파일 만들기

yaml 파일은 yolo에 데이터 위치, 클래스 개수 등의 정보를 전달하는 파일로 직접 만들 수 있다.

이것도 names 파일처럼 간단해서 다행이다.

터미널에서 만드실 분들은 아래 내용 참고하면 되고 알아서 만들 수 있는 사람은 yaml파일 안에 들어갈 내용이 뭔지만 확인하면 될 것 같다.

 

# 터미널에서 yaml파일 만들기
# 경로 확인 먼저 하시고 원하는 곳으로 이동
cd ./starbucks
vi custom.yaml

---
# 키보드 i 눌러서 편집모드
# 아래 내용 입력하고 esc 눌러서 편집모드 종료
# :wq로 저장 및 닫기

 

path: /home/starbucks/data
train: ./images/train
val: ./images/val

nc: 2 # class 개수
names: ['logo', 'letter']

 

path는 train과 val의 공통경로를 적어주는 곳인데, 보통 yolo를 실행하는 디렉토리 위치는 /home/yolov5 이고, 나는 이미지 데이터를 아에 다른 폴더에 넣어줬기 때문에 path를 지정해주었다. 혹시 이미지를 yolov5안에 넣었다면 path는 별도로 작성 할 필요가 없다.

 

 

4. 디렉토리 설정

이미지 10장을 모두 학습시키면 성능을 평가할만한 지표가 없기 때문에 이미지.jpg 파일을 train 7장, val 2장, test 1장으로 나눠서 폴더를 만들어준다. test는 1장이라서 따로 폴더를 만들지 않아도 되는데 원칙적으로는 폴더를 만들어준다.

 

 

앞으로 우리가 만들고자 하는 디렉토리 모양이다.

실습으로 10장밖에 없으니 수동으로 train, val 파일을 만들어서 이동시켜주면 된다.

 

주의할 점

1. images/train 에 있는 .jpeg 파일 이름과 labels/train 에 있는 .txt파일이름이 서로 매칭이 되게 동일해야한다는 점이다.

2. yolo의 실행파일에서 images 와 labels 폴더명이 지정되어있기 때문에 폴더명은 반드시 images, labels로 작성

 

 

5. Train

 

 

yolov5에서 제공하는 모델은 위와 같다. 가장 왼쪽이 가장 가벼운 모델이고 오른쪽으로 갈수록 시간이 오래걸리지만 정확도가 올라가는 모델이다. 여기서는 시간 단축을 위해 가장 가벼운 모델인 yolov5s를 사용했다가 너무 예측을 못해서 그 다음 단계인 yolov5m을 사용했고 배치나 에폭은 따로 조절해주지 않았다.

 

# yolov5로 경로이동
cd ../yolov5

# train
'''
python train.py \
--img 이미지 사이즈 \
--batch 배치 사이즈 \
--data custom.yaml 파일경로 \
--cfg 사용할 모델의 yaml 파일경로 \
--weights 학습에 사용할 모델 \
--name 학습된 정보를 runs 폴더 안에 저장할 이름 \
--project wanbd에 저장할 프로젝트명
'''

# 여러 파라미터 중 핵심만 사용
python train.py \
--data ../starbucks/custom.yaml \
--weights yolov5m.pt

# 조금 더 조절하고 싶은 경우
python train.py \
--data ../starbucks/custom.yaml \
--weights yolov5m.pt \
--batch ?? \
--epochs ??? \
--name starbucks

 

위에서 train, val, test를 7개, 2개, 1개로 나누라고 했었는데 나는 조금 다르게 train 8개, val 2개를 학습시키고 기존의 10개의 이미지를 하나로 합친 새로운 이미지를 만들어서 test를 진행해봤다.

val의 경우 python val.py를 통해서 실행할수도 있지만 train.py를 실행하면 val도 자동으로 학습되기 때문에 따로 진행하지는 않았다.

혹시 val 진행을 알고싶다면 아래 코드를 참고하면 된다.

 

python val.py \
--data ../starbucks/custom.yaml \
--weights 'runs/train/starbucks2/weights/best.pt'

 

학습결과는 yolov5/runs/train/starbucks에 저장이 되어있다.

안에 많은 jpg, png파일이 있는데 중요하게 볼만한거는 confusion_matrix.png / val_batch_pred.jpg 파일이다.

혹시 val_pred 파일에서 예측을 잘 못했다면 좀 더 정밀하게 학습시킬 필요가 있다.

 

 

왼쪽이 직접 레이블링 한 정답이고 오른쪽이 val_pred 한 결과이다.

엄청 잘 잡지는 못했지만 어느정도 학습이 되었다는게 보인다.

 

6. Test

test역시 비슷한 코드로 진행이 된다.

test라고 했지만 inference라고 생각하면 될 것 같다.

trainr에서는 weights에 욜로에서 제공하는 모델명을 썼다면 test에서는 학습된 모델 중 가장 좋은 모델을 사용하도록 runs/train/starbucks/weights/best.pt를 작성해준다는 것이다.

 

'''
python detect.py \
--source 테스트할 이미지 경로 \
--weights 'runs/train/starbucks/weights/best.pt'
'''

python detect.py \
--source /home/starbucks/images/starbucks11.jpg \
--weights 'runs/train/starbucks/weights/best.pt'

 

 

로고는 그럭저럭 잘 잡았지만 글씨는 거의 못잡았다.

이미지 10개로 학습시켰는데 이정도 나왔다는거는 학습에 의의를 두었다고 생각하고... yolov5 object detection 실습 완료!

 

 

profile

매직코드

@개발법사

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!