본 게시글에서는 yolov5를 이용하고, Pytorch를 통한 커스텀 학습을 통해 우리집 고양이인 "몰리"의 머리, 발, 몸통, 꼬리를 탐지해보고자 한다.
yolov5의 설치에 관해서는 github를 참조하였다.
ultralytics/yolov5
YOLOv5 in PyTorch > ONNX > CoreML > TFLite. Contribute to ultralytics/yolov5 development by creating an account on GitHub.
github.com
먼저 원본 동영상은 몰리를 내 발.....로 놀아주는 영상이다.
해당영상은 총 16초의 30fps 동영상이므로 10프레임 마다 동영상 프레임을 저장하여 총 48개의 학습용 이미지를 만들어 주었다.
이미지 캡쳐 코드는 다음과 같다.
import cv2
vidcap = cv2.VideoCapture('./cat.mp4')
count = 0
while(vidcap.isOpened()):
ret, image = vidcap.read()
if(int(vidcap.get(1)) % 10 == 0):
print('Saved frame number : ' + str(int(vidcap.get(1))))
cv2.imwrite("./img/cat_%d.jpg" % count, image)
print('Saved frame%d.jpg' % count)
count += 1
vidcap.release()
이제 학습시키기위한 라벨링을 하기위해 labelimg를 통해 라벨링을 해주었다.
tzutalin/labelImg
🖍️ LabelImg is a graphical image annotation tool and label object bounding boxes in images - tzutalin/labelImg
github.com
predefined_classes.txt에 head, tail, foot, body와 같이 라벨을 사전 지정해주고, 해당 파일을 이용해 labelimg를 실행시켜준다.
predefined_classes.txt
head
body
tail
foot
그후, labelimg를 라벨링할 이미지가 있는 경로, pre_definedclasses가 있는 경로로 실행시켜준다.
labelimg ./img ./result/predefined_classes.txt
다음과 같이 각 객체들을 직접 라벨링 하고, 이름이 틀리지 않도록 지정해준다.
모든 사진을 다 똑같이 해준다. (일일히 해주는 방법밖에 없다. 경우의 수가 늘어날수록 정확도도 증가하고, 학습의 좋은 재료가 된다.)
나는 총 20장만 우선 라벨링을 하고, 학습시켜 보도록 해야겠다.
라벨링을 완료하면 결과폴더로 지정한 곳에 각 사진의 txt파일과 classes파일이 생성된 것을 확인 할 수 있다.
이제 yolo를 설치한 폴더로 간 후 cat폴더를 생성한 후, images폴더를 만들어 학습시킬 이미지를 넣어주고 labels폴더를 만들어 방금 위에서 라벨링 후 생성된 txt파일들을 모두 넣어준다.
그후 data폴더에 cat.yaml파일을 하나 생성한 후 다음과 같이 내용을 채워준다.
# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]
train: ./cat/images/
val: ./cat/images/
# number of classes
nc: 4
# class names
names: ['head','body','tail','foot']
나는 train과 validation을 따로 구분하지 않을 것이기 때문이 train과 val의 경로를 똑같이 해주었다.
nc에는 class의 개수, names에는 아까 라벨링할 때 지정했던 이름들을 넣어준다.
그리고 yolov5폴더 내에 train_list.txt, val_list.txt파일을 만들어 학습시킬 이미지들의 경로를 모두 적어준다.
train_list.txt파일 예시는 다음과 같다.
이걸 일일히 입력하기는 매우 귀찮은 일이기 때문에, yolov5/cat/labels폴더에 있는 txt파일들을 이용해 텍스트 slice를 적용하여 만들어 주었다.
-- train_list.txt, var_list.txt 작성 코드
import glob
input_dir='C:\\Users\\syjin\\Desktop\\object\\yolov5\\cat\\labels\\'
f = open('./train_list.txt', 'w')
input_file=glob.glob(input_dir+'*.txt')
for file in input_file:
f.write(file[:41]+'images\\'+file[48:-4]+'.jpg \n')
f.close()
f = open('./val_list.txt', 'w')
for file in input_file:
f.write(file[:41]+'images\\'+file[48:-4]+'.jpg \n')
f.close()
이제 학습을 시켜줄 차례이다.
pytorch로 학습이 진행되기 때문에 위 yolov5 github를 참고하여 환경을 맞추어 설치해주어야 한다.
anaconda prompt로 yolov5가 설치되어 있는 폴더로 이동 한 후 다음과 같이 입력한다.
python train.py --data ./data/cat.yaml --cfg ./models/yolov5s.yaml --weights yolov5s.pt --batch 8 --epochs 200 --name cat200
아까 만들어준 cat.yaml파일의 경로를 입력해주고 사용할 pretrained모델을 입력해준다.
batch size=8, epoch=200으로 하여 총 200번의 학습을 진행 할 것이다. 그리고 마지막에는 학습된 가중치 파일이 저장될 경로를 적어준다.
pretrained model download
Releases · ultralytics/yolov5
YOLOv5 in PyTorch > ONNX > CoreML > TFLite. Contribute to ultralytics/yolov5 development by creating an account on GitHub.
github.com
모델의 경우 s, m, l, x 사이즈가 있는데 사이즈가 작을수록 가벼우며, 클수록 무겁다.
물론 이에따라 성능도 달라진다. 사용자에 맞추어 파일을 다운로드 한다, 나는 s사이즈를 이용했다.
코드를 입력하면 다음과 같이 학습이 진행될 것이다. 기다려보자...
학습이 완료 된 후, 각 라벨의 R값을 보면 foot의 경우가 0.431로 가장 낮다, 발의 경우 몸이나 머리에 비해 크기가 작다보니 탐지 성능이 낮게 나오는 것 같다. 물론 학습을 더 많이 시켜주면 발의 탐지정확도 역시 올라 갈 것이다.
이제 학습된 가중치 파일은 yolov5폴더 내 runs/train/cat200/weight폴더에 형성되어 있을 것이다. 이를 이용해 한번 동영상에 적용 시켜보자.
학습시킬때와 마찬가지로 anaconda prompt에서 다음과 같은 명령을 입력해준다
python detect.py --source ./data/videos/cat.mp4 --weights ./runs/train/cat200/weights/best.pt
탐지결과는 위 동영상과 같다. 물론 학습 횟수도 200번이며, 학습시킨 이미지도 20장에 불과하기때문에 탐지율이 그렇게 좋진 않지만 어느정도 각 부분을 탐지해내는 것을 볼 수 있다.
또한 사용 모델의 사이즈를 s로 사용했지만 보유한 컴퓨터의 성능에 따라 m, l, x모델을 이용하여 학습한다면 탐지 성능은 더 올라갈 것이다.
yolov5 m모델을 이용하여 1000번 학습시킨 결과 ↓
위에 업로드한 S모델을 이용한 200번 학습 결과보다 훨씬 좋은 탐지성능을 보인다.
'Python > Object Detecting' 카테고리의 다른 글
[python] YOLOv5 이용 객체탐지 및 실시간 Object size 측정하기 (21) | 2021.08.01 |
---|---|
[python] 윈도우 환경에서의 Darkflow를 이용한 youtube(유튜브) 동영상 Object Detecting(객체 탐지) (0) | 2021.04.24 |
댓글