봉식이와 캔따개

Python으로 OpenCV를 사용하여 YOLO Object detection 본문

머신러닝, 딥러닝/이미지처리

Python으로 OpenCV를 사용하여 YOLO Object detection

봉식이누나 2020. 3. 30. 18:01
반응형

 

 

이번엔 뜬금없이 영상처리다...

살면서 한번도 안해봤고 해볼거라고 생각도 못했음.

 

하지만 시키니까 합니다...

 

 

https://pysource.com/2019/06/27/yolo-object-detection-using-opencv-with-python/

 

YOLO object detection using Opencv with Python - Pysource

We’re going to learn in this tutorial YOLO object detection. Yolo is a deep learning algorythm which came out on may 2016 and it became quickly so popular because it’s so fast compared with the previous deep learning algorythm. With yolo we can detect obje

pysource.com

 

이 분 글을 보고 따라해봤습니다.

 


 

YOLO란? 

 

설마 그 욜로인가 했다. 알고보니 비슷했다. 

 

You Only Look Once

 

간단히 object detection을 위한 CNN 기반의 물체인식 알고리즘이다.

 

 

 

 

 

 

YOLO 사용법

 

YOLO를 실행 할 딥러닝 프레임워크가 필요하다.

 

 

YOLO와 호환되는 가장 많이 사용되는 3가지 프레임워크

 

- Darknet : YOLO 개발자가 만든 프레임워크. YOLO를 위해 특별히 제작되었다.

  장점 : 빠르다. GPU또는 CPU와 함께 사용가능

  단점 : 리눅스에서만 호환...

 

- Darkflow : Darknet을 텐서플로우에 적용한것

  장점 : 빠르고 GPU 또는 CPU와 함께 사용 가능하고 리눅스, 윈도우, 맥에서 호환

  단점 : 설치 복잡

 

- OpenCV : 최소 3.4.2버전 필요

  장점 : openCV외에 설치할 것이 없다

  단점 : CPU에서만 작동하기 때문에 비디오를 실시간으로 처리하는 데 속도가 빠르진 않다

 

 

 

 

 

OpenCV 설치

 

Python에서 OpenCV를 사용하기 위해 OpenCV 모듈을 설치했습니다.

pip를 통해 설치 가능

 

python -m pip install opencv-python

 

 

 

 

설치가 잘 되었는지 확인해봅시다.

 

 

굳.

 

 

 

 

 

YOLO 사용법

 

 

 

OpenCV와 numpy 모듈을 import 해줍니다 : 

import cv2
import numpy as np

 

 

알고리즘을 로드합니다. 알고리즘을 실행하기 위해서 세개의 파일이 필요합니다.

 

  • Weight file : 훈련된 model

  • Cfg file : 구성파일. 알고리즘에 관한 모든 설정이 있다.

  • Name files : 알고리즘이 감지할 수 있는 객체의 이름을 포함한다.

 

 

coco.names
0.00MB
yolov3.cfg
0.01MB

 

 

weight파일은 용량때문에 안올라간다ㅓ ㅠㅠㅠㅁㄴㅇ

 

 

 

 

이런식으로 한 폴더에 넣어주었다.

 

 

YOLO 로드 : 

# Yolo 로드
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
classes = []
with open("coco.names", "r") as f:
    classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
colors = np.random.uniform(0, 255, size=(len(classes), 3))

 

 

 

그 다음 물체 감지를 할 이미지를 로드하고 너비, 높이도 가져옵니다 :

# 이미지 가져오기
img = cv2.imread("sample.jpg")
img = cv2.resize(img, None, fx=0.4, fy=0.4)
height, width, channels = img.shape

 

 

 

네트워크에서 이미지를 바로 사용할 수 없기때문에 먼저 이미지를 Blob으로 변환해야 한다.

Blob은 이미지에서 특징을 잡아내고 크기를 조정하는데 사용된다.

 

 

YOLO가 허용하는 세가지 크기

 

  • 320 × 320 : 작고 정확도는 떨어지지 만 속도 빠름

  • 609 × 609 : 정확도는 더 높지만 속도 느림

  • 416 × 416 : 중간

 

 

Object Detect :

# Detecting objects
blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)
outs = net.forward(output_layers

 

outs는 감지 결과이다. 탐지된 개체에 대한 모든 정보와 위치를 제공한다.

 

 

 

 

결과 화면에 표시 / 신뢰도, 신뢰 임계값  계산 (이 부분이 완전 이해가 안된다 ) : 

# 정보를 화면에 표시
class_ids = []
confidences = []
boxes = []
for out in outs:
    for detection in out:
        scores = detection[5:]
        class_id = np.argmax(scores)
        confidence = scores[class_id]
        if confidence > 0.5:
            # Object detected
            center_x = int(detection[0] * width)
            center_y = int(detection[1] * height)
            w = int(detection[2] * width)
            h = int(detection[3] * height)
            # 좌표
            x = int(center_x - w / 2)
            y = int(center_y - h / 2)
            boxes.append([x, y, w, h])
            confidences.append(float(confidence))
            class_ids.append(class_id)

 

신뢰도가 0.5 이상이라면 물체가 정확히 감지되었다고 간주한다. 아니라면 넘어감..

 

임계값은 0에서 1사이의 값을 가지는데

1에 가까울수록 탐지 정확도가 높고 , 0에 가까울수록 정확도는 낮아지지만 탐지되는 물체의 수는 많아진다.

 

 

 

노이즈 제거 : 

indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

 

같은 물체에 대한 박스가 많은것을 제거

Non maximum suppresion이라고 한답니다.

 

 

 

 

마지막으로 모든 정보를 추출하여 화면에 표시합니다.

 

  • Box : 감지된 개체를 둘러싼 사각형의 좌표

  • Label : 감지된 물체의 이름

  • Confidence : 0에서 1까지의 탐지에 대한 신뢰도

 

화면에 표시하기 : 

font = cv2.FONT_HERSHEY_PLAIN
for i in range(len(boxes)):
    if i in indexes:
        x, y, w, h = boxes[i]
        label = str(classes[class_ids[i]])
        color = colors[i]
        cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
        cv2.putText(img, label, (x, y + 30), font, 3, color, 3)
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

 

 

 

 

결과는...??

 

 

 

 

 

ㅋㅋㅋㅋㅋㅋ 우리 봉식이랑 티비를 감지해냈다!

 

 

재밌어서 더 많은 물건이 찍힌 사진을 넣어봤다

 

 

 

 

 

 

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 생각보다 많은걸 감지해냈다.

과자 포장지 그림을 케이크라고 잘못 인식하긴했지만...

 

역시 보는것보단 직접 해보는게 재밌다.

반응형
Comments