目录
- 原理
- 二维高斯分布
- 生成高斯掩膜(小数形式)
- 源码及效果
平台:Windows 10 20H2
Visual Studio 2015
OpenCV 4.5.3
本文算法摘自高斯滤波(GaussianFilter)原理及C++实现 —— 小武~~
原理
高斯滤波和均值滤波一样,都是利用一个掩膜和图像进行卷积求解。不同之处在于:均值滤波器的模板系数都是相同的为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的小数型模板: