OPENCV入门之六非线性滤波(中值滤波双边滤波)
Posted Haven_zhf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OPENCV入门之六非线性滤波(中值滤波双边滤波)相关的知识,希望对你有一定的参考价值。
参考网站:
http://blog.csdn.net/poem_qianmo/article/details/23184547
在很多情况下,比如在噪声是散粒噪声而不是高斯噪声时(图像偶尔会出现很大的值的时候),在这种情况下,用高斯滤波器对图像进行模糊的话,噪声是不会被去除的,它们只是转换为更为柔和但仍然可见的散粒。而用非线性滤波会更好些。
1、中值滤波(Median filter)——medianBlur函数
该方法在去除脉冲噪声、斑点噪声(speckle noise)、椒盐噪声(salt-and-pepper noise)、图像扫描噪声,的同时又能保留凸图像边缘细节。
中值滤波与均值滤波比较:
优势是,在均值滤波器中,由于噪声成分被放入平均计算中,所以输出受到了噪声的影响;而在中值滤波其中,噪声成分很难选上,所以几乎不会影响到输出。
劣势是,中值滤波花费的时间是均值滤波的5倍以上。
注意:中值滤波虽然可以克服线性滤波器所带来的图像细节模糊,但是在线、尖顶等细节多的图像不宜用中值滤波。
void medianBlur(InputArray src,
OutputArray dst,
int ksize) //孔径的线性尺寸(aperture linear size),参数必须是大于1的奇数,比如3,5,7,9
1 //载入原图 2 Mat image=imread("1.jpg"); 3 //进行中值滤波操作 4 Mat out; 5 medianBlur( image, out, 7);
2、双边滤波(Bilateral filter)——bilateralFilter函数
其实结合图像的空间领近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。
优点是,可以做边缘保存(edge preserving)。
缺点是,保存了过多的高频信息,对彩色图像里的高频噪声,不能够干净的滤掉,只能够对于低频信息进行较好的滤波。
void bilateralFilter(InputArray src,
OutputArraydst,
int d, //过滤过程中每个像素领域的直径
double sigmaColor, //颜色空间滤波器的sigma值。这个参数越大,表明该像素领域内有更宽广的颜色会被混合到一起,
产生较大的半相等颜色区域
double sigmaSpace, //坐标空间中滤波器的sigma值,坐标空间的标注方差。这个数值越大,表明越远的像素会相互影响,
从而使更大的区域足够相似的颜色获取相同的颜色。
int borderType=BORDER_DEFAULT)
1 //载入原图 2 Mat image=imread("1.jpg"); 3 //进行双边滤波操作 4 Mat out; 5 bilateralFilter( image, out, 25, 25*2, 25/2 );
3、综合实践:
1 //******************************【程序说明】***************************** 2 // 程序名称:非线性滤波(中值滤波、双边滤波) 3 // opencv版本:2.4.13 4 // 日期:2017/9/21 5 //********************************************************************** 6 7 8 //******************************【头文件包含部分】***************************** 9 // 描述:包含程序所依赖的头文件 10 //***************************************************************************** 11 #include <opencv2/core/core.hpp> 12 #include <opencv2/highgui/highgui.hpp> 13 #include <opencv2/imgproc/imgproc.hpp> 14 #include <iostream> 15 16 17 //******************************【命名空间声明部分】***************************** 18 // 描述:包含程序所使用的命名空间 19 //***************************************************************************** 20 using namespace std; 21 using namespace cv; 22 23 24 //******************************【全局变量声明部分】***************************** 25 // 描述:全局变量声明 26 //***************************************************************************** 27 Mat g_srcImage,g_dstImage1, g_dstImage2, g_dstImage3, g_dstImage4, g_dstImage5; //存储图片的Mat类型 28 int g_nBoxFilterValue = 6; //方框滤波参数值 29 int g_nMeanBlurValue = 10; //均值滤波参数值 30 int g_nGaussianBlurValue = 6; //高斯滤波参数值 31 int g_nMedianBlurValue = 10; //中值滤波参数值 32 int g_nBilateralFilterValue = 10; //双边滤波参数值 33 34 35 //******************************【全局函数声明部分】***************************** 36 // 描述:全局函数声明 37 //***************************************************************************** 38 //轨迹条的回调函数 39 static void on_BoxFilter(int, void* ); //方框滤波 40 static void on_MeanBlur(int, void*); //均值滤波 41 static void on_GaussianBlur(int, void*); //高斯滤波 42 static void on_MedianBlur(int, void*); //中值滤波 43 static void on_BilateralFilter(int, void*); //双边滤波 44 45 46 //******************************【main()部分】***************************** 47 // 描述:控制台应用程序的入口函数,我们的程序从这里开始 48 //***************************************************************************** 49 int main() 50 { 51 //【0】初始化 52 system("color 5E"); 53 54 //【1】读取原图 55 g_srcImage = imread( "1.jpg", 1 ); 56 if(!g_srcImage.data) { printf("Oh,no,读取srcImage错误!!!!\n"); return false; } 57 58 //【2】克隆原图到三个Mat类型中 59 g_dstImage1 = g_srcImage.clone(); 60 g_dstImage2 = g_srcImage.clone(); 61 g_dstImage3 = g_srcImage.clone(); 62 g_dstImage4 = g_srcImage.clone(); 63 g_dstImage5 = g_srcImage.clone(); 64 65 //【3】显示原图 66 namedWindow("【<0>原图窗口】", 1 ); 67 imshow("【<0>原图窗口】", g_srcImage ); 68 69 //【4】滤波操作处理 70 //***********************【<1>方框滤波】******************* 71 namedWindow("【<1>方框滤波】", 1); 72 createTrackbar("内核值:", "【<1>方框滤波】", &g_nBoxFilterValue, 40, on_BoxFilter); 73 on_BoxFilter(g_nBoxFilterValue, 0); 74 imshow("【<1>方框滤波】", g_dstImage1); 75 76 //***********************【<2>均值滤波】******************* 77 namedWindow("【<2>均值滤波】", 1); 78 createTrackbar("内核值:", "【<2>均值滤波】", &g_nMeanBlurValue, 40, on_MeanBlur); 79 on_MeanBlur(g_nMeanBlurValue, 0); 80 imshow("【<2>均值滤波】", g_dstImage2); 81 82 //***********************【<3>高斯滤波】******************* 83 namedWindow("【<3>高斯滤波】", 1); 84 createTrackbar("内核值:", "【<3>高斯滤波】", &g_nGaussianBlurValue, 40, on_GaussianBlur); 85 on_GaussianBlur(g_nGaussianBlurValue, 0); 86 imshow("【<3>高斯滤波】", g_dstImage3); 87 88 //***********************【<4>中值滤波】******************* 89 namedWindow("【<4>中值滤波】", 1); 90 createTrackbar("内核值:", "【<4>中值滤波】", &g_nMedianBlurValue, 40, on_MedianBlur); 91 on_MedianBlur(g_nMedianBlurValue, 0); 92 imshow("【<4>中值滤波】", g_dstImage4); 93 94 //***********************【<5>双边滤波】******************* 95 namedWindow("【<5>双边滤波】", 1); 96 createTrackbar("内核值:", "【<5>双边滤波】", &g_nBilateralFilterValue, 40, on_BilateralFilter); 97 on_BilateralFilter(g_nBilateralFilterValue, 0); 98 imshow("【<5>双边滤波】", g_dstImage5); 99 100 //【5】输出一些有帮助的信息 101 cout<<endl<<"\t嗯。好了,请调整滚动条观察图像效果~\n\n" 102 <<"\t按下“q”键时,程序退出~!\n"; 103 104 //【6】按下“q”键时,程序退出 105 while(char(waitKey(1) != ‘q‘)){} 106 107 return 0; 108 } 109 110 111 //******************************【on_BoxFilter()部分】***************************** 112 // 描述:方框滤波操作的回调函数 113 //***************************************************************************** 114 static void on_BoxFilter(int, void* ) 115 { 116 boxFilter(g_srcImage, g_dstImage1, -1, Size(g_nBoxFilterValue+1, g_nBoxFilterValue+1)); 117 imshow("【<1>方框滤波】", g_dstImage1); 118 } 119 120 121 //******************************【on_MeanBlur()部分】***************************** 122 // 描述:均值滤波操作的回调函数 123 //***************************************************************************** 124 static void on_MeanBlur(int, void*) 125 { 126 blur(g_srcImage, g_dstImage2, Size(g_nMeanBlurValue+1, g_nMeanBlurValue+1), Point(-1, -1)); 127 imshow("【<2>均值滤波】", g_dstImage2); 128 } 129 130 131 //******************************【on_GaussianBlur()部分】***************************** 132 // 描述:高斯滤波操作的回调函数 133 //***************************************************************************** 134 static void on_GaussianBlur(int, void*) 135 { 136 GaussianBlur(g_srcImage, g_dstImage3, Size(g_nGaussianBlurValue*2+1, g_nGaussianBlurValue*2+1), 0, 0); 137 imshow("【<3>高斯滤波】", g_dstImage3); 138 } 139 140 141 //******************************【on_MedianBlur()部分】***************************** 142 // 描述:中值滤波操作的回调函数 143 //***************************************************************************** 144 static void on_MedianBlur(int, void*) 145 { 146 medianBlur(g_srcImage, g_dstImage4, g_nMedianBlurValue*2+1); 147 imshow("【<4>中值滤波】", g_dstImage4); 148 } 149 150 //******************************【on_BilateralFilter()部分】***************************** 151 // 描述:双边滤波操作的回调函数 152 //***************************************************************************** 153 static void on_BilateralFilter(int, void*) 154 { 155 bilateralFilter(g_srcImage, g_dstImage5, g_nBilateralFilterValue, g_nBilateralFilterValue*2, g_nBilateralFilterValue/2); 156 imshow("【<5>双边滤波】", g_dstImage5); 157 }
以上是关于OPENCV入门之六非线性滤波(中值滤波双边滤波)的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV 图像处理 (线性滤波,非线性滤波 - 方框滤波均值滤波高斯滤波中值滤波,双边滤波)