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 中值滤波与双边滤波

OpenCV 图像处理 (线性滤波,非线性滤波 - 方框滤波均值滤波高斯滤波中值滤波,双边滤波)

opencv学习-均值滤波高斯滤波中值滤波双边滤波

非线性滤波:中值滤波;双边滤波

从0到1学Python丨图像平滑方法的两种非线性滤波:中值滤波双边滤波

Atitit   图像处理 平滑 也称 模糊, 归一化块滤波高斯滤波中值滤波双边滤波)