C++版本OpenCv教程(三十)高斯滤波

高斯噪声是一种常见的噪声,图像采集的众多过程中都容易引入高斯噪声,因此针对高斯噪声的高斯滤波也广泛应用于图像去噪领域。高斯滤波器考虑了像素离滤波器中心距离的影响,以滤波器中心位置为高斯分布的均值,根据高斯分布公式和每个像素离中心位置的距离计算出滤波器内每个位置的数值,从而形成一个形如图5-15所示的高斯滤波器。之后将高斯滤波器与图像之间进行滤波操作,进而实现对图像的高斯滤波。
在这里插入图片描述
OpenCV 4提供了对图像进行高斯滤波操作的GaussianBlur()函数,该函数的函数原型在代码清单5-13中给出。

void cv::GaussianBlur(InputArray  src,
                       OutputArray  dst,
                       Size  ksize,
                       double  sigmaX,
                       double  sigmaY = 0,
                       int  borderType = BORDER_DEFAULT 
                       )
  • src:待高斯滤波图像,图像可以具有任意的通道数目,但是数据类型必须为CV_8U,CV_16U,CV_16S,CV_32F或CV_64F。
  • dst:输出图像,与输入图像src具有相同的尺寸、通道数和数据类型。
  • ksize:高斯滤波器的尺寸,滤波器可以不为正方形,但是必须是正奇数。如果尺寸为0,则由标准偏差计算尺寸。
  • sigmaX:X方向的高斯滤波器标准偏差。
  • sigmaY:Y方向的高斯滤波器标准偏差;如果输入量为0,则将其设置为等于sigmaX,如果两个轴的标准差均为0,则根据输入的高斯滤波器尺寸计算标准偏差。
  • borderType:像素外推法选择标志,取值范围在表3-5中给出,默认参数为BORDER_DEFAULT,表示不包含边界值倒序填充。

该函数能够根据输入参数自动生成高斯滤波器,实现对图像的高斯滤波,函数的前两个参数与前面介绍的滤波函数的参数含义相同。该函数第三个参数是高斯滤波器的尺寸,与前面函数不同的是,该函数除了必须是正奇数以外,还允许输入尺寸为0,当输入的尺寸为0时,会根据输入的标准偏差计算滤波器的尺寸。函数第四个和第五个参数为X方向和Y方向的标准偏差,当Y方向参数为0时表示Y方向的标准偏差与X方向相同,当两个参数都为0时,则根据输入的滤波器尺寸计算两个方向的标准偏差数值。但是为了能够使计算结果符合自己的预期,建议将第三个参数、第四个参数和第五个参数都明确的给出。

高斯滤波器的尺寸和标准偏差存在着一定的互相转换关系,OpenCV 4提供了输入滤波器单一方向尺寸和标准偏差生成单一方向高斯滤波器的getGaussianKernel()函数,在函数的定义中给出了滤波器尺寸和标准偏差存在的关系,这个关系不是数学中存在的关系,而是OpenCV 4为了方便而自己设定的关系。在了解这个关系之前,我们首先了解以下getGaussianKernel()函数,该函数的函数原型在代码清单5-14中给出。

Mat cv::getGaussianKernel(int  ksize,
                          double  sigma,
                          int  ktype = CV_64F 
                          )
  • ksize:高斯滤波器的尺寸。
  • sigma:高斯滤波的标测差。
  • ktype:滤波器系数的数据类型,可以是CV_32F或者CV_64F,默认数据类型为CV_64F。

该函数用于生成指定尺寸的高斯滤波器,需要注意的是该函数生成的是一个ksize×1的Mat类矩阵。函数第一个参数是高斯滤波器的尺寸,这个参数必须是一个正奇数。第二个参数表示高斯滤波的标准差,这个参数如果是一个负数,则调用程序中默认的高斯滤波器尺寸与标准差的公式,其计算公式如式(5.4)所示。
在这里插入图片描述
生成一个二维的高斯滤波器需要调用两次getGaussianKernel()函数,将X方向的一维高斯滤波器和Y方向的一维高斯滤波器相乘,得到最终的二维高斯滤波器。例如计算的X方向的一维滤波器和Y方向的一维滤波器均如式(5.5)所示。
在这里插入图片描述
最终二维高斯滤波器计算过程和结果如式(5.6)所示。
在这里插入图片描述
为了了解高斯滤波对不同噪声的去除效果,在代码清单5-15中利用高斯滤波分别处理不含有噪声的图像、含有椒盐噪声的图像和含有高斯噪声的图像,处理结果在图5-16、图5-17、图5-18中给出。通过结果可以发现,高斯滤波对高斯噪声去除效果较好,但是同样会对图像造成模糊,并且滤波器的尺寸越大,滤波后图像变得越模糊。

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;

int main(){
    
    
    Mat img=imread("luffy.jpg",IMREAD_ANYDEPTH);//用于方框滤波
    Mat luffy;
    resize(img,luffy,Size(img.rows/3,img.cols/3));
    Mat luffy_gauss=imread("luffy_gauss.jpg",IMREAD_ANYDEPTH);
    Mat luffy_salt=imread("luffy_salt.jpg",IMREAD_ANYDEPTH);
    if(luffy.empty()||luffy_gauss.empty()||luffy_salt.empty()){
    
    
        cout<<"请确认输入的图片路径是否正确"<<endl;
        return -1;
    }
    Mat result_5,result_9;//存放不含早生结果,后面数组代表滤波器尺寸
    Mat result_5gauss,result_9gauss;//存放含有高斯噪声滤波结果,后面数字代表滤波器尺寸
    Mat result_5salt,result_9salt;//存放含有椒盐噪声的滤波结果,后面数字代表滤波器尺寸
    //调用均值滤波函数blur()进行滤波
    GaussianBlur(luffy,result_5,Size(5,5),10,20);
    GaussianBlur(luffy,result_9,Size(9,9),10,20);
    GaussianBlur(luffy_gauss,result_5gauss,Size(5,5),10,20);
    GaussianBlur(luffy_gauss,result_9gauss,Size(9,9),10,20);
    GaussianBlur(luffy_salt,result_5salt,Size(5,5),10,20);
    GaussianBlur(luffy_salt,result_9salt,Size(9,9),10,20);
    //显示不含早生图像
    imshow("luffy",luffy);
    imshow("result_5",result_5);
    imshow("result_9",result_9);
    //显示含有高斯噪声图像
    imshow("luffy_gauss",luffy_gauss);
    imshow("result_5gauss",result_5gauss);
    imshow("result_9gauss",result_9gauss);
    //显示含有椒盐噪声图像
    imshow("luffy_salt",luffy_salt);
    imshow("result_5salt",result_5salt);
    imshow("result_9salt",result_9salt);
    waitKey(0);
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_33287871/article/details/112461916