본문 바로가기

major/Python

파이썬으로 가우시안 필터링하기

가우시안 필터(Gaussian Filter)는 노이즈를 제거하기 위해서 사용하고 필터링을 하면 이미지가 흐려집니다.

sigma의 값에 따라서 필터링의 정도가 결정되는데, 그 식은 아래와 같습니다.

가우시안 함수

가우시안 필터링을 하게 되면 저주파만 남게 됩니다.

원본 이미지에서 가우시안 필터링 한 이미지를 빼게 되면 원본 이미지 - 저주파가 되므로 고주파만 남게 됩니다.

 

간단하게 가우시안 필터에 대해서 정리해봤는데, 위 이론을 기본으로 opencv를 활용해서 가우시안 필터링을 해봤습니다. 그리고 직접 가우시안 필터를 구현해봤습니다.

 

이번 포스팅에서는 opencv를 사용합니다.

깔려있지 않다면 pip install opencv-python 명령어로 설치할 수 있습니다.

 

1. opencv로 1D gaussian filter 생성

cv2.getGaussianKernel()을 사용해 kernel size가 5이고 sigma가 3인 kernel을 생성합니다.

import cv2

kernel = cv2.getGaussianKernel(5, 3)
print(kernel)

 

결과

 

2. opencv와 numpy로 2D gaussian filter 생성

1D gaussian kernel을 내적 해서 2D gaussian kernel을 생성합니다.

import cv2
import numpy as np

kernel1d = cv2.getGaussianKernel(5, 3) 
kernel2d = np.outer(kernel1d, kernel1d.transpose())
print(kernel2d)

결과

 

3. 이미지에 gaussian filter 적용

이미지에 gaussian filter 처리를 하기 위해서 cv.filter2D 함수를 사용해 convolve 합니다.

원본 이미지로는 귀여운 베이가 트리스타나 신스킨 이미지를 사용했습니다.

원본 이미지

import cv2
import numpy as np
from PIL import Image

im = Image.open('newskin.jpg') # Image load
im_array = np.asarray(im) # Image to np.array

kernel1d = cv2.getGaussianKernel(5, 3)
kernel2d = np.outer(kernel1d, kernel1d.transpose())

low_im_array = cv2.filter2D(im_array, -1, kernel2d) # convolve

low_im = Image.fromarray(low_im_array) # np.array to Image
low_im.save('low_newskin.bmp','BMP')

가우시안 필터 처리 된 이미지

원본 이미지에 비해 흐려진 걸 확인할 수 있습니다.

 

4. 고주파 이미지 생성

가우시안 필터 처리된 이미지는 원본 이미지에서 저주파 데이터만 남은 이미지입니다.

"원본 이미지 - 가우시안 필터링된 이미지 + 128"을 해서 고주파 데이터만 남겨보겠습니다.

여기서 128을 더하는 이유는, "원본 이미지 - 가우시안 필터링된 이미지"의 mean 값이 0이 되기 때문에, 시각화를 위해서 RGB 0~255의 중간값인 128을 더하게 됩니다.

import cv2
import numpy as np
from PIL import Image

im = Image.open('newskin.jpg')
im_array = np.asarray(im)

kernel1d = cv2.getGaussianKernel(5, 3) 
kernel2d = np.outer(kernel1d, kernel1d.transpose()) 

low_im_array = cv2.filter2D(im_array, -1, kernel2d)

high_im_array = im_array - low_im_array + 128
high_im = Image.fromarray(high_im_array)
high_im.save('high_newskin.bmp','BMP')

고주파 이미지

 

5. 1D gaussian filter 구현

opencv를 사용하지 않고 나만의 1D gaussian filter를 구현하는 get_gaussian_filter_1d를 구현했습니다.

import numpy as np
import math

def get_gaussian_filter_1d(size, sigma):
    """
    1D 가우시안 필터를 생성한다.
    :param size: int 커널 사이즈
    :param sigma: float
    :return kernel: np.array
    """
    assert size%2==1, "Filter Dimension must be odd" # filter size는 무조건 odd여야한다
    arr = np.arange(math.trunc(size/2)*(-1), math.ceil(size/2)+1 ,1) # 중심으로 부터의 거리가 값인 배열 생성
    kernel_raw = np.exp((-arr*arr)/(2*sigma*sigma)) # 가우시안 필터 공식
    kernel = kernel_raw/kernel_raw.sum() # 정규화
    return kernel

print(get_gaussian_filter_1d(5, 3))

결과

 

이미지 처리를 공부한 내용을 간단하게 정리해봤습니다.

이미지 처리는 처음 해봤는데, 공부하면서도 굉장히 재미있는 것 같습니다. 하지만 수학적인 공식은 어렵네요ㅠㅠ


잘못된 내용이 있다면 언제든지 댓글이나 메일로 알려주시면 감사하겠습니다.

이 포스팅이 도움이 되었다면 공감 부탁드립니다.

궁금한 점은 언제든지 댓글 남겨주시면 답변해드리겠습니다:D