티스토리 뷰

2022학년도 텀프로젝트로 진행했던 내용입니다.

 


 

1. 배경 및 프로젝트 목표

 

전면적으로 대면 수업이 진행되면서 캠퍼스가 활기를 되찾고 있다. 그에 따라 공유형 전동킥보드(지쿠터, 씽씽이 등)들을 교내에서 쉽게 볼 수 있게 되었다. 이들은 짧은 거리를 효율적으로 이동할 수 있다는 장점이 있지만, 최근에는 안전 수칙이 잘 지켜지지 않아 위험한 존재로 대두되고 있다.

2021년에 도로교통법 개정으로 전동킥보드 등 개인형 이동장치(PM)에 대한 범칙금 등 규제 강화가 되었지만 잘 지켜지지 않으며, 단속이 어려운 실정이다. 이에 대학교를 중심으로 '교내 통행 금지' 움직임이 불고 있다. 우리 대학 또한 2021년 10월, 구성원들의 안전을 위해 학생처장 명의로 '교내 전동킥보드 통행 금지'를 공지했다.

이에 대학에서는 후문에 인원을 배치해 교내 전동 킥보드 출입을 막을수 있도록 하고있다. 하지만 매번 인원을 배치해 감시하는 것은 비효율적이고 여러 한계가 있다. 이에 Yolo를 통한 객체 인식으로 전동 킥보드 사용자의 출입을 탐지해 자동으로 기록하는 프로젝트를 제시한다.

 

 

방법은 다음과 같다.

 

1. Yolov5를 이용해 전동 킥보드 탑승 이미지를 학습시켜, 모델을 구축한다.

2. 구축된 모델이 실시간으로 교내를 감시하고 전동 킥보드 탑승자를 탐지했다면 해당 이미지를 저장한다.

 

 

 

2. YOLOv5

YOLO는 You Only Look Once의 약자로 딥러닝 기반 객체 감지(Object detection) 알고리즘이다. YOLO는 준수한 성능을 보여주며 여러 버전으로 계속 출시되고 있다. 이 프로젝트에서는 YOLO중 v4에 비해 용량은 낮지만 빠른 속도를 가진 YOLOv5를 사용하여 실시간 객체 탐지를 실행한다.

YOLOv5 가이드에 따라 Google Colab에서 학습 환경을 구현할 것이다.

 

 

GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite

YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite. Contribute to ultralytics/yolov5 development by creating an account on GitHub.

github.com

 

 

 

 먼저 YOLOv5를 설치한다. Git clone을 사용하여 다운받을 수 있다. 코드를 실행하면 content/yolov5가 생성된 것을 확인할 수 있다.

 

 

 

 

3. 데이터

구글에서 직접 이미지 데이터들을 모아 데이터 셋을 구성하였다. YOLOv5에서 요구하는 형식에 맞추어 다음과 같이 디렉토리를 생성하였다.

 

 

 

처음에는 킥보드 탑승자를 중심으로 한 개의 클래스로 데이터를 수집한 뒤 학습을 진행했었다.

 

 

하지만 탑승자 + 킥보드를 객체영역으로 설정하니 보행자 까지 탑승자로 인식하는 문제가 발생하였다. 후에 보행자를 분리하여 인식시키기 위해 데이터를 추가 및 변경하였고 최종적으로 훈련데이터 셋 총77개, 테스트(검증) 데이터 셋, 11개로 학습을 진행하였다. (이미지의 파일명과 데이터 개수는 관계가 없다)

 

 

 

 

 

4. 데이터 라벨링

위 수집한 이미지에 대한 바운딩 박스 데이터를 라벨링하기 위해 사이트 https://www.makesense.ai/ 를 이용하였다. 웹사이트라 접근이 쉽고, 별도의 가입없이 사용이 가능하다. 자바 스크립트로 작성되어 속도도 굉장히 빠르며 yolo 형식의 라벨링을 지원한다.

 

 

Make Sense

 

www.makesense.ai

 

메인 페이지에서 GetStarted를 누르면 사이트에 이미지들을 적재할 수 있다.

데이터가 들어있는 폴더(images/train, images/val)을 드래그 앤 드롭하여 사용하였다.

 

 

 

이어 클래스 레이블을 추가한다. 탑승자를 scooter, 보행자를 person으로 클래스를 생성하였다. 

 

 

 

