7장. Median 과 Bilateral 필터, 필터 비교
경계를 지키는 필터가 필요한 까닭
안경에 김이 서리면 먼지 자국은 안 보이지만, 칠판 글씨도 함께 뿌옇게 됩니다. 6장의 평균 필터와 Gaussian 필터가 그렇습니다. 노이즈를 지우려고 흐리게 하면, 물체의 테두리도 함께 흐려집니다.
위 왼쪽은 노이즈가 없는 표지판 일부이고, 오른쪽은 평균 필터 9×9 를 건 모습입니다. 아래 그래프는 다홍 점선이 지나는 가로 한 줄의 밝기입니다. 초록 선(원본)은 글자 획에서 90 과 250 사이를 곧게 오르내리는 계단인데, 다홍 선(평균 필터)은 비탈처럼 기울고 꼭대기도 250 까지 오르지 못합니다. 여기서 김 서린 안경이 흐리게 하는 필터이고, 뿌옇게 된 칠판 글씨가 번진 경계입니다.
AI 학습 데이터에서는 경계가 곧 단서입니다. 글자를 알아보는 모델은 획의 테두리를, 부품 불량을 찾는 모델은 흠집의 가장자리를 봅니다. 노이즈를 지우다 경계까지 지우면 모델이 볼 것이 사라집니다.
노이즈와 경계의 차이
| 견줄 것 | 노이즈 | 경계 |
|---|---|---|
| 생김새 | 칸 하나하나가 따로 튄다 | 밝기가 바뀌는 곳이 선으로 이어진다 |
| 양옆의 밝기 | 둘레는 대부분 비슷하다 | 한쪽은 어둡고 한쪽은 밝다 |
| 남겨야 하나 | 지운다 | 남긴다 |
| 흐리게 하는 필터의 결과 | 줄어든다 | 함께 번진다 |
평균 필터는 이 둘을 가리지 않고 모든 이웃을 똑같이 섞습니다. 그래서 "건너편 칸은 섞지 않는" 필터가 필요합니다. 다음 절의 Bilateral 필터가 그 일을 합니다.
짧은 예시
import cv2
gray = cv2.imread("ch07_sign.png", cv2.IMREAD_GRAYSCALE)
# 커널을 키울수록 경계가 더 번진다. 세로 80 줄의 가로 54~66 칸(글자 G 의 왼쪽 테두리)을 본다
for k in (1, 5, 9):
out = gray if k == 1 else cv2.blur(gray, (k, k))
print(k, [int(v) for v in out[80, 54:67:2]])
# 결과: 커널 1(원본)은 90 → 219 → 250 으로 곧장 오르고, 커널 9 는 104 → 139 → 175 → 211 → 218 로 천천히 오르다 250 에 닿지 못한다주의할 점
- 경계가 번지는 정도는 커널 크기에 따라 다릅니다. 노이즈가 약하면 작은 커널로도 충분하니, 처음부터 큰 커널을 쓰지 않습니다.
- 경계를 "찾는" 일(Sobel, Laplacian)은 10장에서 다룹니다. 이 장은 경계를 "지키는" 데까지 봅니다.