영상처리

Part 6 : Gabor 및 가우시안 필터

dainj 2026. 2. 25. 16:55

1. 가우시안 필터 (Gaussian Filter)

가우시안 필터는 의료 영상 처리에서 가장 많이 사용되는 필터 중 하나로, 가우시안 커널을 영상과 컨볼루션하여 노이즈를 제거하고 영상을 부드럽게 만든다.

  • 수리적 표현: 2D 가우시안 함수는 다음과 같이 표현되며, u는 평균(mean), sigma는 분산(variance)을 나타낸다.
  • OpenCV 함수: cv2.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]])를 사용한다.
  • 특징: 커널 사이즈(ksize)의 가로, 세로 길이는 모두 양수의 홀수여야 한다.

가우시안 함수 수식

 

[실습 코드: 1D 커널을 이용한 2D 가우시안 필터 생성 및 적용]

Python
import cv2
import numpy as np
from google.colab.patches import cv2_imshow

# 1. 영상 읽기
image = cv2.imread("/content/drive/MyDrive/의료영상대 /chest.bmp", cv2.IMREAD_GRAYSCALE)

# 2. getGaussianKernel() 함수로 1d kernel 만들기 (사이즈 15, 시그마 4)
kernel1d = cv2.getGaussianKernel(15, 4) [cite: 816]

# 3. 1d kernel로 2d kernel 만들기 (외적 이용)
kernel2d = np.outer(kernel1d, kernel1d.transpose()) [cite: 817]

# 4. 필터 시각화 준비 (크기 조정 및 정규화)
kernel = cv2.resize(kernel2d, (220, 220), interpolation=cv2.INTER_NEAREST) [cite: 818]
kernel = 255 * (kernel / kernel.max()) # PDF 기반 수정: 시각화를 위해 최대값으로 정규화
kernel = np.clip(kernel, 0, 255).astype(np.uint8) [cite: 820, 821]
cv2_imshow(kernel) # 가우시안 커널 형태 확인 [cite: 822]

# 5. filter2D를 이용한 영상 적용
dst3 = cv2.filter2D(image, cv2.CV_32FC1, kernel2d) [cite: 823, 826, 827]
u_img = np.clip(dst3, 0, 255).astype(np.uint8) [cite: 832, 833]

cv2_imshow(image)
cv2_imshow(u_img)

2. Gabor 필터 (Gabor Filter)

Gabor 필터는 특정 방향의 선 패턴이나 질감을 검출하는 데 탁월한 성능을 보인다. 망막 이미지에서 혈관을 추출하는 등 의료 영상의 특징 검출에 주로 사용된다.

  • 수리적 표현: 가우시안 포락선(envelope)과 사인파형 인자의 곱으로 구성된다.

  • 주요 파라미터:
    • sigma: 가우시안 포락선의 표준 편차.
    • theta: Gabor 함수의 평행 줄무늬에 대한 법선 방향(방향성).
    • lambd: 사인파형 인자의 파장.
    • gamma: 공간 종횡비(Spatial aspect ratio).
    • psi: 위상 오프셋(Phase offset).

[실습 코드: Gabor 필터 계수 출력 및 영상 적용]

Python
import cv2
import numpy as np
from google.colab.patches import cv2_imshow

# 1. Gabor 커널 생성
kernel = cv2.getGaborKernel(
    (11, 11),    # 커널 사이즈 [cite: 869]
    3.12,        # sigma [cite: 870]
    np.pi / 4,   # theta (Orientation) [cite: 872]
    8.0,         # lambd (Wavelength) [cite: 871]
    0.85,        # gamma [cite: 874]
    np.pi,       # psi [cite: 875]
    ktype=cv2.CV_32F
) [cite: 868, 876]

# 2. 필터 계수 확인 (일부 출력)
print(kernel.shape, kernel.dtype) [cite: 879]

# 3. 필터 시각화
dst = cv2.resize(kernel, (220, 220), interpolation=cv2.INTER_NEAREST) [cite: 885]
dst = 255 * (dst + 0.5) [cite: 886] # 보기 좋게 오프셋 조정
dst = np.clip(dst, 0, 255).astype(np.uint8) [cite: 887, 888]
cv2_imshow(dst)

# 4. 의료 영상 적용 (예: 망막 이미지)
image = cv2.imread("retina.jpg", cv2.IMREAD_GRAYSCALE) # 파일명은 환경에 맞게 수정
dst_filtered = cv2.filter2D(image, cv2.CV_32FC1, kernel) [cite: 892, 895, 897]

# 5. 결과 디스플레이 (unsigned int 8bit 변환)
u_img = np.clip(dst_filtered + 128, 0, 255).astype(np.uint8) [cite: 902, 903, 904]
cv2_imshow(image)
cv2_imshow(u_img)

 

이와 같이 가우시안 필터와 Gabor 필터는 마스크의 계수를 어떻게 설계하느냐에 따라 영상의 노이즈를 줄이거나 특정 특징을 강조하는 역할을 수행한다.

 

3. Sobel 에지 검출 및 가우시안 선명화 (Sharpening)

에지는 영상의 경계이며, Sobel 연산자는 수평/수직 에지의 절대치 합으로 이를 검출한다

 

[실습 코드: Sobel 필터 적용]

 
Python
import cv2
image = cv2.imread("chest.bmp", cv2.IMREAD_GRAYSCALE)
from google.colab.patches import cv2_imshow
cv2_imshow(image)
# cv2.CV_8UC1 -> ddepth : output image의 depth
dst1 = cv2.Sobel(image, cv2.CV_8UC1, 1, 0, ksize=3)
dst2 = cv2.Sobel(image, cv2.CV_8UC1, 0, 1, ksize=3)
cv2_imshow(dst1)
cv2_imshow(dst2)
dst = dst1 + dst2
cv2_imshow(dst)

 

[실습 코드: 가우시안 선명화 구현]

선명화는 원본에서 스무딩된 영상을 뺀 차영상(Unsharp Mask)을 다시 더하는 방식이다.

 
Python
#-*- coding: utf-8 -*--#
import cv2
import numpy as np
from google.colab.patches import cv2_imshow
# 영상은 구글에서 "x-ray raw image"를 찾아 적절한 것을 다운받아 사용
image = cv2.imread("???.jpg", cv2.IMREAD_GRAYSCALE)
cv2.imshow(image)
#gaussian smoothing
f_img = np.float32(image)
smooth = cv2.GaussianBlur(f_img, (7, 7), 0, 0)
#smooth는 실수값을 가지므로 8비트 unsigned int로 변환 후 display
view = np.uint8(smooth)
cv2_imshow(view)
#차영상
diff = f_img - smooth
#차영상 보기
cv2_imshow(np.uint8(2*diff+128))
# enhance 영상
sharp = f_img + 2 * diff
sharp = np.clip(sharp, 0, 255)
view = np.uint8(sharp)
cv2_imshow(view)