19장. Vision 데이터 파이프라인
추론 단계
은행 창구 직원은 손님 서류를 받아 도장을 찍어 돌려줍니다. 직원은 아침에 한 번 자리에 앉아 도장을 꺼내 두고, 손님이 올 때마다 도장만 찍습니다. 손님마다 도장을 새로 만들지 않습니다. 추론 단계도 모델을 한 번만 불러 두고, 그림마다 predict 만 부릅니다.
그림의 네 걸음이 추론 단계의 순서입니다. 18장에서 학습한 out_ch18_runs/parts/weights/best.pt 를 한 번 불러 두고, 다듬은 그림 배열을 predict 에 넣고, 결과에서 상자 좌표(xyxy), 신뢰도(conf), 클래스 번호(cls)를 꺼내, 한 행에 물체 하나씩 표에 담습니다. 여기서 도장을 꺼내 두는 일이 모델 부르기, 도장 찍기가 predict, 돌려받은 서류가 물체 표입니다.
추론 결과에서 꺼내는 것
| 꺼내는 코드 | 무엇 | 모양 |
|---|---|---|
r.boxes.xyxy.cpu().numpy() | 상자 모서리 두 점 (x1, y1, x2, y2), 픽셀 | 물체 수 × 4 |
r.boxes.conf.cpu().numpy() | 신뢰도 0~1 | 물체 수 |
r.boxes.cls.cpu().numpy().astype(int) | 클래스 번호 0, 1, 2 | 물체 수 |
r.names | 번호 → 이름 사전 {0: 'bolt', 1: 'nut', 2: 'washer'} | 사전 |
cpu() 는 계산 결과를 컴퓨터의 보통 메모리로 옮기고, numpy() 는 NumPy 배열로 바꿉니다(18장). 이 장의 실습 코드는 그림 배열을 그대로 predict 에 넣습니다. ultralytics 는 NumPy 배열을 OpenCV 와 같은 BGR 순서로 받아들입니다. 또 ultralytics 를 불러오면 cv2.imread 가 한글 경로도 읽도록 바뀝니다(교안 PC 에서 확인). 실습은 data 폴더의 상대 경로를 쓰므로 어느 쪽이든 상관없습니다.
짧은 예시
YOLO 를 실제로 돌리는 코드는 실습 3에 있습니다. 여기서는 추론 결과와 같은 모양의 배열을 손으로 만들어, 표로 담고 원래 좌표로 되돌리는 부분만 연습합니다. 아래 숫자는 설명을 위해 지어낸 값입니다.
import numpy as np
import pandas as pd
# 추론 결과와 같은 모양의 가짜 배열(지어낸 값): 상자 2개
xyxy = np.array([[100.0, 40.0, 160.0, 70.0], [20.5, 120.0, 52.5, 150.0]])
conf = np.array([0.91, 0.47])
cls = np.array([0, 2])
names = {0: "bolt", 1: "nut", 2: "washer"}
scale = 0.5 # 다듬기에서 640x480 을 절반으로 줄였다
rows = []
for (x1, y1, x2, y2), c, k in zip(xyxy, conf, cls):
rows.append({"file": "belt_016.png", "class": names[int(k)], "conf": round(float(c), 3),
# 줄인 그림의 좌표를 비율로 나눠 원래 그림의 좌표로 되돌린다
"x1": round(float(x1) / scale), "y1": round(float(y1) / scale),
"x2": round(float(x2) / scale), "y2": round(float(y2) / scale)})
table = pd.DataFrame(rows)
print(table.to_string(index=False))
# 결과: file class conf x1 y1 x2 y2
# belt_016.png bolt 0.91 200 80 320 140
# belt_016.png washer 0.47 41 240 105 300zip 으로 세 배열을 한 칸씩 함께 꺼내면 물체 하나의 상자, 신뢰도, 클래스가 나옵니다. 표의 한 행이 물체 하나이므로, 나중에 클래스별 개수는 value_counts(), 그림별 개수는 groupby("file").size() 로 바로 셉니다. 41 은 20.5 ÷ 0.5 = 41 입니다.
주의할 점
- 모델을 반복문 안에서 부르면 그림마다 수 MB 파일을 다시 읽어 아주 느려집니다. 반복문 밖에서 한 번만 부릅니다.
- 신뢰도 기준(
conf=0.25)을 낮추면 상자가 많아지고 틀린 상자도 늘어납니다. 기준은 CONFIG 에 두고, 바꾸면 보고서에 적습니다. - 상자는 꼭 원래 그림의 좌표로 되돌려 저장합니다. 줄인 그림의 좌표로 남기면 정답표(원래 크기 기준)와 견줄 때 어긋납니다.