Qt+OpenCV联合开发(二十八)--高斯双边模糊(bilateralFilter)

一、边缘保留滤波算法-高斯双边模糊

前面我们介绍的图像卷积处理无论是均值还是高斯都是属于模糊卷积,它们都有一个共同的特点就是模糊之后图像的边缘信息不复存在,受到了破坏。今天介绍的滤波方法有能力通过卷积处理实现图像模糊的同时对图像边缘不会造成破坏,滤波之后的输出完整的保存了图像整体边缘(轮廓)信息,我们称这类滤波算法为边缘保留滤波算法(EPF) 。最常见的边缘保留滤波算法有以下几种

  1. 高斯双边模糊(opencv中最常见)
  2. Meanshift均值迁移模糊
  3. 局部均方差模糊
  4. OpenCV中对边缘保留滤波还有一个专门的API

本章先来讲述高斯双边模糊,高斯模糊是考虑图像空间位置对权重的影响,但是它没有考虑图像像素分布对图像卷积输出的影响,双边模糊考虑了像素值分布的影响,对像素值空间分布差异较大的进行保留从而完整的保留了图像的边缘信息

Qt+OpenCV联合开发(二十八)--高斯双边模糊(bilateralFilter)_第1张图片

前面我们高斯模糊破坏了人物脸的轮廓,图像变得模糊不清,这其实是破坏了图像的原有信息。然后左上角黑白图,是一个输入图像,中间有明显的界限,黑、白两部分的像素都比较相似,但你会看到其中的小白点,也叫高斯噪声。

把这个灰度图像反映到一个三维上就是那个棕褐色的立体图。每一个点表示一个灰度值,这些点上面灰度值比较高的分布在立体图的左边,尖锐的部分表示有噪声。白色的小点,就是我们当前要对他进行高斯模糊的中心点。立体图右边对应图像黑色部分,像素值比较低,所以黑白两部分像素值有一定的落差,这个落差就是他们的交界部分。 

中两个权重的和,一个是色彩空间的,一个是坐标空间的,相乘得,那为什么没有了右半边?因为左上角黑白图的黑色部分跟白色部分差异很大,中心点还在白色部分这边,这个也叫做双边核,双边中一边是表示空间的,一边是表示RGB色彩的。两边的和组成的系数再去进行卷积操作,操作完得到右上角的黑白图,这个图保留了边缘,因为保留了色彩空间颜色值的差异,再用这个图构建右上角的三维图,这个三维图的噪声都没了,但是差异还在

二、函数原型

bilateralFilter函数

c++原型:

参数:

  1. src: 输入图像,Mat类型,图像必须是8位或浮点型的图像,可以是单通道或三通道。
  2. dst: 输出图像,和原图像有相同的size和type。
  3. d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。一般用0表示
  4.  sigmaColor: 色彩空间过滤器的sigma值,这个参数的值越大,表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
  5. sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace
  6.  borderType:  图像边缘处理方式,有默认值BORDER_DEFAULT

补充:

sigmaColor 是颜色值的差异,取值要大一点,这个越大,sigma就越小,越趋近于0,影响就越低

sigmaSpace 是空间窗口的sigma,前面我们取10或者15

三、实现效果

Qt+OpenCV联合开发(二十八)--高斯双边模糊(bilateralFilter)_第2张图片

 根据滑动条进行调整:

Qt+OpenCV联合开发(二十八)--高斯双边模糊(bilateralFilter)_第3张图片

四、代码

void test1::biFilter_image(Mat &image)
{
    Mat dst;
    bilateralFilter(image,dst,0,100,10);
    imshow("bilateralFilter_image", dst);
}
void test1::biFilter_image2(Mat &image)
{

        g_src_img=image;
        //定义输出图像窗口属性和轨迹条属性
        namedWindow("bilateralFilter_image", WINDOW_AUTOSIZE);
        g_diamValue = 10;
        g_nsigmaColorValue = 10;
        g_nsigmaSpaceValue = 10;

        char diam_name[20];
        sprintf(diam_name, "Field diameter %d", g_ndMaxValue);

        char sigmaColorName[30];
        sprintf(sigmaColorName, "sigmaColor %d", g_nsigmaColorMaxValue);

        char sigmaSpaceName[30];
        sprintf(sigmaSpaceName, "sigmaSpace %d", g_nsigmaSpaceMaxValue);

        //创建轨迹条
        createTrackbar(diam_name, "bilateralFilter_image", &g_diamValue,
                       g_ndMaxValue, on_bilateralFilterTrackbar);
        on_bilateralFilterTrackbar(g_diamValue, 0);

        createTrackbar(sigmaColorName, "bilateralFilter_image", &g_nsigmaColorValue,
                         g_nsigmaColorMaxValue, on_bilateralFilterTrackbar);
        on_bilateralFilterTrackbar(g_nsigmaColorValue, 0);

        createTrackbar(sigmaSpaceName, "bilateralFilter_image", &g_nsigmaSpaceValue,
                        g_nsigmaSpaceMaxValue, on_bilateralFilterTrackbar);
        on_bilateralFilterTrackbar(g_nsigmaSpaceValue, 0);

}

 原创不易,转载请注明出处:

https://blog.csdn.net/hml111666/article/details/122829930

你可能感兴趣的:(opencv,Qt实战,C/C++,opencv,qt,计算机视觉)