관리 메뉴

공부 기록장 💻

[OpenCV/C++] 영상의 필터링 2 - 블러링과 가우시안 필터링 (Blurring, Gaussian Filtering) 본문

# Tech Studies/Computer Vision • OpenCV

[OpenCV/C++] 영상의 필터링 2 - 블러링과 가우시안 필터링 (Blurring, Gaussian Filtering)

dream_for 2022. 11. 30. 13:29

OpenCV 4로 배우는 컴퓨터비전과 머신 러닝 CH7 필터링 정리

 

영상 필터링 시리즈

영상의 필터링 1 - 필터 마스크 연산과 엠보싱 필터링 (Embossing) https://dream-and-develop.tistory.com/307

영상의 필터링 2 - 블러링과 가우시안 필터링 (https://dream-and-develop.tistory.com/308

영상의 필터링 3 - 샤프닝과 잡음 제거 필터링 (https://dream-and-develop.tistory.com/309)

 

 


블러링: 영상 부드럽게 하기

 

블러링(Blurring) 이란, 초점이 맞지 않은 사진처럼 영상을 부드럽게 만드는 필터링 기법으로, 스무딩(smoothing)이라고도 한다.

영상에서 인접한 픽셀 간의 픽셀 값 변화가 크지 않은 경우 부드러운 느낌을 받을 수 있는데, 블러링은 거친 느낌의 입력 영상을 부드럽게 만드는 용도로, 혹은 입력 영상에 존재하는 잡음의 영향을 제거하는 전처리 과정으로 사용된다.

비교적 간단한 평균값 필터를 사용하는 블러링 기법과, 수식이 조금 복잡하지만 좀 더 자연스러운 블러링을 수행하는 가우시안 필터에 대해 알아보자.

 

 

1. 평균값 필터

 평균값 필터(mean filter) 은 블러링 필터 중에서 단순하고 구현하기 쉬운 필터 방법이다. 이는 입력 영상에서 특정 픽셀과 주변 픽셀들의 산술 평균을 결과 영상 픽셀 값으로 설정하는 필터이다.

결과적으로 픽셀 값의 급격한 변화가 줄어들어 날카로운 에지가 무뎌지고 잡음의 영향이 크게 사라질 수 있다.

 

아래와 같이 3x3, 5x5 크기의 평균값 필터를 비롯해 다양한 크기의 필터 마스크가 나타날 수 있다. 각각의 행렬이 모두 원소 값이 1로 설정되어 있고, 행렬의 전체 원소 개수로 각 행렬 원소 값을 나누는 형태로 표현이 되어 있다.

평균값 필터는 마스크의 크기가 커지면 커질수록 더욱 부드러운 느낌의 결과 영상을 생성하며, 대신 연산량이 크게 증가할 수 있다. 

 

 

일반적으로 필터 마스크 행렬은 모든 원소 합이 1 또는 0이 되도록 설계한다. 행렬의 전체 원소 합이 1이면 필터링 결과 영상의 평균 밝기가 입력 영상의 평균 밝기오 ㅏ같게 유지된다. 1보다 작은 경우 어두운 결과 영상이, 1보다 크면 좀 더 밝은 형태의 결과 영상이 생성 된다. 행렬 원소의 합이 0이라면, 전체적으로 검은색으로 구성된 필터링 결과 영상이 생성된다.

 

 

blur() 함수

OpenCV에서는 blur() 함수를 이용해 평균값 필터링을 수행할 수 있다. 원형은 다음과 같다.

평균값 필터 마스크 연산을 수행하는 blur() 함수

ksize 크기의 평균값 필터 마스크를 사용하여 dst 출력 영상을 생성하게 된다.

anchor 인자와 borderType 인자는 기본값을 가지므로 호출 시 생략이 가능하다.

 

blur() 함수에서 사용하는 커널은 다음과 같은 형태를 가지며, 전체 원소 개수로 각 행렬 원소 값을 나누는 형태의 수식이다.

 

 

ksize의 값을 각각 3, 5, 7로 설정하여 ksize x kszie 크기의 블러링 커널 크기를 적용한 평균값 필터 마스크를 이용한 블러링을 수행해보자.

 

// 평균값 필터를 이용한 블러링
void blurring_mean() {
	Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);

	if (src.empty()) {
		cerr << "Image load failed!" << endl;
		return;
	}

	imshow("src", src);
	Mat dst;

	// 3x3, 5x5, 7x7 크기의 평균값 필터를 이용해 블러링 수행
	for (int ksize = 3; ksize <= 7;ksize += 2) {
		blur(src, dst, Size(ksize, ksize)); // 평균값 필터링을 이용한 블러링

		String desc = format("Mean: %dx%d", ksize, ksize);
		putText(dst, desc, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255), 1, LINE_AA);

		imshow("dst", dst);
		waitKey(0);
	}

	destroyAllWindows();
}

 

결과는 다음과 같이 나타난다.

평균값 필터의 크기가 커질 수록 결과 영상이 더욱 부드럽게 변경되는 것을 확인할 수 있다.

 

 

 

5x5 크기부터 영상이 전체적으로 흐려지므로, 커널 크기 ksize를 적절히 조절하여 영상의 블러링 연산을 수행해야 할 것이다.

 

 


 

가우시안 필터

가우시안 필터(Gaussian filter) 는 가우시안 분포(Gaussian Distribution) 함수를 근사하여 생성한 필터 마스크를 사용하는 필터링 기법으로, 평균값 필터보다 자연스러운 블러링 결과를 생성한다.

 

 

