YOLO 모델로 객체 검출 시작하기, 비디오에서 객체 검출하기 실시간 웹캠 및 비디오 파일에서 객체 검출

YOLO(You Only Look Once)는 객체 검출 분야에서 가장 인기 있는 방법 중 하나로, 빠르고 정확하게 객체를 탐지할 수 있는 특징을 가지고 있습니다. YOLO는 이미지나 비디오 프레임을 한 번만 보고 모든 객체를 동시에 검출하는 방식으로 작동합니다. 본 강좌에서는 YOLO 모델을 활용하여 실시간 웹캠 및 비디오 파일에서 객체를 검출하는 방법을 알아보겠습니다.

YOLO란 무엇인가?

YOLO는 객체 검출의 최전선에서 자리 잡고 있는 딥러닝기반의 기술입니다. 전통적인 기법은 이미지의 모든 영역을 슬라이딩 윈도우 방식으로 검색하며, 각 영역에 대해 분류기를 사용할 필요한 반면, YOLO는 이미지를 한 번에 입력으로 받아서 모든 객체를 한 번의 패스로 감지합니다. 이 덕분에 YOLO는 실시간 처리에 적합합니다.

YOLO 모델 준비하기

YOLOv3와 YOLOv4는 두 가지의 인기 있는 모델입니다. 이들 모델은 사전 훈련된 가중치를 제공하므로, 우리는 이를 통해 모델을 쉽게 사용할 수 있습니다. 본 강좌에서는 YOLOv3를 사용하여 객체를 검출할 것입니다.

필요한 라이브러리 설치하기

pip install opencv-python numpy

YOLOv3 가중치 및 구성 파일 다운로드

모델의 설정 파일과 가중치는 YOLO의 공식 GitHub 저장소에서 다운로드할 수 있습니다. 너무 길지 않게, 두 파일을 다운로드하고 저장합니다:

YOLOv3로 이미지에서 객체 검출하기

이제 YOLOv3 모델을 사용하여 이미지를 처리해보겠습니다. 다음은 YOLOv3를 사용하여 이미지를 입력으로 받아 객체를 검출하는 코드 예제입니다.

import cv2
import numpy as np

# YOLOv3 설정 파일과 가중치 파일 경로
config_path = 'yolov3.cfg'
weights_path = 'yolov3.weights'
class_file = 'coco.names'

# 클래스 로드
with open(class_file, 'r') as f:
    classes = [line.strip() for line in f.readlines()]

# 모델 로드
net = cv2.dnn.readNet(weights_path, config_path)

def detect_objects(image):
    height, width = image.shape[:2]
    
    # 모델 입력 설정
    blob = cv2.dnn.blobFromImage(image, 0.00392, (416, 416), (0, 0, 0), True, cropped=False)
    net.setInput(blob)

    # 출력 레이어 이름 가져오기
    layer_names = net.getLayerNames()
    output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
    
    # 객체 감지 수행
    outputs = net.forward(output_layers)

    boxes = []
    confidences = []
    class_ids = []

    for output in outputs:
        for detection in output:
            scores = detection[5:]
            class_id = np.argmax(scores)
            confidence = scores[class_id]
            if confidence > 0.5:
                center_x, center_y = int(detection[0] * width), int(detection[1] * height)
                w, h = int(detection[2] * width), 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)

    # 비최대 억제
    indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

    return indexes, boxes, confidences, class_ids

def draw_labels(image, indexes, boxes, confidences, class_ids):
    for i in range(len(boxes)):
        if i in indexes:
            x, y, w, h = boxes[i]
            label = str(classes[class_ids[i]])
            confidence = confidences[i]
            cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
            cv2.putText(image, f"{label} {confidence:.2f}", (x, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

# 이미지 읽기
image = cv2.imread('image.jpg')
indexes, boxes, confidences, class_ids = detect_objects(image)
draw_labels(image, indexes, boxes, confidences, class_ids)

# 결과 이미지 표시
cv2.imshow('Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

위 코드는 YOLOv3를 사용하여 이미지를 입력받고, 검출된 객체를 사각형으로 표시하는 방식입니다. 감지된 객체에 대한 클래스 이름과 신뢰도도 표시됩니다.

비디오 파일에서 객체 검출하기

이제 비디오 파일에서 객체를 검출해보도록 하겠습니다. 비디오 파일을 열고 프레임마다 객체 검출을 수행하여 결과를 출력하는 예제를 작성해보겠습니다.

cap = cv2.VideoCapture('video.mp4')

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    indexes, boxes, confidences, class_ids = detect_objects(frame)
    draw_labels(frame, indexes, boxes, confidences, class_ids)

    cv2.imshow('Video', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

위 코드는 비디오 파일을 열고, 각 프레임에서 객체를 감지하여 화면에 표시합니다. 사용자가 ‘q’ 키를 누르면 비디오가 종료됩니다.

웹캠에서 실시간 객체 검출하기

웹캠을 통해 실시간으로 객체를 검출하는 것도 가능합니다. 아래 코드는 실시간으로 웹캠에서 객체를 감지하며, 사용자가 ‘q’ 키를 누르면 종료됩니다.

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    indexes, boxes, confidences, class_ids = detect_objects(frame)
    draw_labels(frame, indexes, boxes, confidences, class_ids)

    cv2.imshow('Webcam', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

이 코드를 실행하면 연결된 웹캠에서 객체를 실시간으로 검출할 수 있습니다.

결론

YOLO를 사용하여 객체를 검출하는 과정에 대해 알아보았습니다. 이 강좌에서는 기본적인 이미지에서의 객체 검출, 비디오 파일에서의 객체 검출, 실시간 웹캠에서의 객체 검출을 포함하였습니다. YOLO는 다양한 환경에서 효율적으로 사용될 수 있으며, 실시간 애플리케이션에 적합한 기술입니다. YOLO를 더욱 깊이 이해하고 싶다면, 다양한 파라미터 조정 및 커스터마이징을 통해 모델의 성능을 최적화하는 방법에 대해 연구해 보시기 바랍니다.