블러링(Bluring) 및 샤프닝(Sharpening) 필터
- 영상 필터링은 픽셀 주변의 값들을 조합해 새로운 픽셀 값을 계산하는 과정이다.
- 이 중 블러링(Blurring)/스무딩(Smoothing) 은 영상의 세부 정보를 흐릿하게 만들어 노이즈를 제거하거나, 특정 영역의 변화량을 줄이는 효과가 있으며, 반대로 샤프닝(Sharpening) 은 경계와 세부 묘사를 강조하여 더 선명하게 보이도록 만든다.
필터 종류 | 방법 | 설명 |
---|
평균(Mean) 필터 | 커널 내 평균을 계산 | 구현이 간단, 빠름 |
중간값(Median) 필터 | 커널 내 중간값으로 대체 | salt-and-pepper 노이즈 제거에 효과적, 적당한 엣지 보존, 느림 |
가우시안(Gaussian) 필터 | 가우시안 분포 가중치로 블러링 | 자연스럽고 부드러운 흐림, 고주파 잡음 제거 |
양방향(Bilateral) 필터 | 거리 + 색상 차이 모두 고려 | 노이즈 제거하면서 엣지 보존 강함, 느림 |
언샤프 마스킹(Unsharp Masking) | 블러 이미지 빼서 엣지 강화 후 원본에 더함 | 자연스러운 샤프닝, 노이즈도 강조될 수 있음 |
1. 평균 필터 (Mean Filter)
개요
- 주변 픽셀들의 평균값으로 현재 픽셀을 바꾸는 방법.
- 주변과 큰 차이가 있는 픽셀 값이 평균에 의해 완화 → 노이즈 제거 효과.
- 하지만 경계(Edge)도 함께 흐려짐 → 부드러운 이미지 생성.
방법
- 윈도우(커널) 크기를 M×N 이라고 할 때, 결과 이미지 I′(x,y)는 다음과 같이 계산된다.
I′(x,y)=MN1u=−a∑av=−b∑bI(x+u,y+v)
- a=2M−1,b=2N−1 : 중심 픽셀 기준 좌우/상하 범위
- I(x+u,y+v) : 원본 이미지의 주변 픽셀값
- MN1 : 픽셀 개수로 나누어 평균을 구함

OpenCV
import cv2
# 원본 이미지 읽기
src = cv2.imread("image.jpg")
dst = cv2.blur(src, (3, 3)) # 3×3 평균 필터
- cv2.blur(src, ksize, borderType = ‘BORDER_REFLECT_101’)
- src : 이미지 객체 행렬
- ksize : 평균 필터 크기 (너비 방향 필터 크기, 높이 방향 필터 크기) → 홀수
- borderType : 이미지 가장자리를 처리하는 방식 (default : ‘BORDER_REFLECT_101’)
- BORDER_CONSTANT : 주어진 특정 값(default : 0)으로 채움
- BORDER_REPLICATE : 가장 가까운 픽셀 값을 가져옴
- BORDER_REFLECT : 이미지 가장자리를 포함한 대칭 방향의 인접한 픽셀 값을 가져옴
- BORDER_REFLECT_101 : 이미지 가장자리를 제외한 대칭 방향의 인접한 픽셀 값을 가져옴
개요
- 주변 픽셀들의 중간값(중위수) 으로 현재 픽셀을 대체하는 비선형 필터.
- 특히 소금-후추 노이즈(Salt-and-Pepper Noise) 같은 갑작스러운 밝기 변화에 강하며, 평균 필터와 달리, 주변 픽셀 중 일부가 매우 크거나 작더라도 결과 값이 크게 왜곡되지 않는 장점이 있다.
방법
- 윈도우(커널) 크기를 M×N 이라고 할 때, 결과 이미지 I′(x,y)는 다음과 같이 계산된다.
I′(x,y)=median{I(x+u,y+v)∣u∈[−a,a],v∈[−b,b]}
- a=2M−1,b=2N−1 : 중심 픽셀 기준 좌우/상하 범위
- median{⋯} : 집합 안의 값들을 오름차순 정렬 했을 때, 가운데 위치한 값(중간값)

OpenCV
import cv2
# 원본 이미지 읽기
src = cv2.imread("image.jpg")
# 3x3 중간값 필터 적용
dst = cv2.medianBlur(src, 3)
- cv2.medianBlur(src, ksize)
- src : 이미지 객체 행렬
- ksize : 커널 크기(only one because we use a square window) → 홀수
3. 가우시안 필터 (Gaussian Filter)
개요
- 가우시안 필터는 픽셀 평균을 낼 때 중심에 가까운 픽셀일수록 가중치를 높게 주는 필터로, 이때 사용되는 가중치는 가우시안 분포 를 따른다.
- 평균 필터와 다르게 단순히 모든 픽셀을 같은 비중으로 평균내는 것이 아니라, 중심부의 영향이 가장 크고 멀리 떨어질수록 영향이 적도록 한다.
- 평균 필터보다 경계 흐림이 덜하고 부드러운 결과 생성를 생성하며, 고주파 노이즈 제거에 효과적임.
방법
- 윈도우(커널) 크기를 M×N 이라고 할 때, 결과 이미지 I′(x,y)는 다음과 같이 계산된다.
I′(x,y)=u=−a∑av=−b∑bw(u,v)⋅I(x+u,y+v)
- 여기서 가중치 w(u,v) 는 2차원 가우시안 함수로 정의된다.
w(u,v)=2πσ21exp(−2σ2u2+v2)=(2πσ1exp(−2σ2u2))(2πσ1exp(−2σ2v2))
- σ : 표준편차 (값이 클수록 블러 강도가 커짐)
- w(u,v) : 필터의 총합은 1이 디도록 정규화(평균 밝기 유지)



