目录
- 原理
- 二维高斯分布
- 生成高斯掩膜(小数形式)
- 源码及效果
平台:Windows 10 20H2
Visual Studio 2015
OpenCV 4.5.3
原理
高斯滤波和均值滤波一样,都是利用一个掩膜和图像进行卷积求解。不同之处在于:均值滤波器的模板系数都是相同的为1,而高斯滤波器的模板系数,则随着距离模板中心的增大而系数减小(服从二维高斯分布)。所以,高斯滤波器相比于均值滤波器对图像个模糊程度较小,更能够保持图像的整体细节。
二维高斯分布
要产生一个3×3的高斯滤波器模板,以模板的中心位置为坐标原点进行取样。模板在各个位置的坐标,如下所示(x轴水平向右,y轴竖直向下)
这样,将各个位置的坐标带入到高斯函数中,得到的值就是模板的系数。
对于窗口模板的大小为 (2k+1)×(2k+1),模板中各个元素值的计算公式如下:
模板有两种形式:小数和整数。
小数形式的模板,就是直接计算得到的值,没有经过任何的处理;
整数形式的模板,需要进行归一化处理,将模板左上角的值归一化为1。使用整数的模板时,需要在模板的前面加一个系数,系数为模板系数和的倒数。
生成高斯掩膜(小数形式)
首先我们要确定我们生成掩模的尺寸wsize,然后设定高斯分布的标准差。首先根据模板的大小,找到模板的中心位置center。 然后就是遍历,根据高斯分布的函数,计算模板中每个系数的值。
最后模板的每个系数要除以所有系数的和。这样就得到了小数形式的模板。
源码及效果
3×3,σ=0.8的小数型模板:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
//x,y方向联合实现获取高斯模板
//
void generateGaussMask(cv::Mat& Mask, cv::Size wsize, double sigma)
{
Mask.create(wsize, CV_64F);
int h = wsize.height;
int w = wsize.width;
int center_h = (h - 1) / 2;
int center_w = (w - 1) / 2;
double sum = 0.0;
double x, y;
for (int i = 0; i < h; ++i)
{
y = pow(i - center_h, 2);
for (int j = 0; j < w; ++j)
{
x = pow(j - center_w, 2);
//因为最后都要归一化的,常数部分可以不计算,也减少了运算量
double g = exp(-(x + y) / (2 * sigma*sigma));
Mask.at<double>(i, j) = g;
sum += g;
}
}
Mask = Mask / sum;
cout << '[' << endl;
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
cout << Mask.at<double>(i, j) << '\t';
}
cout << endl;
}
cout << ']' << endl;
}
int main(int argc, char * argv[])
{
Mat Mask;
Size TestSize;
TestSize.width = TestSize.height = 3;
generateGaussMask(Mask, TestSize, 0.8);
system("pause");
return 0;
}
3×3,σ=1.5的小数型模板:
5×5, σ=0.8的小数型模板: