19장. Vision 데이터 파이프라인
다듬기 단계
김밥 가게는 재료를 늘 같은 굵기로 썰어 둡니다. 시금치가 덜 데쳐졌으면 한 번 더 데치고, 단무지가 길면 잘라 맞춥니다. 김밥 마는 사람이 늘 같은 손놀림으로 말 수 있게 하려는 것입니다. 다듬기 단계도 모델이 배울 때 본 그림과 같은 조건으로 그림을 맞춥니다.
그림의 세 카드가 이 장의 손질입니다. 모든 그림을 18장에서 학습한 크기인 320×240 으로 맞추고 줄인 비율을 적어 둡니다. 평균 밝기가 50 보다 낮은 그림만 5장의 감마 보정(감마 0.7)으로 밝히고, 잡음 점수가 3 보다 큰 그림만 6장의 가우시안 블러(5×5)로 잡음을 줄입니다. 여기서 같은 굵기로 썰기가 크기 맞추기, 한 번 더 데치기가 밝기 고치기, 잘라 맞추기가 잡음 줄이기입니다. 비유와 다른 점은, 김밥 재료는 모두 손질하지만 이 장의 밝기와 잡음 손질은 필요한 그림에만 건다는 것입니다.
위 줄이 다듬기 전, 아래 줄이 다듬은 뒤입니다. 왼쪽의 어두운 그림은 감마 0.7 로 평균 밝기가 43.4 에서 72.6 으로 올라 다른 정상 그림(63~81)과 비슷해졌습니다. 가운데 노이즈 그림은 가우시안 블러로 잡음 점수가 7.57 에서 0.59 로 줄었습니다. 오른쪽 640×480 그림은 절반 크기로 줄여 320×240 이 되었고, 이때의 비율 0.5 를 기록해 두었다가 추론한 상자를 원래 크기로 되돌릴 때 씁니다.
다듬기의 판단과 손질
| 손질 | 언제 | 어떻게 | 앞 장 |
|---|---|---|---|
| 크기 맞추기 | 가로세로가 320×240 이 아닐 때 | cv2.resize(..., interpolation=cv2.INTER_AREA), 비율 = 320 ÷ 원래 가로 | 14장 |
| 밝기 고치기 | 평균 밝기 50 미만 | 감마 0.7 조회표와 cv2.LUT | 5장 |
| 잡음 줄이기 | 잡음 점수 3 초과 | cv2.GaussianBlur(img, (5, 5), 0) | 6장 |
잡음 점수는 이 장에서 쓰는 간단한 잣대입니다. 3×3 미디언 블러(7장)는 점 같은 잡음을 지우고 큰 모양은 남기므로, 원래 흑백 그림과의 차이가 크면 잡음이 많다는 뜻입니다. 정상 그림은 0.4~1.0 쯤, 노이즈 그림은 7.57 이었습니다.
짧은 예시
import cv2
import numpy as np
def noise_score(img):
"""흑백과 3x3 미디언 블러의 차이 평균. 클수록 자글자글하다."""
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return float(cv2.absdiff(gray, cv2.medianBlur(gray, 3)).mean())
def gamma_table(gamma):
"""5차시의 감마 조회표: 0~255 마다 (i/255)**gamma*255."""
return np.array([((i / 255) ** gamma) * 255 for i in range(256)]).round().astype(np.uint8)
dark = cv2.imread("ch19_incoming/belt_004.png")
brighter = cv2.LUT(dark, gamma_table(0.7))
print("밝기:", round(float(dark.mean()), 1), "→", round(float(brighter.mean()), 1))
noisy = cv2.imread("ch19_incoming/belt_008.jpg")
smooth = cv2.GaussianBlur(noisy, (5, 5), 0)
print("잡음 점수:", round(noise_score(noisy), 2), "→", round(noise_score(smooth), 2))
big = cv2.imread("ch19_incoming/belt_016.png")
scale = 320 / big.shape[1] # 줄인 비율: 새 가로 ÷ 원래 가로
small = cv2.resize(big, (320, 240), interpolation=cv2.INTER_AREA)
print("크기:", big.shape[:2], "→", small.shape[:2], "비율", scale)
# 결과: 밝기: 41.8 → 71.6
# 잡음 점수: 7.57 → 0.59
# 크기: (480, 640) → (240, 320) 비율 0.5dark.mean() 은 B, G, R 세 채널을 그대로 평균 낸 값이라, 흑백으로 바꿔 잰 43.4 와 72.6 보다 조금 낮게 나옵니다(41.8 과 71.6). 흑백 변환은 G 에 가장 큰 무게(0.587)를 주는데, 이 벨트는 G 가 가장 밝은 채널이기 때문입니다. 비율 0.5 는 "원래 그림에서 2칸이 새 그림에서 1칸"이라는 뜻입니다. 새 그림에서 x = 100 에 있는 상자 모서리는 원래 그림에서 100 ÷ 0.5 = 200 입니다.