[OpenCV] 잡음 제거 – 2. 미디언 필터

이번 글에서는 미디언 필터(median filter)에 대해 알아보겠습니다.

영상의 잡음 중에는 소금과 후추를 뿌린 것같은 소금, 후추 잡음이 있습니다. 잡음의 픽셀값이 0 또는 255이여서 흰색과 검은 소금 후추를 뿌린것 같다하여 생긴 이름입니다.

소금, 후추 잡음을 생성하는 예제 코드는 아래와 같습니다.

Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
if (src.empty())
{
	cerr << "image open error" << endl;
	return;
}

Mat noise;
src.copyTo(noise);
int noise_count = src.total() / 100;
for (int i = 0 ; i < noise_count ; i++)
{
	int x = rand() % noise.cols;
	int y = rand() % noise.rows;
	// 소금, 후추 잡음 생성
	noise.at<uchar>(y, x) = (i % 2) * 255;
}

imshow("src", src);
imshow("noise", noise);

waitKey();
destroyAllWindows();

미디언 필터는 소금 후추 잡음과 같이 잡음의 픽셀 값이 주변 값과 차이가 클 때 사용하면 효과적인 필터입니다.
미디언 필터는 주변 픽셀에 대한 값을 정렬한 뒤 중간 값을 새로운 값으로 사용합니다.

해당 방식을 이미지로 표현하면 아래와 같습니다.

미디언 필터 방식

OpenCV에서 미디언 필터에 대한 함수를 제공합니다.

/** 
@param src 입력 영상
@param dst 출력 영상
@param ksize 필터 크기. 3보단 큰 홀수(for example: 3, 5, 7 ...)
 */
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );

미디언 필터 예제 코드는 아래와 같습니다.

Mat src = imread("lenna.bmp", IMREAD_GRAYSCALE);
if (src.empty())
{
	cerr << "image open error" << endl;
	return;
}

Mat noise;
src.copyTo(noise);

int noise_count = src.total() / 100;
for (int i = 0 ; i < noise_count ; i++)
{
	int x = rand() % noise.cols;
	int y = rand() % noise.rows;
	// 소금, 후추 잡음 생성
	noise.at<uchar>(y, x) = (i % 2) * 255;
}

Mat median;

medianBlur(src, median, 3);

imshow("src", src);
imshow("noise", noise);
imshow("median", median);

waitKey();
destroyAllWindows();

실행 결과는 아래와 같습니다.