OpenCV
import cv2
# 원본 이미지 읽기
src = cv2.imread("image.jpg")
# 가우시안 필터 적용 (커널 크기 5x5, 표준편차 1)
dst = cv2.GaussianBlur(src, (5, 5), 1)
- cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None) → dst
- src: 입력 영상. 각 채널 별로 처리됨
- dst: 출력 영상. src와 같은 크기, 같은 타입
- ksize: 가우시안 커널 크기. (0, 0)을 지정하면 sigma 값에 의해 자동 결정됨
- sigmaX: x방향 sigma
- sigmaY: y방향 sigma. 0이면 sigmaX와 같게 설정
- borderType: 가장자리 픽셀 확장 방식
4. 양방향 필터 (Bilateral Filter)
개요
- Bilateral 필터는 가우시안 블러처럼 부드럽게 하면서도 경계(Edge)는 보존하는 고급 블러링 필터로써, 기존 가우시안 필터는 거리만 고려하지만, Bilateral 필터는 거리와 색(강도) 차이 두 가지를 모두 고려한다.
- 가까운 픽셀 → 영향 큼
- 색이 비슷한 픽셀 → 영향 큼
- 색이 많이 다른 픽셀(경계) → 영향 작음
- 따라서, Bilateral 필터의 모양은 이미지의 대상 영역에 영향을 받는다.
방법
- Bilateral 필터는 다음 수식으로 정의된다.
f(i,j,k,l)=N1exp(−2σx2(i−k)2−2σy2(j−l)2)⋅exp(−2σr2(I(i,g)−I(k,l))2)
- (i,j) : 현재 처리 중인 중심 픽셀 좌표.
- (k,l) : 주변 이웃 픽셀 좌표.
- σx,σy : 거리(공간) 민감도. 좌표 공간에서 필터의 표준 편차.
- σr : 색(강도) 민감도. 색 공간에서 필터의 표준 편차.
- N : 모든 가중치의 합.
1. 공간 가우시안 항(Spatial Gaussian)
exp(−2σx2(i−k)2−2σy2(j−l)2)
- 중심 픽셀에서 멀리 떨어진 픽셀일수록 영향이 작아짐 = 가우시안 필터와 동일한 개념.
2. 강도 가우시안 항(Range Gaussian)
exp(−2σr2(I(i,g)−I(k,l))2)
- 색(밝기) 차이가 큰 픽셀일수록 영향이 작아짐.
- 경계(Edge) 부분은 색 차이가 크기 때문에 평균에 거의 포함되지 않음.

OpenCV
import cv2
# 원본 이미지 읽기
src = cv2.imread("image.jpg")
# Bilateral 필터 적용
# d=9: 픽셀 이웃 직경, sigmaColor=75, sigmaSpace=75
dst = cv2.bilateralFilter(src, d=9, sigmaColor=75, sigmaSpace=75)
- cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None) → dst
- src: 입력 영상. 8비트 또는 실수형, 1채널 또는 3채널
- d: 필터링에 사용될 이웃 픽셀의 거리(지름), 음수(-1)를 입력하면 sigmaSpace 값에 의해 자동 결정(권장)
- sigmaColor: 색 공간에서 필터의 표준 편차
- sigmaSpace: 좌표 공간에서 필터의 표준 편차
- dst: 출력 영상. src와 같은 크기, 같은 타입
- borderType: 가장자리 픽셀 처리 방식
5. 언샤프 마스킹
개요
- 이미지를 선명하게(Sharp) 만드는 필터링 기법으로, 블러링된 이미지(언샤프 이미지)를 원본에서 빼서 엣지 정보만 뽑아내고, 이를 원본에 더해주는 방식.
- 즉, “경계 부분은 강조하고, 균일한 영역은 변화 없이” 처리한다.
방법
I′(x,y)=I(x,y)+α(I(x,y)−Iblur(x,y))
- I(x,y) : 원본 이미지
- Iblur(x,y) : 블러 처리된 이미지
- I(x,y)−Iblur(x,y) : 엣지 정보만 남김
- α : 샤프닝 강도 (0< α < 2 범위가 일반적)
OpenCV
import cv2
# 이미지 읽기
img = cv2.imread("image.jpg")
# 가우시안 블러 적용
blur = cv2.GaussianBlur(img, (5, 5), 1.0)
# 샤프닝 강도
k = 1.5
# Unsharp Masking
sharp = cv2.addWeighted(img, 1 + k, blur, -k, 0)
6. 특정 필터 연산
- 특정 모양의 필터를 정의함으로써 블러링 또는 샤프닝을 구현할 수 있다.
- 아래는 샤프닝을 위한 3×3 필터의 예시로, 중심 픽셀 값을 크게하고 주변 픽셀 값들을 빼서 차이를 강조할 수 있다.
K=−1−1−1−19−1−1−1−1
- 주변 픽셀 값들이 모두 -1로 곱해져 더해지므로, 중심 픽셀과 이웃 픽셀의 차이를 강조하고 이 과정에서 엣지(경계) 정보가 부각된다. (High-pass 효과)
- 가운데 값이 1보다 훨씬 큰 9이므로, 중심 픽셀의 원래 값이 많이 반영된다.

OpenCV
import cv2
import numpy as np
# 이미지 읽기
img = cv2.imread("image.jpg")
# 필터 생성
kernel = np.array([[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]])
# 필터 연산
sharpen_img = cv2.filter2D(image, -1, kernel)
참고