基本原理
双边滤波是《Bilateral Filtering for Gray and Color Images》论文提出的一种非线性滤波。它是一种结合图像的空间邻近度和像素相似度的折中处理,同时考虑空域信息和像素值相似性,从而达到去噪的同时保留边缘。原理是其滤波器的核由一个与空间距离相关的高斯函数与另一个与像素值距离相关的高斯函数相乘生成。所以
对于高斯滤波,仅仅用到空间距离的权重系数核与图像卷积确定中心点的像素。即离中心点越近的点,其权重系数越大。双边滤波加入像素值信息的权重,即在邻域内像数值越接近中心点像素值,其权重系数越大。
对于彩色图像,论文中建议在CIE-Lab 彩色空间里计算像素值之间的距离。
示例演示
我们调用OpenCV的双边滤波解决bilateralFilter。工程代码链接
void 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。
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int g_d = 15;
int g_sigmaColor = 20;
int g_sigmaSpace = 50;
Mat g_srcimg;
Mat g_dstimg;
void on_Trackbar(int, void*)
{
bilateralFilter(g_srcimg, g_dstimg, g_d, g_sigmaColor, g_sigmaSpace);
imshow("output", g_dstimg);
}
int main(int argc, char **argv)
{
g_srcimg = imread("D:\\TestData\\lena.jpg");
if (g_srcimg.empty())
{
cout << "Could not load image ... " << endl;
return -1;
}
g_dstimg = Mat::zeros(g_srcimg.rows, g_srcimg.cols, g_srcimg.type());
bilateralFilter(g_srcimg, g_dstimg, g_d, g_sigmaColor, g_sigmaSpace);
namedWindow("input");
createTrackbar("核直径", "input", &g_d, 50, on_Trackbar);
createTrackbar("颜色空间方差", "input", &g_sigmaColor, 100, on_Trackbar);
createTrackbar("坐标空间方差", "input", &g_sigmaSpace, 100, on_Trackbar);
imshow("input", g_srcimg);
imshow("output", g_dstimg);
waitKey(0);
return 0;
}