OpenCV 비전 실무18장 · OpenCV 전처리와 YOLO 연계7 / 21← 이전목차다음 →MetaContents

18장. OpenCV 전처리와 YOLO 연계

추론 결과 다루기

택배를 받으면 상자를 열어 내용물을 꺼내고, 주문서와 맞춰 본 뒤, 필요 없는 포장재는 버립니다. 추론 결과도 같습니다. predict 가 돌려준 결과 상자에서 상자 좌표, 신뢰도, 클래스를 꺼내고, 신뢰도가 낮은 것은 버린 뒤, 남은 것을 사진 위에 그립니다.

추론하기, 꺼내기, 거르기, 그리기의 네 단계를 이은 흐름도

그림의 네 단계가 추론 결과를 다루는 순서입니다. 여기서 택배 상자가 results[0], 내용물이 xyxy·conf·cls, 포장재를 버리는 일이 신뢰도 기준값으로 거르기입니다. 마지막 그리기는 12장에서 쓴 cv2.rectangle 과 cv2.putText 를 그대로 씁니다.

결과를 꺼내는 코드 꼴

코드하는 일
results = model.predict(그림, ...)그림 목록을 넣으면 그림마다 결과 하나씩 든 목록을 돌려준다
r = results[0]그림 한 장만 넣었으면 첫 결과만 쓴다
r.boxes.xyxy.cpu().numpy()상자 좌표를 NumPy 배열로. .cpu() 는 계산 장치에서 꺼내 오는 일
r.boxes.conf.cpu().numpy()신뢰도 배열
r.boxes.cls.cpu().numpy().astype(int)클래스 번호 배열. 실수로 오므로 정수로 바꾼다
r.names번호 → 이름 사전

predict 에는 파일 경로도, cv2.imread 로 읽은 그림 배열도 넣을 수 있습니다. 배열을 넣을 때는 OpenCV 의 BGR 순서 그대로 넣습니다. ultralytics 도 BGR 로 받기 때문입니다. 그래서 OpenCV 로 손질한 그림을 저장하지 않고 바로 넣을 수 있고, 실습 5와 프로젝트가 이 방법을 씁니다.

신뢰도 기준값

predict(..., conf=0.25) 는 신뢰도 0.25 보다 낮은 상자를 버리고 돌려줍니다. 0.25 는 ultralytics 의 기본값입니다.

기준값남는 상자좋아지는 것나빠지는 것
낮게(예: 0.1)많다놓친 것이 줄어 재현율이 오른다헛것이 늘어 정밀도가 떨어진다
기본(0.25)중간둘 사이의 타협
높게(예: 0.5)적다헛것이 줄어 정밀도가 오른다놓친 것이 늘어 재현율이 떨어진다

표는 보통의 경우입니다. 이 장에서 학습한 모델은 가상 그림의 부품을 모두 신뢰도 0.5 이상으로 찾아서, 0.25 와 0.5 의 결과가 같았습니다(실습 3). 기준값의 효과는 모델이 자신 없어하는 사진이 섞일 때 드러납니다.

Python
import cv2
import numpy as np

img = cv2.imread("ch17_raw/part_022.png")
# 찾았다고 치고 지어낸 결과 세 개(실습 3에서 실제 결과로 한다)
xyxy = np.array([[52, 160, 92, 200], [131, 220, 175, 239], [300, 25, 320, 65]], dtype=float)
conf = np.array([0.91, 0.47, 0.12])
cls = np.array([1, 1, 2])
names = {0: "bolt", 1: "nut", 2: "washer"}

keep = conf >= 0.25                     # 기준값 이상만 True 인 배열
print("남는 상자:", int(keep.sum()), "개 / 전체", len(conf), "개")
for box, p, c in zip(xyxy[keep], conf[keep], cls[keep]):
    x1, y1, x2, y2 = [int(v) for v in box]
    cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
    # 이름과 신뢰도를 상자 위에 쓴다. 위쪽 테두리에 붙으면 글자가 잘리므로 max 로 막는다
    cv2.putText(img, f"{names[int(c)]} {float(p):.2f}", (x1, max(y1 - 4, 12)),
                cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 1)

conf >= 0.25 는 1장의 is_red 처럼 칸마다 True/False 가 든 배열입니다. xyxy[keep] 처럼 넣으면 True 인 줄만 남습니다.

주의할 점

  • xyxy 는 소수로 옵니다. cv2.rectangle 은 정수만 받으므로 int 로 바꿔 넣습니다.
  • r.plot() 을 쓰면 ultralytics 가 상자를 대신 그려 줍니다. 편하지만 색과 글자를 고르기 어렵고, 결과를 어떻게 꺼내는지 배우지 못합니다. 이 장에서는 직접 그립니다.
← 이전 절18장 · 학습 기록 읽기다음 절 →18장 · 맞혔는지 재기