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

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

네 필터 한눈에 견주기

같은 재료로 국을 끓여도 체로 거르는 방법, 숟가락으로 건지는 방법, 국자로 살살 걷어 내는 방법이 저마다 다릅니다. 노이즈를 거르는 네 필터도 이웃을 섞는 방법이 다르고, 그래서 잘 거르는 노이즈가 다릅니다.

평균, Gaussian, Median, Bilateral 네 필터가 이웃을 섞는 방법을 나란히 놓은 비교 그림

왼쪽 둘(평균, Gaussian)은 6장에서, 오른쪽 둘(Median, Bilateral)은 이 장에서 배웠습니다. 왼쪽 둘은 이웃의 밝기를 보지 않고 자리만 보고 섞고, 오른쪽 둘은 이웃의 밝기를 보고 섞을지 말지를 정합니다. 여기서 체, 숟가락, 국자가 네 필터이고, 국에 뜬 건더기가 노이즈입니다.

네 필터 비교표

견줄 것평균 (cv2.blur)Gaussian (cv2.GaussianBlur)Median (cv2.medianBlur)Bilateral (cv2.bilateralFilter)
섞는 법이웃을 똑같이가까울수록 크게줄 세워 가운데 값가깝고 비슷한 칸만
가우시안 노이즈줄인다잘 줄인다줄인다잘 줄인다
Salt & Pepper 노이즈얼룩으로 번진다얼룩으로 번진다가장 잘 지운다거의 못 지운다
경계 보존약하다약하다꽤 지킨다(가는 선은 지운다)가장 잘 지킨다
속도빠르다빠르다중간가장 느리다
커널 인자(k, k) 튜플(k, k) 튜플과 sigma홀수 하나d, sigmaColor, sigmaSpace

이 표의 "잘", "약하다"는 이 장의 실습 5와 프로젝트에서 실제 숫자로 확인합니다.

짧은 예시

Python
import cv2
import numpy as np

gray = cv2.imread("ch07_sign.png", cv2.IMREAD_GRAYSCALE)
# 실습 코드와 같은 방법으로 점 비율 10% 를 더한다
r = np.random.default_rng(711).random(gray.shape)
noisy = gray.copy()
noisy[r < 0.05] = 0
noisy[r > 0.95] = 255

# 네 필터를 같은 그림에 돌려 PSNR 을 견준다. 커널 크기는 5 로 맞춘다
filters = {
    "평균": cv2.blur(noisy, (5, 5)),
    "Gaussian": cv2.GaussianBlur(noisy, (5, 5), 0),
    "Median": cv2.medianBlur(noisy, 5),
    "Bilateral": cv2.bilateralFilter(noisy, 9, 75, 75),
}
for name, out in filters.items():
    print(f"{name:10} PSNR {cv2.PSNR(gray, out):.2f}")

이 코드를 돌리면 Median 이 가장 높고 Bilateral 이 가장 낮게 나옵니다. 점 노이즈에서 Bilateral 이 약하다는 표의 내용 그대로입니다.

주의할 점

  • 견줄 때는 커널 크기를 비슷하게 맞춥니다. 한 필터만 큰 커널을 주면 공정한 비교가 아닙니다.
  • 비교표는 이 장의 가상 그림에서 얻은 경향입니다. 실제 사진은 노이즈가 섞여 있고 물체도 복잡하므로, 자기 사진으로 다시 재어 봅니다.
← 이전 절7장 · 필터를 견주는 방법다음 절 →7장 · 필터 고르는 순서