Opencv学习之去噪方法(二)

中值滤波的基本原理:

选一个对称的滤波模板,模板边长为奇数,将模板的中心位置置于图像的任意一点,然后将模板在图像中包围的所有点的像素值按从大到小的顺序进行排列,找到排在最中间的值,把该值作为图像上模板中心位置的新像素值。

中值滤波能很好的保持画面的清晰度,抑制突变噪声效果较好,但对高斯噪声的抑制效果较差。

实现方法:

Opencv中提供了medianBlur()函数,使用时直接调用,函数原型如下:

C++: void medianBlur(InputArray src, OutputArray dst, int ksize)

第一个参数:输入图像,为1、3、4通道的图像。当ksize为3或5的时候,图像深度只能是CV_8U、CV_16U、CV_32F,而对于较大孔径尺寸的图像,深度只能是CV_8U。

第二个参数:输出图像,尺寸和类型与输入图像一致;

第三个参数:滤波模板尺寸大小,须为大于1的奇数。

例程演示:

#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

//定义全局变量
Mat g_mSrcImage;//定义原图像
Mat g_mDstImage;//定义目标图像
const int g_nMedianBlurMaxValue = 9;//定义轨迹条的最大值
int g_nMedianBlurValue;//定义轨迹条的初始值
int g_nkernelSize;//定义中值滤波模板大小

//定义回调函数
void on_medianBlurTrackBar(int, void*);

int main()
{
	g_mSrcImage = imread("D:\\Tencent\\test.jpg");

	//判断文件是否加载成功
	if (g_mSrcImage.empty())
	{
		cout << "图像加载失败!" << endl;
		return -1;
	}
	else
		cout << "图像加载成功!" << endl;

	//判断图像是否是CV_8U图像
	if (0 <= g_mSrcImage.depth() <= 255)
		cout << "加载图像符合处理要求!" << endl;
	else
	{
		cout << "图像深度不是CV_8U,程序即将退出..." << endl;
		return -1;
	}

	namedWindow("原图像", WINDOW_AUTOSIZE);
	imshow("原图像", g_mSrcImage);

	//输出图像窗口属性及轨迹条名称
	namedWindow("中值滤波图像", WINDOW_AUTOSIZE);
	char medianBlurName[20];
	sprintf_s(medianBlurName, "核函数尺寸 %d", g_nMedianBlurMaxValue);
	g_nMedianBlurValue = 1;

	//创建轨迹条
	createTrackbar(medianBlurName, "中值滤波图像", &g_nMedianBlurValue,
		g_nMedianBlurMaxValue, on_medianBlurTrackBar);
	on_medianBlurTrackBar(g_nMedianBlurValue, 0);

	waitKey(0);


	return 0;
}

void on_medianBlurTrackBar(int, void*)
{
	//重新计算尺寸值,尺寸值应为大于1的奇数
	g_nkernelSize = g_nMedianBlurValue * 2 + 1;
	medianBlur(g_mSrcImage, g_mDstImage, g_nkernelSize);

	imshow("中值滤波图像", g_mDstImage);

}

(注:程序为学习他人博客,在此表示感谢)

发现中值滤波的实现方法与均值滤波十分相似,只是多了判断图像深度的步骤。

运行结果与均值滤波运行结果相同(名称不同),就不再上传。


你可能感兴趣的:(Opencv)