17장. Batch Processing 과 YOLO 데이터 준비
상자와 함께 하는 증강
거울 앞에서 오른손을 들면 거울 속 사람은 왼손을 듭니다. 거울에 비친 방에서는 가구의 자리도 좌우가 바뀝니다. 14장에서 그림을 좌우로 뒤집는 법을 봤습니다. 객체 탐지 데이터는 그림만 뒤집으면 안 되고, 거울 속 가구 자리처럼 상자의 자리도 함께 옮겨야 합니다.
왼쪽은 원본, 가운데는 좌우로 뒤집은 그림, 오른쪽은 가로세로를 절반으로 줄인 그림입니다. 가운데 그림에서 상자는 xc 를 1 − xc 로 바꿔 옮겼고, 오른쪽 그림에서는 비율 좌표를 하나도 고치지 않았는데 상자가 부품에 맞습니다. 여기서 거울이 좌우 뒤집기이고, 거울 속 가구 자리가 1 − xc 입니다.
변환마다 상자 좌표가 바뀌는 법
| 변환 | xc | yc | w, h | 배운 곳 |
|---|---|---|---|---|
| 좌우 뒤집기 | 1 − xc | 그대로 | 그대로 | 14장의 cv2.flip(img, 1) |
| 위아래 뒤집기 | 그대로 | 1 − yc | 그대로 | 14장의 cv2.flip(img, 0) |
| 크기 바꾸기 | 그대로 | 그대로 | 그대로 | 14장의 cv2.resize |
| 자르기, 여백 붙이기 | 다시 계산 | 다시 계산 | 다시 계산 | 14장의 자르기와 레터박스 |
| 밝기, 노이즈 | 그대로 | 그대로 | 그대로 | 5장부터 7장까지, 16장 |
손으로 확인해 봅니다. 가로 320 인 그림에서 x1 = 40, x2 = 120 인 상자는 xc = 0.25 입니다. 좌우로 뒤집으면 xc = 1 − 0.25 = 0.75, 곧 가운데가 0.75 × 320 = 240 입니다. 픽셀로 따져도 x1 = 320 − 120 = 200, x2 = 320 − 40 = 280 이라 가운데는 (200 + 280) ÷ 2 = 240 으로 같습니다.
import cv2
img = cv2.imread("ch17_raw/part_001.png")
H, W = img.shape[:2]
xc, yc, w, h = 0.25, 0.333333, 0.25, 0.166667 # 비율 상자 하나
# 좌우 뒤집기: 그림은 cv2.flip(img, 1), 상자는 xc 만 1 - xc
flipped = cv2.flip(img, 1)
print("뒤집은 xc:", round(1 - xc, 6), "→ 가운데 픽셀", round((1 - xc) * W))
# 크기 바꾸기: 그림만 줄이고 비율 상자는 그대로 둔다
small = cv2.resize(img, (W // 2, H // 2))
sh, sw = small.shape[:2]
print("줄인 그림에서 가운데 픽셀:", round(xc * sw), round(yc * sh))주의할 점
- 돌리기(회전)는 상자가 기울어지므로 곧은 상자로 다시 감싸야 하고, 그러면 상자가 커집니다. 증강을 처음 할 때는 뒤집기, 크기, 밝기처럼 상자가 쉽게 따라오는 변환부터 씁니다.
- 증강은 학습용 데이터에만 합니다. 검증용 데이터를 증강하면 모의고사에 연습 문제를 섞는 셈입니다.