OpenCV 비전 실무6장 · 평균 필터와 Gaussian 필터3 / 21← 이전목차다음 →MetaContents

6장. 평균 필터와 Gaussian 필터

노이즈란

캄캄한 방에서 휴대폰으로 사진을 찍으면 화면이 자글자글합니다. 라디오 주파수가 조금 어긋났을 때 노랫소리 위로 "치익" 하는 잡음이 깔리는 것과 비슷합니다. 노래(원래 장면)는 그대로 있는데, 그 위에 원래 없던 소리(값)가 섞여 들어간 것입니다. 사진에서는 이것을 노이즈라고 부릅니다.

깨끗한 그림에 평균 0, 표준편차 10, 20, 40 의 가우시안 노이즈를 더한 네 그림

같은 안내판 그림에 세기가 다른 노이즈를 더했습니다. 왼쪽이 깨끗한 원본이고, 오른쪽으로 갈수록 노이즈가 셉니다. 여기서 노래가 원본 그림이고, 라디오 잡음이 노이즈이고, 라디오 볼륨처럼 잡음의 세기를 정하는 숫자가 표준편차입니다. 비유와 다른 점도 있습니다. 라디오 잡음은 귀로 듣고 지나가지만, 사진의 노이즈는 칸마다 숫자로 남아 다음 계산(밝기, 경계 찾기, AI 학습)에 그대로 끼어듭니다.

가우시안 노이즈는 어떻게 생겼나

가우시안 노이즈는 칸마다 작은 수를 더하거나 뺍니다. 더하는 수는 대부분 0 근처로 작고, 아주 가끔만 큽니다.

가우시안 노이즈 76,800개의 값을 세어 그린 종 모양 막대그래프와 표준편차 구간

표준편차 20 인 노이즈 값 76,800개를 4장의 히스토그램처럼 세어 그렸습니다. 막대가 0 에서 가장 높고, 양쪽으로 갈수록 낮아지는 종 모양입니다. 짙은 초록으로 칠한 -20~20 구간에 약 68%, 연두로 칠한 바깥까지 넓혀 -40~40 을 보면 약 95% 가 들어 있습니다. 표준편차는 4장에서 본 "평균에서 평균적으로 얼마나 떨어져 있나"였으므로, 표준편차 20 은 "칸마다 평균 20 쯤 흔들린다"는 뜻입니다.

노이즈생기는 곳생김새다루는 장
가우시안 노이즈어두운 곳에서 찍음, 센서의 열모든 칸이 조금씩 지글지글 흔들림이 장
Salt & Pepper 노이즈전송 오류, 고장 난 센서 칸드문드문 새하얀 점과 새까만 점7장

노이즈 만드는 법

순서할 일코드
1씨앗을 고정한 난수 만들개 준비rng = np.random.default_rng(600)
2그림과 같은 모양의 노이즈 표noise = rng.normal(0, 20, img.shape)
3소수로 바꿔 더하기img.astype(np.float64) + noise
40~255 로 잘라 정수로np.clip(..., 0, 255).astype(np.uint8)
깨끗한 그림, 노이즈 표 만들기, 더하기, 0~255 로 자르기의 네 단계 흐름도

그림의 네 단계가 표의 순서와 같습니다. 셋째 단계에서 소수로 바꿔 더하는 까닭은 1장에서 본 대로 uint8 이 255 를 넘으면 0 으로 돌아가기 때문입니다.

짧은 예시

Python
import cv2
import numpy as np

img = cv2.imread("ch06_board.png", cv2.IMREAD_GRAYSCALE)

# default_rng: 씨앗(600)을 고정한 난수 만들개. 언제 돌려도 같은 노이즈가 나온다
rng = np.random.default_rng(600)
# normal(평균, 표준편차, 모양): 정규분포를 따르는 난수 표. 그림과 같은 (240, 320) 모양
noise = rng.normal(0, 20, img.shape)
print(round(float(noise.mean()), 2), round(float(noise.std()), 2))   # 결과: -0.03 19.96

# 소수로 바꿔 더한 뒤 0~255 로 자르고 uint8 로 되돌린다
noisy = np.clip(img.astype(np.float64) + noise, 0, 255).astype(np.uint8)
print(noisy.dtype, noisy.shape)   # 결과: uint8 (240, 320)

normal 은 정규분포(normal distribution)에서 왔습니다. 평균을 0 으로 주었으므로 노이즈를 모두 더하면 거의 0 이 되고, 사진 전체의 밝기는 거의 그대로입니다.

주의할 점

  • uint8 그림에 노이즈를 바로 더하면 255 를 넘는 칸이 0 근처로 돌아가 엉뚱한 검은 점이 생깁니다. 소수로 바꿔 더하고 np.clip 으로 잘라야 합니다.
  • 씨앗을 주지 않으면 실행할 때마다 노이즈가 달라져, 필터의 효과를 견줄 수 없습니다. 이 장은 씨앗 600 을 씁니다.
← 이전 절6장 · 용어 짚고 가기다음 절 →6장 · 필터와 커널