【机器视觉学习笔记】生成高斯滤波器掩膜(C++)

平台: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的小数型模板:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44457994/article/details/120900286