그리고 인식하고자 하는 모든 객체들에 대해 바운딩 박스를 그려주고 클래스를 지정해준다. 모든 이미지에 대한 레이블 처리가 끝났다면 Action  ExportAnnotions  A .zip package containing files in YOLO format.를 선택해 YOLO 형식으로 저장한다.

 

 

이를 압축 해제한 후 train_data 하위의 훈련데이터 레이블 폴더 labels/train과 테스트 데이터 레이블 폴더 labesl/val에 각각 배치한다.

 

 


아래는 실제 7.txt의 내용이다. 첫번째 줄을 해석해 보면 클래스 0, 전동킥보드 객체이며, 그리드에서 바운딩 박스의 x 좌표는 0.686014, y좌표는 0.501035, 너비는 0.220404, 높이는 0.931677가 된다. 이렇게 탑승자 3, 보행자 2로 5개의 객체가 해당 사진에 있는 것을 확인할 수 있다.

 

 

 

 

 

완성된 데이터 셋은 zip형식으로 Colab에 업로드하고, 압축을 해제한다.

 

 

 

 

5. YOLOv5 학습

YOLOv5와 데이터 셋이 준비되었다면, 이제 학습을 진행한다. YOLOv5는 학습에 python train.py를 사용한다. 이에 정의된 여러 파라미터를 지정해 학습을 진행할 수 있다.

 

 

이 중 사용한 파라미터들을 분석해 보면 다음과 같다.

 

- img : 이미지의 크기를 지정한다. YOLOv5는 학습할 때 모든 이미지 사이즈를 동일하게 resizing 하기 때문에 별도의 이미지 처리가 필요하지 않다. 단, 검증시 같은 이미지 크기를 지정해야 일정한 성능이 나온다. 디폴트 값은 640이다.

- batch : 학습시 한번에 처리할 이미지의 수이다.

- epochs : 학습의 반복 횟수이다.

- data : 데이터셋의 파일 경로를 지정한다.

- weights : 모델 구조를 지정한다. YOLOv5는 다양한 모델 구조를 제공한다. 가장 간단한 모델은 YOLOv5s이며, 이외에도 YOLOv5m, YOLOv5l, YOLOv5x가 있다. (오른쪽으로 갈수록 구조가 복잡해지며, FPS가 낮아진다.)

 

- cache : 빠른 훈련을 위해 캐싱 이미지를 사용한다.

 

 

 

또한 코드에서 사용한 --data 파라미터의 costom.yaml은 다음과 같다.

데이터셋의 경로와 클래스 수, 클래스 이름을 담고 있다. YOLOv5는 이 파일에 적혀있는 데이터 셋과 클래스 정보를 이용해 학습을 진행한다.

 

 

 

 

 

학습이 완료된 모습이다. mAP값이 0.935로 좋은 성능을 보여준다. 이렇게 학습을 마치면 /yolov5/runs /train 경로에 exp*디렉토리가 생성되는데, 이 폴더에서 여러 학습에 대한 진행 상황과 결과를 확인할 수 있다.

 

 

그 중 val_batch*.jpg은 테스트(검증)데이터에 대한 바운딩 박스 예측 결과를 확인할 수 있다.


val_batch0_labels.jpg

 

 

- val_batch0_pred.jpg

 

 

 

 

 

 

results.png에서는 여러 손실함수들과 지표를 그래프로 확인할 수 있다.

 

 

Yolo에서는 모델의 성능을 mAP으로 평가한다. 앞서 학습된 언급했듯이 mAP가 높을수록 좋은 성능을 가졌다고 할 수 있다. 그럼 mAP이란 무엇이고 mAP(0.5:.05:0.95)은 무엇을 의미하는 걸까?

 

IoU(Intersection over union)는 객체 검출 모델의 정확도를 측정하는데 사용되는 지표이다. 예측 바운딩 박스가 빨간색 정답 바운딩 박스가 초록색이라고 할 때, 겹치는 부분(교집합) / 전체 부분(합집합)한 값을 의미한다. 즉 겹치는 부분이 많을수록, 점수가 높아진다.

 

 

 

보통 이러한 IoU점수가 0.5 이상인 경우를 TP(true positive)로 인식한다고 한다. 이러한 IoU를 기준으로 Precision과 Recall를 정의할 수 있다.

Precision = TP / TP + FP       Recall = TP / TP + FN

 

