주파수 영역에서의 필터링은 마치 체(Sieve)를 이용해 원하는 크기의 모래알만 걸러내는 과정과 같다. 앞서 2차 퓨리에 변환 결과인 스펙트럼 영상에서 정중앙은 저주파 성분(부드러운 배경)이 모여 있고, 가장자리 외곽은 고주파 성분(날카로운 경계선, 노이즈)이 모여 있다는 점을 기억해야 한다.

1. 저역통과필터 (Low Pass Filter, LPF)와 마스킹 원리
저역통과필터(LPF)는 이름 그대로 '낮은 주파수(Low Frequency)만 통과(Pass)시키는 필터'이다.
- 원리 및 효과: 스펙트럼의 정중앙(저주파) 부분만 살려두고, 외곽에 퍼져 있는 고주파 성분은 모두 0(검은색)으로 지워버린다. 고주파 성분인 날카로운 윤곽선이나 거친 노이즈가 사라지게 되므로, 최종적으로 영상을 다시 원래대로 복원(역변환)하면 전체적으로 영상이 부드럽고 흐릿해지는 블러링(Blurring) 효과를 얻게 된다.
- 마스크 생성: 빈 도화지(np.zeros)의 정중앙에 하얀색 원(cv2.circle)을 그린다. 이 원 내부의 값은 1이 되고 바깥은 0이 된다. 이 마스크를 주파수 스펙트럼에 곱하면, 중앙의 저주파 데이터만 살아남게 된다.


[실습 코드: LPF 적용 및 역 퓨리에 변환]
Python
# 이미지 만들기
image=cv2.imread(image_path("test_pattern.png"), cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,dsize =(512,512))
f_img = fft2(image)
f = fftshift(f_img)
fshift = f
fshift2 = np.abs(fshift)
magnitude_spectrum = 2*np.log(np.abs(fshift)) #spectrum 구하는 수학식.
# 필터 만들기
filter = np.zeros((512,512), np.float32)
cv2.circle(filter, (256,256), 8, (1,1,1), -1)
filtered_img = np.zeros((512,512), np.float32)
# 필터 적용하기 (스펙트럼과 마스크 행렬을 곱함)
filtered_img = f*filter
# 역 퓨리에 변환을 위해 중앙으로 모았던 주파수를 다시 분산시킴
fimg_shift = ifftshift(filtered_img)
# 역 2차 퓨리에 변환 (Inverse FFT) 수행
inverse_fimg = ifft2(fimg_shift)
inverse_fimg = np.abs(inverse_fimg)
plt.subplot(141),plt.imshow(image, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(142),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('fft2'), plt.xticks([]), plt.yticks([])
plt.subplot(143),plt.imshow(filter, cmap = 'gray')
plt.title('filter'), plt.xticks([]), plt.yticks([])
plt.subplot(144),plt.imshow(inverse_fimg, cmap = 'gray')
plt.title('final'), plt.xticks([]), plt.yticks([])
plt.show()
2. 고역통과필터 (High Pass Filter, HPF)
고역통과필터(HPF)는 LPF와 정반대로 '높은 주파수(High Frequency)만 통과시키는 필터'이다.
- 원리 및 효과: 스펙트럼의 정중앙에 있는 저주파 성분(부드러운 색상 변화, 밋밋한 배경)을 0으로 만들어 까맣게 지워버리고, 외곽의 고주파 성분만 살려둔다. 이를 다시 역변환하면 배경은 어두워지고, 밝기가 급격하게 변했던 사물의 경계선(에지)이나 세밀한 디테일만 하얗게 도드라지는 효과를 얻을 수 있다.
- 공간 영역에서의 HPF 구현 (언샤프 마스킹 기법): 주파수 영역에서 직접 정중앙을 까맣게 뚫는 마스크를 쓸 수도 있지만, 기말고사 PDF 코드에서는 흥미롭게도 LPF = 1 - HPF라는 개념을 활용하여 공간 영역(Spatial Domain)에서 이를 구현했다. 원본 이미지에서 부드러워진 이미지(가우시안 블러 적용, 즉 LPF 결과물)를 빼버리면, 자연스럽게 날카로운 성분(HPF 결과물)만 남게 된다.
[실습 코드: HPF 적용 (공간 영역 구현 방식)]
Python
image=cv2.imread(image_path("test_pattern.png"), cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,dsize =(512,512))
#### LPF = 1 - HPF 원리를 이용한 공간 영역에서의 Highpass 구현
def highpass(img, sigma):
# 원본 이미지에서 가우시안 블러(저주파 통과) 이미지를 빼서 고주파 성분만 남김
# 결과가 음수가 될 수 있으므로 127을 더해 회색조 배경 위에 표현함
return img - cv2.GaussianBlur(img, (511,511), sigma) + 127
# 앞선 LPF 역변환 과정 (코드 흐름 유지를 위해 포함됨)
fimg_shift = ifftshift(filtered_img)
inverse_fimg = ifft2(fimg_shift)
inverse_fimg = np.abs(inverse_fimg)
plt.figure(figsize=(12, 12))
plt.subplot(141),plt.imshow(image, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(142),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('fft2'), plt.xticks([]), plt.yticks([])
plt.subplot(143),plt.imshow(filter, cmap = 'gray')
plt.title('filter'), plt.xticks([]), plt.yticks([])
# HPF 함수를 적용한 결과물 출력
plt.subplot(144),plt.imshow(highpass(image, 3), cmap = 'gray')
plt.title('final'), plt.xticks([]), plt.yticks([])
plt.show()
- 노이즈를 없애고 부드럽게 만들고 싶다면? (저역통과필터, LPF): 중심부의 저주파만 놔두고, 외곽에 퍼져 있는 고주파(노이즈, 거친 질감) 부분에 검은색 원형 마스크를 씌워 값을 0으로 지워버린다.
- 윤곽선과 디테일만 날카롭게 추출하고 싶다면? (고역통과필터, HPF): 반대로 중심부의 저주파 영역을 까맣게 지워버리고, 외곽의 고주파 영역만 남긴다.
이렇게 주파수 영역에서 원하는 성분만 남기는 필터링(Filtering) 작업을 거친 뒤, 다시 역 퓨리에 변환(Inverse Fourier Transform) 공식을 적용해 우리가 아는 일반 이미지로 되돌린다. 이것이 주파수 영역 영상처리의 완벽한 흐름이다.
'영상처리' 카테고리의 다른 글
| Part 11 : 기하학적 변환 (Geometric Transformation) (0) | 2026.02.27 |
|---|---|
| Part 10 : 모폴로지 연산 (Morphological Operations) (0) | 2026.02.27 |
| Part 8 : 주파수 영역 영상처리와 퓨리에 변환 (0) | 2026.02.26 |
| Part 7 : 다중 주파수 및 피라미드 선명화 (0) | 2026.02.25 |
| Part 6 : Gabor 및 가우시안 필터 (0) | 2026.02.25 |