【拜小白opencv】32-平滑处理5非线性滤波之——双边滤波

来源:互联网 发布:微信签到抽奖源码 编辑:程序博客网 时间:2024/04/29 10:47

常言道“温故而知新”,写此文章就是对自己目前学习内容的小小的总结与记录。

本文力求用最简洁的语言,详细的代码将此部分内容讲解清楚,但由于博主同样是刚刚接触OpenCV,或许表达上有些瑕疵,还望读者能够指教探讨,大家共同进步。

博主机器配置为:VS2013+opencv2.4.13+Win-64bit。

若本文能给读者带来一点点启示与帮助,我就很开心了。

=========================分割线========================


1-双边滤波

  • 双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的,具有简单、非迭代、局部的特点。
  • 双边滤波器的好处是可以做边缘保存,这个特点对于一些图像模糊来说很有用。一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显地模糊边缘,对于高频细节的保护效果并不明显。一般的高斯模糊在进行采样时主要考虑了像素间的空间距离关系,但是却并没有考虑像素值之间的相似程度,因此这样我们得到的模糊结果通常是整张图片一团模糊。
  • 双边滤波的改进就在于在采样时不仅考虑像素在空间距离上的关系,同时加入了像素间的相似程度考虑。双边滤波器比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。对于脉冲噪声,双边滤波会把它当成边缘从而不能去除。

在双边滤波器中,输出像素的值依赖于邻域像素值的加权值组合,公式如下:

而加权系数w(i,j,k,l)取决于定义域核值域核的乘积。

其中定义域核表示如下


定义域滤波对应图示:

值域核表示为:

值域滤波:


两者相乘后,就会产生依赖于数据的双边滤波权重函数



=======================分割线====================

2-bilateralFilter()——双边滤波

OpenCV将双边滤波封装在bilateralFilter()函数中,作用是输入一副图像对其进行双边滤波。下面来看下bilateralFilter()函数的定义:

void bilateralFilter( InputArray src, OutputArray dst, int d,                                   double sigmaColor, double sigmaSpace,                                   int borderType=BORDER_DEFAULT );

参数说明:

  • 参数1:输入要处理的图像,需要为8位或者浮点型单通道、三通道的图像。
  • 参数2:得到处理后的输出图像,与输入图像有一样的尺寸和类型。
  • 参数3:表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。
  • 参数4:表示颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
  • 参数5:double类型的sigmaSpace坐标空间中滤波器的sigma值,坐标空间的标注方差。它的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
  • 参数6:用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT,我们一般不用管它。
=========================分割线=================

3-代码演示

/*功能:非线性滤波之双边滤波*/#include <opencv2/core/core.hpp>                #include <opencv2/highgui/highgui.hpp>    #include <opencv2/imgproc/imgproc.hpp>#include <iostream>   using namespace std;using namespace cv;int main(){//------------【1】读取源图像并检查图像是否读取成功------------   Mat srcImage = imread("D:\\OutPutResult\\ImageTest\\boat1.jpg");if (!srcImage.data){cout << "读取图片错误,请重新输入正确路径!\n";system("pause");return -1;}imshow("【源图像】", srcImage);//------------【2】对图像进行双边滤波处理------------   Mat dstImage;bilateralFilter(srcImage, dstImage, 9, 9 * 9, 9 / 2);//双边滤波imshow("【双边滤波】", dstImage);waitKey(0);return 0;}
======================分割线==================

4-显示结果


========================分割线=================

5-程序说明

可以发现双边滤波对图像物体的边缘信息保留的很完整。

参考文献:【OpenCV入门教程之九】 非线性滤波专场:中值滤波、双边滤波
====================END=======================



阅读全文
0 0
原创粉丝点击