이 둘은 반비례 관계에 있기에 한쪽의 값만으로 성능을 평가하는 것은 적절하지 않다. 따라서 두 값을 종합해 평가하고자 사용하는 방법이 AP이고 이를 모든 클래스에 대해 평균낸 것이 mAP이다. 그리고  IoU 값의 기준을 0.5, 0.55, 0.6~ 0.95일 때에 mAP값을 각각 계산하고 평균낸 값이 mAP(0.5:.05:0.95)이다.

 

 

 

 

 

6. 모델 적용

이제 학습한 모델을 이용해 테스트 영상에 적용해본다. 테스트 영상은 유튜브에서 추출하였으며, 여러 보행자와 전동 킥보드 탑승자가 등장한다.

 

 

적용에는 detect.py를 사용한다. 사용한 파라미터들은 다음과 같다.

 

- weight : 학습한 모델의 weight를 넣어준다. 학습이 끝나면 exp폴더에 weight가 저장된다. 그 중 성능이 가장 좋은 것이 best.pt이다.

- img : 이미지의 크기이다. 모델 학습시 사용한 동일한 크기를 넣어준다.

- conf : 신뢰 임계값이다. 임계값 이상의 객체들만 바운딩 박스를 그린다

- save-crop : 인식된 객체의 이미지를 저장하는 옵션

- source : 모델을 적용할 데이터이다. 이미지, 영상등 다양한 소스가 사용될 수 있다.

 

 

 

코드 실행시 프레임당 객체를 인식하여 바운딩 박스가 그려진 출력 영상을 생성한다. 영상을 확인하니 보행자와 탑승자를 개별적으로 인식에 성공한 것을 확인할 수 있다.

 

 

 

 

 

7. 이미지 저장

학습한 모델을 이용해 전동 킥보드 탑승자를 가려낼수 있었으며 –save-crop 옵션으로 인식된 객체의 이미지를 폴더에 저장할 수 있었다.  이어서 detect.py를 수정하여 감지된 탑승자의 이미지를 저장하고 확인할 수 있도록 한다. 글로벌 변수 flag를 선언하고, 다음과 같이 인식된 객체가 scooter일 때만, flag를 증가시키고, 이미지를 exp*/scooter에 저장할 수 있도록 하였다. 즉 flag는 탑승자가 감지된 횟수이다.

 

모든 예측후에 감지 횟수와 저장 경로를 출력하도록 print문을 작성하였다.

 

 

 

그리고 다시 한번 detcet.py를 이용해 영상에 모델을 적용하였다.

마지막에 감지횟수와 저장경로가 출력된 것을 확인할 수 있다.

 

 

 

 

잘 저장되었는지 OpenCV를 이용해 해당 폴더에 저장되어있는 이미지 파일들을 읽어와 출력해 본다. 폴더의 명은 위에서 출력된 폴더명을 가져와 뒤에 덧붙힌다.

 

 

OpenCV를 이용해 화면에 이미지 출력할 때, 보통 cv2.imshow 명령을 사용한다. 하지만 이 명령은 기본 OS에 깔린 유틸리티로 이미지를 열게 해주는 기능이기 때문에 온라인 기반 IPython에서는 실행이 불가능 하다. 이에 colab에는 from google.colab.patches import cv2_imshow를 대신 제공하고 있다. 이를 이용한다.

 

 

라이브러리 적재 후 편의를 위해 아래 두 함수를 작성한다.

 

 

- ResizeWithAspectRatio( ) : 이미지가 너무 크게 출력될 시 확인이 어렵기 때문에 이미지를 리사이징한다. 너비를 인수로 받아 너비를 고정하고 비율을 유지하며 리사이징한 이미지를 반환한다.

 

 

 

- Load_images_from_folder( ) : 폴더명을 받아 해당 폴더의 모든 이미지들을 읽어 리스트로 반환한다.

 


그리고 반복문을 통해 위 함수들을 호출하고 폴더에 저장된 이미지들을 읽어 리사이징후 출력하도록 한다.

 

 

 

전동킥보드 사용자가 잘 감지되었으며, 이미지 또한 잘 저장된 것을 확인할 수 있다. 

 

 

 

 

감사합니다.

 

 


공부한 내용을 복습/기록하기 위해 작성한 글이므로 내용에 오류가 있을 수 있습니다.

 

댓글
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Total
Today
Yesterday