코딩헤딩

Deep learning[딥러닝] YOLO 객체탐지 네트워크 기초 본문

머신러닝 | 딥러닝

Deep learning[딥러닝] YOLO 객체탐지 네트워크 기초

멈머이 2024. 1. 10. 21:00
728x90

<YOLO(You Only Look Once)>
  - "욜로"라고 칭한다.
  - 한 개의 네트워크(계층, 모델 같은 의미로 칭함)에서 객체(물체, 사물)를 탐지
  - 탐지된 개체의 영역(바운딩 박스-사각형)과 객체의 이름(사람, 고양이, ...)을 표시해 주는 기능을 수행함
  - 객체 탐지 기술이라고 해서 "Object Detection"이라고 언어 소통이 된다.

  - 객체탐지는 컴퓨터 버전 기술의 세부 분야중 하나로 주어진 이미지 또는 영상 내에 사용자가 관심 있는 

     객체를 탐지하는 기술을 의미함
  - 객체탐지 모델을 만들기에 앞서
     => 바운딩 박스를 만드는 것이 우선시 되어야 함
  - 바운딩 박스란?
     => 사각형의 시작 좌표(x1, y1), 종료 좌표(x2, y2)로 표현되는 타겟 위치(객체 위치)를 사각형으로 표현한 것을 의미함.

<YOLO원리>
  - 이미지를 입력으로 받음(이미지파일 또는 카메라에서 들어오는 영상)
  - 이미지파일, 영상파일 등을 이용해서 numpy의 배열(array)로 데이터 생성이 가능하다면 처리가능
  - 이미지 내부를 격자(그리드)로 세분화해서 예측하는 구조를 가짐
  - 예측된 부분은 바운딩박스로 그려줌
  - 이미 훈련된 모델을 사용할 수 있기 떄문에, 별도의 훈련모델을 생성하지 않아도 됨
    (경우에 따라, 별도의 객체 인자를 위해 재훈련하여 사용하는 경우도 있음)

<YOLO 사용법>
  - YOLO를 사용하기 위해서는 YOLO기반의 딥러닝 프레임워크가 필요함
  - YOLO기반의 딥러닝 프레임워크 종류
  
     => DarkNet 프레임워크
        - YOLO 개발자가 만든 프레임워크
        - 장점 : 객체 탐지 속도가 빠름, GPU 또는 CPU와 함께 사용가능
        - 단점 : 리눅스 운영체게(OS)에서 안적적으로 작동됨 / CPU와 GPU 동시 사용 시에 속도가 빠름
    
    => DarkFlow
        - 장점 : DarkNet과 동일 / 리눅스, 윈도우, 맥과 호환 가능
        - 단점 : 설치가 매우 복잡함
    
    => OpenCV 프레임워크
        - 주로 사진 개발테스트 시에 많이 사용되는 프레임워크
        - 장점 : 설치가 간단하며, 리눅스, 윈도우, 맥과 호환가능
        - 단점 : CPU에서만 작동함 / 실시간 영상 처리 시에 속도가 다소 느릴 수 있음


* YOLO모델 및환경파일 다운로드 및 설정

0. 파일관리 폴더 생성
   - yolo 생
1. YOLO가중치(Weight) 파일 다운로드하기
   - https://pjreddie.com/media/files/yolov3.weights
   - https://pjreddie.com/media/files/yolov2-tiny.weights

2. YOLO환경설정 파일 다운로드하기  
   - https://github.com/pjreddie/darknet 접속 후 [다운로드] > 압축 풀기
   - cfg 폴더 안에 -> "yolov3.cfg", "yolov2-tiny.cfg" 2개 파일을 config 폴더 안에 위치시기키
   - data폴더 안에 "coco.names" 1개 파일을 config 폴더 안에 위치 시키

3. 테스트 데이터 다운로드하기(자동차 데이터셋 사용)
   - https://www.kaggle.com/sshikamaru/car-object-detection
   - 오른쪽 상단 [다운로드] 클릭 > 다운로드 > 압축 풀기
   - 다운로드한 폴더 내에 "data" 폴더를 사용
   - data 폴더 이름은 cardataset으로 변경 후 yolo/폴더 밑으로 위치하기

