您的位置:首页 > 运维架构

opencv学习(二十一)之中值滤波medianBlur

2017-01-14 16:49 225 查看
中值滤波是一种典型的非线性滤波,是基于排序统计理论的一种能够有效抑制噪声的非线性信号处理技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,让周围的像素值接近真实的值从而消除孤立的噪声点。该方法在取出脉冲噪声、椒盐噪声的同时能保留图像的边缘细节。这些优良特性是线性滤波所不具备的。

中值滤波首先也得生成一个滤波模板,将该模板内的各像素值进行排序,生成单调上升或单调下降的二维数据序列,二维中值滤波输出为g(x, y)=medf{f(x-k, y-1),(k, l∈w)},其中f(x,y)和g(x,y)分别是原图像和处理后图像, w为输入的二维模板,能够在整幅图像上滑动,通常尺寸为3*3或5*5区域,也可以是不同的形状如线状、圆形、十字形、圆环形等。通过从图像中的二维模板取出奇数个数据进行排序,用排序后的中值取代要处理的数据即可。

中值滤波对消除椒盐噪声非常有效,能够克服线性滤波器带来的图像细节模糊等弊端,能够有效保护图像边缘信息,是非常经典的平滑噪声处理方法。在光学测量条纹图像的香味分析处理方法中有特殊作用,但在条纹中心分析方法中作用不大。

中值滤波相较于线性滤波中的均值滤波优点在前面已经提到,取得良好滤波效果的代价就是耗时的提升,可能达到均值滤波的数倍,而且对于细节较多的图像也不太适用。

opencv中提供了medianBlur()函数实现了中值滤波操作,其原型如下:

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


参数解释:

. InputArray src: 输入图像,图像为1、3、4通道的图像,当模板尺寸为3或5时,图像深度只能为CV_8U、CV_16U、CV_32F中的一个,如而对于较大孔径尺寸的图片,图像深度只能是CV_8U。

. OutputArray dst: 输出图像,尺寸和类型与输入图像一致,可以使用Mat::Clone以原图像为模板来初始化输出图像dst

. int ksize: 滤波模板的尺寸大小,必须是大于1的奇数,如3、5、7……

示例程序:

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

using namespace std;
using namespace cv;

//定义全局变量
Mat g_mSrcImage;
Mat g_mDstImage;
const int g_nMedianBlurMaxValue = 5;
int g_nMedianBlurValue;
int g_nkernelSize;

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

int main()
{
g_mSrcImage = imread("lena.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(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);
}


运行结果:



程序说明:

对于程序中对图像深度的判断根据如下标准:

CV_8U - 8-bit unsigned integers ( 0..255 )
CV_8S - 8-bit signed integers ( -128..127 )
CV_16U - 16-bit unsigned integers ( 0..65535 )
CV_16S - 16-bit signed integers ( -32768..32767 )
CV_32S - 32-bit signed integers ( -2147483648..2147483647 )
CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )
CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息