DataScience
article thumbnail
728x90

Opencv에서 YOLO를 사용하는 방법

 

cv2와 numpy를 import해줍니다.

import cv2
import numpy as np

알고리즘을 실행하려면 세 개의 파일이 필요합니다.

  • weight 파일: 물체를 감지하는 알고리즘의 핵심인 훈련된 모델입니다.
  • Cfg 파일 : 알고리즘의 모든 설정이 있는 구성 파일입니다.
  • name 파일: 알고리즘이 감지할 수 있는 개체의 이름을 포함합니다.

weights 파일 다운로드(용량이커서 링크로대체)

coco.names
0.00MB
yolov3.cfg
0.01MB

#버전에 따라  net.getUnconnectedOutLayers()가 1차원,2차원 일 수 있습니다.

그러므로 layer_names[i[0] -1] 에서 layer_names[i -1] 으로 수정해줬습니다.

modelConfiguration = "yolo_object_detection/yolov3.cfg"
modelWeights = "yolo_object_detection/yolov3.weights"

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

 

그런 다음 객체 감지를 수행하려는 이미지를 로드하고 이미지의 너비와 높이도 얻습니다.

# Loading image
img = cv2.imread("yolo_object_detection/1.jpg")
img = cv2.resize(img, None, fx=0.4, fy=0.4)
height, width, channels = img.shape

 

이제 이미지를 네트워크에 전달하고 감지를 수행할 차례입니다.

네트워크에서 전체 이미지를 바로 사용할 수는 없지만 먼저 Blob으로 변환해야 합니다. 

Blob 이미지에서 기능을 추출하고 크기를 조정하는 데 사용됩니다. YOLO는 세 가지 size를 사용합니다.

  • 320×320은 작아서 정확도는 떨어지지만 속도는 더 좋습니다.
  • 609×609보다 크기 때문에 정확도가 높고 속도가 느립니다.
  • 416×416은 중간에 있고 둘 다 조금씩 얻을 수 있습니다.

Outs 은 감지 결과입니다. Outs는 감지된 개체, 해당 위치 및 감지에 대한 신뢰도에 대한 모든 정보를 포함하는 배열입니다.

# 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 배열을 통해 반복하고 신뢰도를 계산하고 신뢰도 임계값을 선택합니다.

임계값 신뢰도(confidence)를 0.5로 설정했습니다. 신뢰도  크면 개체가 올바르게 감지된 것으로 간주하고 그렇지 않으면 건너뜁니다.
임계값은 0에서 1까지입니다. 1에 가까울수록 감지 정확도가 높고 0에 가까울수록 정확도는 낮지만 감지된 물체의 수가 많습니다.

# Showing informations on the screen
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)

            # Rectangle coordinates
            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)

 

탐지를 수행할 때 동일한 개체에 대해 더 많은 상자가 있으므로 다른 기능을 사용하여 이 "노이즈"를 제거해야 합니다. 비 최대 억제라고 합니다.

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

 

마침내 모든 정보를 추출하여 화면에 표시합니다.

  • 상자 : 감지된 물체를 둘러싸는 사각형의 좌표를 포함합니다.
  • 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[class_ids[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()

 

사용자 지정 객체를 감지하는 방법

사용자 지정 객체를 감지하려면 사전 훈련된 모델을 사용하는 대신 사용자 지정 YOLO 모델을 만들어야 합니다.

사용자 지정 객체 탐지기를 만들려면 두 단계가 필요합니다.

  1. 감지하려는 물체의 이미지가 포함된 데이터 세트를 만듭니다.
  2. 해당 이미지 데이터 세트에서 YOLO 모델 훈련

 

profile

DataScience

@Ninestar

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