4. OpenCV 프레임워크 설치하기
   - 가상환경 활성화 > pip install opencv-python

 


<자동차 좌표값을 이용해서 이미지에 바운딩 박스 그리기>

 

* 사용 라이브러리 

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

### openCV 프레임워크 라이브러리
import cv2

 

* 자동차 데이터셋에서 바운딩 박스 정보 읽어 들이기

box = pd.read_csv("./yolo/cardataset/train_solution_bounding_boxes (1).csv")
box.info()

 

 

 

- 자동차 이미지별 => 바운딩 박스 정보 데이터 읽어 들이기
    - > 변수명 : box
    - > 사용데이터파일 : train_solution_bounding_boxes (1).csv

 

 

 

 

 

 

* 자동차 이미지 바운딩박스 표시하기(Object Detection)

- 샘플 자동차 이미지 1개 가지고 오기
     - > imread() : 이미지파일을 읽어 들이는 함수
     -> 반환값은 이미지 데이터(3차원 이미지 픽셀 데이터)
     -> sample1.shape = (높이, 너비, 체널, 흑백은 0, 컬러는 3 (RGB 또는 BGR))

sample1 = cv2.imread("./yolo/cardataset/training_images/vid_4_1000.jpg")
print(sample1.shape)
sample1

결과 : 

(380, 676, 3)
array([[[255, 211, 128],
        [254, 210, 127],
        [254, 210, 127],
        ...,
        [252, 184, 101],
        [251, 183, 100],
        [250, 182,  99]],

                   .

                   .

                   .

 

* 색상 채널 순서 정의하기

sample = cv2.cvtColor(sample1, cv2.COLOR_BGR2RGB)
sample

결과 : 

array([[[128, 211, 255],
        [127, 210, 254],
        [127, 210, 254],                                   - yolo에서는 현재 색상 순서를 RGB를 사용함
        ...,
        [101, 184, 252],                                   - 저장된 이미지 데이터의 순서는 BRG를 사용하고 있음
        [100, 183, 251], 
        [ 99, 182, 250]],                                    - 색상순서를 RGB로 바꾸는 작업이 필요함
                   . 
                   .
                   .
                   

 

* 사용하는 이미지 파일이름에 해당하는 바운딩박스의 x, y 좌표값 추출하기

point = box.iloc[0]
point, type(point)

결과 : 

(image    vid_4_1000.jpg
 xmin         281.259045
 ymin         187.035071                                               - vid_4_1000.jpg 이미지 파일 이름은 0번째 인덱스에 있음
 xmax         327.727931
 ymax         223.225547                                              - 0번째 인덱스의 모든 컬럼값 추출하기
 Name: 0, dtype: object,
 pandas.core.series.Series)

* 시작 좌표(xmin, ymin)와 종료 좌표(xmax, ymax) 추출하기

    - 시작 좌표 변수 : pt1 = (xmin, ymin)
    - 종료 좌표 변수 : pt2 = (xmax, ymax)
    - 시작과 종료 좌표는 튜플 타입으로 생성

* int형으로 무조건 변환해줘야 한다.

pt1 = (int(point["xmin"]), int(point["ymin"]))
pt1

pt2 = (int(point["xmax"]), int(point["ymax"]))
pt2

print(pt1, pt2)

결과 : (281, 187) (327, 223)

* 이미지 보이기

plt.imshow(sample)

 

 

 

-  이미지 픽셀 데이터를 이미지로 보이기
   - > 이때 이미지 픽셀 데이터의 차원은  =>  3차원

 

 

 

 

 

 

 

* 자동차 좌표값을 이용해서 이미지에 바운딩박스 그리기

cv2.rectangle(sample, pt1, pt2, color=(255,0,0), thickness=2)

# 이미지에 바운딩박스를 그리고 잘 보이는지 다시 imshow() 하기
plt.imshow(sample)

 

 

* rectangle() : 사각형(바운딩박스는 

   사각형으로 표시하기 위해)을 그리는 함수
   - sample : 이미지 데이터
   - pt1 : 박스의 시작점 좌표
   - pt2 : 박스의 종료 좌표
   - color : 박스 선의 색상 지정
   - thickness : 박스 선의 굵기 지정

728x90