图像平滑处理 双边滤波 (Bilateral Filter)

    原理   

        双边滤波(Bilateral filter)是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波的基本思想是:将高斯滤波(空间临近)的原理中,通过各个点到中心点的空间临近度计算的各个权值进行优化,将其优化为空间临近度计算的权值 和 像素值相似度计算的权值的乘积,优化后的权值再与图像作卷积运算。从而达到保边去噪的效果。
       双边滤波器的好处是可以做边缘保存(edge preserving),一般用高斯滤波去降噪,会较明显地模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

下图是双边滤波的原理示意图:

图像平滑处理 双边滤波 (Bilateral Filter)_第1张图片

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

这里写图片描述

权重系数w(i,j,k,l)取决于定义域核 

这里写图片描述

和值域核 

这里写图片描述

的乘积,也就是 

这里写图片描述

       d函数是根据像素距离选择权重,距离越近权重越大,这一点和方框滤波,高斯滤波方式相同。而r函数则是根据像素的差异来分配权值。如果两个像素值越接近,即使相距较远,也比差异大而距离近的像素点权重大。正是r函数的作用,使得边缘,即相距近但差异大的像素点的特性得以保留。

C++ API函数 

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

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

Mat image1;
Mat image2;

void on_Trackbar(int, void*)
{
	bilateralFilter(image1, image2, g_d, g_sigmaColor, g_sigmaSpace);
	imshow("output", image2);
}

int main()
{
	image1 = imread("test.png", IMREAD_COLOR);

	image2 = Mat::zeros(image1.rows, image1.cols, image1.type());
	bilateralFilter(image1, image2, g_d, g_sigmaColor, g_sigmaSpace);

	namedWindow("output");

	createTrackbar("核直径", "output", &g_d, 50, on_Trackbar);
	createTrackbar("颜色空间方差", "output", &g_sigmaColor, 100, on_Trackbar);
	createTrackbar("坐标空间方差", "output", &g_sigmaSpace, 100, on_Trackbar);

	imshow("input", image1);
	imshow("output", image2);

	waitKey();
	return 0;
}

图像平滑处理 双边滤波 (Bilateral Filter)_第2张图片

 很明显,粗糙的皮肤得到了平滑,该算法对皮肤不佳的妹子有奇效。

 参考:

https://www.jianshu.com/p/8d11e26c9665

https://blog.csdn.net/keith_bb/article/details/54427779

 

你可能感兴趣的:(【OpenCV_平滑】)