1 什么是高斯滤波?
高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。[1]通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。
2 基本原理
数值图像处理中,高斯滤波主要可以使用两种方法实现。一种是离散化窗口滑窗卷积,另一种方法是通过傅里叶变化。最常见的就是滑窗实现,只有当离散化的窗口非常大,用滑窗计算量非常搭的情况下,可能会考虑基于傅里叶变化的实现方法。所以本文将主要介绍滑窗实现的卷积。
离散化窗口划船卷积时主要利用的是高斯核,高斯核的大小为奇数,因为高斯卷积会在其覆盖区域的中心输出结果。常用的高斯模板有如下几种形式:
高斯模板是通过高斯函数计算出来的,公式如下:
以3 × 3的高斯滤波器模板为例,以模板的中心位置为坐标原点进行取样。模板在各个位置的坐标,如下所示(x轴水平向右,y轴竖直向上)。
这样,将各个位置的坐标带入到高斯函数G中,得到的每个值按照位置排列,就得到了模板。
这样输出的模板有两种形式:
① 小数类型:直接计算得到的值,没有经过任何处理。
② 整数类型:将得到的值进行归一化处理,即将坐上叫的值归一化为1,其他每个系数都除以左上角的系数,然后取整。在使用整数模板时,则需要在模板的前面加一个系数,该系数为模板系数之和的倒数。
例如:生成高斯核为3 × 3,σ = 0.8的模板
再经过四舍五入和添加系数得到最终结果:
从以上描述中我们可以看出,高斯滤波模板中最重要的参数就是高斯分布的标准差σ。它代表着数据的离散程度,如果σ较小,那么生成的模板中心系数越大,而周围的系数越小,这样对图像的平滑效果就不是很明显;相反,σ较大时,则生成的模板的各个系数相差就不是很大,比较类似于均值模板,对图像的平滑效果就比较明显。通过下面的一维高斯分布图也可验证上述观点。
3 GaussianBlur函数API
void GaussianBlur(InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY=0,
int borderType=BORDER_DEFAULT);
src,输入图像,即源图像,填Mat类的对象即可。它可以是单独的任意通道数的图片,
但需要注意,图片深度应该为CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
dst,即目标图像,需要和源图片有一样的尺寸和类型。比如可以用Mat::Clone,以源图片为模板,
来初始化得到如假包换的目标图。
ksize,高斯内核的大小。其中ksize.width和ksize.height可以不同,但他们都必须为正数和奇数
(并不能理解)。或者,它们可以是零的,它们都是由sigma计算而来。
sigmaX,表示高斯核函数在X方向的的标准偏差。
sigmaY,表示高斯核函数在Y方向的的标准偏差。若sigmaY为零,就将它设为sigmaX,
如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height计算出来。
4 C++应用示例
Created by duyq on 2020/4/7.//
#include #include
using namespace std;
using namespace cv;
int main()
{
cv::namedWindow("Orgin Image", cv::WINDOW_AUTOSIZE);
cv::namedWindow("Gaussian Blur Image", cv::WINDOW_AUTOSIZE);
// 读取图像,并用输入的窗口显示输入图像 cv::Mat img = cv::imread("/home/duyq/workspace/cpp/demo/MyCPPDemo/opencv/demo01_base/lena.jpg", -1);
if (img.empty())
{
cout << "Could not load image ..." << endl;
return -1;
}
cv::imshow("Orgin Image", img);
// 声明输出矩阵 cv::Mat out;
// 进行平滑操作,可以使用GaussianBlur()、blur()、medianBlur()或bilateralFilter() // 此处共进行了两次模糊操作 cv::GaussianBlur(img, out, cv::Size(5, 5), 3, 3);
cv::GaussianBlur(out, out, cv::Size(5, 5), 3, 3);
// 在输出窗口显示输出图像 cv::imshow("Gaussian Blur Image", out);
// 等待键盘事件 cv::waitKey(0);
destroyAllWindows();
return 0;
}
5 运行结果