OpenCV 비전 실무7장 · Median 과 Bilateral 필터, 필터 비교4 / 21← 이전목차다음 →MetaContents

7장. Median 과 Bilateral 필터, 필터 비교

평균 필터가 점 노이즈에 약한 까닭

반 학생 아홉 명의 용돈을 평균 낸다고 해 봅시다. 여덟 명은 만 원 남짓인데 한 명이 명절에 받은 큰돈을 함께 적으면, 평균이 확 올라가 "우리 반의 보통 용돈"과 동떨어진 숫자가 됩니다. 6장의 평균 필터가 하얀 점을 만나면 이 일이 그대로 일어납니다.

가운데 칸만 255 인 아홉 칸과, 이웃의 보통 밝기, 아홉 칸의 평균, 아홉 칸의 중앙값을 막대로 견준 그림

왼쪽 아홉 칸은 90~96 의 어두운 칸 여덟 개 가운데에 하얀 점(255) 하나가 박힌 모습입니다. 오른쪽 막대를 보면 이웃의 보통 밝기는 93 인데, 아홉 칸의 평균(산호)은 111 로 튀어 오릅니다. 중앙값(초록)은 93 그대로입니다. 여기서 큰돈을 받은 한 명이 하얀 점이고, 반의 평균 용돈이 평균 필터의 결과입니다.

아홉 칸 손계산

단계계산
① 아홉 칸90, 92, 93, 95, 255, 91, 94, 96, 93
② 모두 더하기90 + 92 + 93 + 95 + 255 + 91 + 94 + 96 + 93 = 999
③ 개수로 나누기999 ÷ 9 = 111
④ 하얀 점을 뺀 여덟 칸의 평균(999 − 255) ÷ 8 = 744 ÷ 8 = 93

하얀 점 하나 때문에 평균이 93 에서 111 로 18 이나 올랐습니다. 평균 필터는 점을 지우는 대신, 점의 밝기를 이웃 여덟 칸에 조금씩 나눠 줍니다. 그래서 날카로운 하얀 점 하나가 흐릿한 회색 얼룩 3×3 으로 번집니다.

짧은 예시

Python
import cv2
import numpy as np

# 밝기 100 으로 고른 5×5 그림에 하얀 점 하나(가운데)와 검은 점 하나(오른쪽 위)를 찍는다
tiny = np.full((5, 5), 100, dtype=np.uint8)
tiny[2, 2] = 255
tiny[0, 4] = 0

# cv2.blur: 6차시의 평균 필터. 3×3 칸의 평균으로 바꾼다
print(cv2.blur(tiny, (3, 3)))
# 결과: 가운데 둘레 3×3 칸이 117 로, 오른쪽 위 둘레가 89 로 바뀐다(두 점을 함께 품은 칸은 106) → 점이 얼룩으로 번졌다

가운데 칸은 (100 × 8 + 255) ÷ 9 = 1055 ÷ 9 ≈ 117 이 되고, 둘레 여덟 칸도 하얀 점을 커널 안에 품으므로 같이 117 이 됩니다. 점 하나가 아홉 칸짜리 얼룩이 된 셈입니다.

주의할 점

  • 커널을 키우면 점은 옅어지지만, 얼룩이 더 넓게 번지고 그림 전체가 흐려집니다. 평균 필터로는 점을 "지울" 수 없고 "옅게 펴 바를" 뿐입니다.
  • 튀는 값이 섞인 묶음에서는 평균보다 중앙값이 보통의 값을 더 잘 나타냅니다. 다음 절에서 중앙값을 자세히 봅니다.
← 이전 절7장 · Salt & Pepper 노이즈다음 절 →7장 · 중앙값이란