가우시안 분포란?

가우시안 분분포는 평균을 중심으로 좌우 대칭의 종 모양을 갖는 확률 분포를 말하며, 정규 분포(noramal distribution)라고도 한다. 이는 평균 근방에서 분포가 가장 많이 발생하고, 평균에서 멀어질수록 발생 빈도가 종 모양으로 감소하는 형태를 따른다.

 

가우시안 분포는 평균과 표준 편차에 따라 분포 모양이 결정되는데, 영상의 가우시안 필터에서는 주로 평균이 0인 가우시안 분포를 사용한다.

평균이 0이고 표준 편차가 σ 인 1차원 가우시안 분포의 함수식은 다음과 같다.

 

평균이 0, 표준 편차가 &nbsp;&sigma;인 가우시안 분포 함수식

 

평균이 0이고 표준 편차가 각각 0.5, 1.0, 2.0인 가우시안 분포 그래프를 나타내면 다음과 같다.

 

 

 

2차원 가우시안 분포 필터 마스크

 

가우시안 분포를 따르는 2차원 필터 마스크 행렬을 생성하려면, 2차원 가우시안 분포 함수를 근사해야 하는데,

이는 x와 y 2개의 변수를 사용하고, 분포의 모양을 결정하는 평균과 표준 편차도 x축과 y축 방향에 따라 따로 설정한다.

평균이 (0,0)이고 x축과 y축 방향의 표준 편차가 각각  σ(x) ,  σ(y) 인 2차원 가우시안 분포 함수는 다음과 같이 정의된다.

 

 

아래는 평균이 (0,0)이고, σ(x)=σ(y)=1.0 인 2차원 가우시안 분포 함수 그래프를 나타낸 것이다.

평균이 (0,0)이므로 (0,0)에서 최댓값을 갖고, 평균에서 멀어질수록 함수가 감소한다. 2차원 가우시안 분포 함수의 경우 함수 그래프 아래의 부피를 구하면 1이 된다. 

 

 

가우시안 필터는 위의 2차원 가우시안 분포 함수로부터 구한 마스크 행렬을 사용한다.

가우시안 분포 함수는 연속 함쉬지만 이산형의 마스크를 만들기 위해, x와 y값이 정수인 위치에서만 가우시안 분포 함수 값을 추출하여 생성한다.

 

평균이 0이고 표준 편차가 σ인 가우시안 분포는 x가 -4σ에서 4σ 사이인 구간에서 대부분의 값이 나타나므로, 가우시안 필터 마스크의 크기는 보통 (8σ+1)로 결정한다. 

예를 들어 위와 같이 σ(x)=σ(y)=1.0 인 가우시안 함수를 사용하는 경우, x={-4,-3,...,3,4} , y={-4,-3,...,3,4} 인 경우에만 가우시안 분포 함수 값을 추출하여 필터 마스크를 생성한다. 이렇게 추출한 9x9 가우시안 필터 마스크는 아래와 같이 나타난다.

 

 

위에서 가우시안 필터 마스크 행렬은 중앙부에서 비교적 큰 값을 가지고, 주변부로 갈 수록 행렬 원소 값이 0에 가까운 작은 값을 가진다. 따라서 이 마스크를 이용해 마스크 연산을 수행한다는 것은, 필터링 대상 픽셀 근처에는 가중치를 크게 주고, 필터링 대상 픽셀과 멀리 떨어져 있는 주변부에는 가중치를 조금만 주어서 가중 평균(weighted average)르ㅓㄹ 구하는것과 같다.

 

 

GaussianBlur() 함수

OpenCV에서 가우시안 필터링을 수행하려면 GaussianBlur() 함수를 사용한다.

 

가우시안 필터링을 수행하는 GaussianBlur() 함수

위 함수는 src 영상에 가우시안 블러링 필터링을 수행하고 결과를 dst 영상에 저장한다.

x, y축 방향으로의 표준 편차 sigmaX와 sigmaY는 보통 같은 값을 사용하고, 가우시안 필터의 크기를 지정하는 ksize 인자에도 보통 Size()를 전달하여 적절한 필터 크기를 자동으로 결정하도록 한다.

 

아래는 sigma 값을 1부터 5까지 지정하여 x, y축으로의 가우시안 커널 표준 편차를 바꿔 가며

가우시안 필터 마스크 연산을 수행한 결과의 차이를 확인하는 예제이다.

 

// 가우시안 필터링 이용한 블러링 연산
void blurring_gaussian() {
	Mat src = imread("rose.bmp", IMREAD_GRAYSCALE);

	if (src.empty()) {
		cerr << "Image load failed!" << endl;
		return;
	}

	imshow("src,", src);

	Mat dst;
	// 1부터 5까지의 가우시안 커널 표준 편차를 지정하여 가우시안 필터링 수행
	for (int sigma = 1;sigma <= 5;sigma++) {
		GaussianBlur(src, dst, Size(), (double)sigma);

		String text = format("sigma = %d", sigma);
		putText(dst, text, Point(10, 30), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255), 1, LINE_AA);

		imshow("dst", dst);
		waitKey();
	}

	destroyAllWindows();
}

 

 

결과는 다음과 같이, 표준 편차 값이 커질 수록 결과 영상이 더욱 부드럽게 변경되는 것을 확인할 수 있다.

 

 

728x90
반응형
Comments