티스토리 뷰

영상처리/OpenCV

07. mean / gaussian filter

빠리빵 2019. 4. 18. 22:49

이전까지 간단하게 openCV에서 이미지를 불러오고 pixel value에 접근하고 수정하는 법을 배웠는데, 앞으로 한동안 filter에 대해서 배워보고자 한다. (중간을 건너뛰는 이유는 단순하게 filter가 먼저 궁금해서이다.. 나중에 다시 다룰 기회가 있지 않을까 싶다.) 앞으로 문서로 남기는 것이 더 좋을 것 같아서 PPT로 요약 후 그 내용으로 대체하고자 한다. (+ 글이 많으면 읽기가 귀찮다. 한눈으로 볼 수 있게 노력할 예정... 블로그 글에는 약간의 코멘트는 더 추가할 생각이다.)

이번 시간에는 기본적인 filtering의 개념과 가장 간단하고 많이 사용되는 Mean, Gaussian filter에 대해서 배워본다. 

 

Filtering을 사용하는 목적은 영상에서 특정한 feature를 뽑아낼 때 전처리 혹은 후처리로 사용할 수 있으며, noise 제거, down or up scaling에 사용될 수 있다.

 

우선 filtering에 앞서 신호 및 시스템의 관점에서 frequency와 spatial domain이 무엇인지 살펴보자. 영상의 픽셀은 0 ~ 255(8bit, gray scale 기준)의 밝기로 이루어져 있다. 이것의 모임이 우리가 보는 영상이 되는 것인데, 신호 관점에서 바라볼 수도 있다. 하늘과 같은 영역은 신호가 대부분 변하지 않는 영역이며, 작은 물체들이 있는 scene의 경우는 신호가 급격하게 변하는 구간이다. Frequency domain과 spatial domain의 전환은 Fourier transform과 같은 방식을 통해 전환할 수 있으며, spatial domain에서는 gray-level의 분포를 관찰하는 것이며, frequency domain에서는 variation의 frequency를 관찰하는 것이다. 영상의 경우 2차원이기 때문에 frequency 또한 2차원으로 생각하며, filter를 사용하여 특정 주파수 대역의 증폭, blocking, 감소를 할 수 있다.  

 

low pass filter로 넘어와서, 가장 간단한 방식으로는 Mean filter가 있겠다. 신호 변화의 진폭을 줄이기 위해서 간단하는 방법으로는 해당 픽셀의 값을 주위 픽셀의 평균 값으로 대체하는 방식이 있다. openCV에서는 blur라는 함수를 제공하고, paramter로는 input, output, kernel의 size가 들어간다.

 

Kernel은 mask라도 불리며, 이미지의 각각의 픽셀을 움직이며 해당 픽셀의 주위 값들과 weight를 고려하여 새로운 값으로 변경한다. 이러한 것을 convolution이라 하며, 수학적 관점에서는 위의 공식으로 표현될 수 있다. Mean filter의 경우 weight가 모두 동일하며, 그림과 같이 계산이 된다.
Gaussian filter의 경우 Gaussianblur 함수를 통해 사용할 수 있다. 사용법 또한 비슷하며, sigma value가 추가된다. 문서를 읽어보면 parameter를 지정하지 않는 경우 kernel size를 고려하여 자동으로 계산된다. 지정하는 경우 X축과 Y축 각각 지정할 수 있으며, Y sigma가 0인 경우에 X sigma와 동일하게 적용된다.  

 

sigma 값에 대해 알아보면 gaussian distribution은 중심을 기준으로 대칭을 이루며, 면적은 1(확률 및 통계)이 된다. 여기서 그래프는 중심에 더 집중된 것(빨강)과 더 넓게 분포된 것(파랑) 모양이 존재할 수도 있는데, 이것을 sigma value를 통해 조절하는 것이다. getGaussianKernel 함수를 통해 size와 data type, sigma를 지정하여 kernel을 생성할 수 있다. 오른쪽 상단에 gaussian filter에 해당되는 kernel의 예가 있는데, mean filter와 다르게 gaussian의 경우 중심에 더 많은 weight를 주고 거리가 멀어질 수록 weight가 감소하는 kernel임을 확인할 수 있다.   
Mean filter와 Gaussian filter의 결과를 비교해보면, Mean filter의 경우 detail이 조금 더 떨어지는 것을 볼 수 있다. 이는 Gaussian filter의 경우 center에서 멀어질 수록 weight를 감소시켜 pixel간 transition이 조금 더 smooth한 반면, Mean filter의 경우 같은 weight로 해당 신호를 주위 신호의 평균으로 대체해버리기 때문에 급격한 변화가 발생한다. 이는 frequency 관점에서 mean filter는 모든 high frequency components를 제거하지 못했다고 볼 수 있다. (이해가 잘 안된다면 흑과 백이 양쪽으로 존재하는 영역에서 filter를 적용한다고 생각해보자. Mean filter의 경우 경계선에서 흑과 백의 평균인 회색으로 나타날 것이며, Gaussian filter의 경우 좀 더 smooth하게 변하는 결과가 보여질 것이다.)

 

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main() {
	Mat original = imread("lena.tif", IMREAD_GRAYSCALE);
	Mat blurResult;
	Mat gaussianBlurResult;
	
	blur(original, blurResult, Size(5, 5));
	GaussianBlur(original, gaussianBlurResult, Size(5, 5), 1.5);

	cv::Mat gauss = cv::getGaussianKernel(3, 1.5, CV_32F);
	cout << gauss << endl;

	namedWindow("original");
	namedWindow("blurResult");
	namedWindow("GaussianBlurResult");
	imshow("original", original);
	imshow("blurResult", blurResult);
	imshow("gaussianBlurResult", gaussianBlurResult);

	waitKey(0);
}

'영상처리 > OpenCV' 카테고리의 다른 글

09. Median filter  (2) 2019.04.24
08. Downsampling  (4) 2019.04.22
06. Writing efficient scanning loops  (0) 2019.04.16
05. Scanning with iterator  (0) 2019.04.15
04.Scanning with pointer  (0) 2019.04.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함