关于高斯滤波的一些理解

2021年9月6日 6点热度 0条评论 来源: 大熊背

一、滤波算法简介

         图像处理中,常用的滤波算法有均值滤波、中值滤波以及高斯滤波等。均值滤波使用模板内所有像素的平均值代替模板中心像素灰度值,这种方法易收到噪声的干扰,不能完全消除噪声,只能相对减弱噪声;中值滤波计算模板内所有像素中的中值,并用所计算出来的中值体改模板中心像素的灰度值,这种方法对噪声不是那么敏感,能够较好的消除椒盐噪声,但是容易导致图像的不连续性。高斯滤波对图像邻域内像素进行平滑时,邻域内不同位置的像素被赋予不同的权值,对图像进行平滑的同时,同时能够更多的保留图像的总体灰度分布特征。

二、高斯滤波

        数值图像处理中,高斯滤波主要可以使用两种方法实现。一种是离散化窗口滑窗卷积,另一种方法是通过傅里叶变化。在这我主要想说说第一种方法的高斯滤波。离散化窗口滑窗卷积的时,主要利用的是高斯核,高斯核一般是一个奇数的大小的高斯模板。常用的高斯模板有如下几种形式:

       上图所示是常用的两种高斯模板, 左侧是常用的3*3的高斯模板,右侧是常用的5*5高斯模板。那么,上述高斯模板中的参数是怎么得到的呢?这是我第一次接触高斯滤波时,一直不太明白的问题。经过一段时间的学习,查阅资料。才渐渐明白高斯模板中的参数是如何得到的!

       高斯模板中的参数是通过高斯函数计算出来的。计算高斯模板参数时,通过如下公式:

    x的平方和y的平方分别表示的是邻域内其他像素与邻域内中心像素的距离,Sigmma代表的是标准差。

    如上图所示由二维高斯图像可知,标准差越小,二维高斯图像越窄小,平滑效果不明显;标准差越大,而为高斯图像越矮宽,滤波效果比较明显。主要代码如下:

        
        double weight;
	double sum = 0;
	double Sigmma = 1;

	double Gaussian_Temp[SIZE][SIZE] = {0};
	int i,j;

	weight = 2*PI*Sigmma*Sigmma;
	for(i =0;i <SIZE;i++)
	{
		for(j = 0;j < SIZE;j++)
		{
			Gaussian_Temp[i][j] =exp(-((i-SIZE/2)*(i-SIZE/2)+(j-SIZE/2)*(j-SIZE/2))/(2.0*Sigmma*Sigmma));
			sum += Gaussian_Temp[i][j];
		}
	}

	for(i = 0; i < SIZE;i++)
	{
			for(j = 0;j < SIZE;j++)
		{
			Gaussian_Temp[i][j] = Gaussian_Temp[i][j]/sum;//归一化处理
			printf("%f ",Gaussian_Temp[i][j]);
		}
			printf("\n");
	}

        以5*5高斯模板为例,计算出来的高斯模板值为:

        计算出来的结果与上图5*5的高斯模板有一定差异,为什么会不一样呢?查阅资料,解释到:高斯模板实际上也就是模拟高斯函数的特征,具有对称性并且数值由中心向四周不断减小,上述图像中的5*5这个模板刚好符合这样的特性,并且非常简单,容易被大家接受,于是就比较经典。也就是说上述图像中5*5的高斯模板只是对二维高斯函数理论上计算出来的值的一种近似处理,如何从理论上的计算出来的值得到图片中5*5的高斯模板呢?我是这么理解高斯模板中各个参数得由来,如何从理论值得到高斯模板中的值还不太清楚!!

      此外,计算高斯模板参数时,需要归一化处理,为什么需要进行归一化处理呢?我的理解如下:

​      这是一维高斯函数概率密度函数图像。横轴表示可能得取值x,竖轴表示概率分布密度F(x),由高斯概率密度函数可知,那么不难理解这样一个曲线与x轴围成的图形面积为1。在实际应用中,在计算离散近似的时候,在大概距离之外的像素都可以看作不起作用这些像素的计算也就可以忽略。也就是说,为了尽可能的模拟高斯函数的相关性质,计算高斯模板的时候,计算出来的高斯模板中各个数值其和必须为1,这也就是为什么需要进行归一化的原因。

    高斯函数计算出来的模板之所以归一化,另外一种解释是:归一化之后,通过卷积计算出来的模板中心像素被限制到了0-255的灰度区间中。假若某一邻域内所有像素的灰度值为255,利用该模板进行卷积之后,求得的模板中心像素灰度值仍然为255;假若计算出来的高斯模板参数之和小于1,那么通过该模板进行卷积之后,模板中心像素的灰度值将小于255,偏离了实际的灰度值,产生了误差。

       归一化的原因更加正确的表述应该为:对灰度级为常数的图像区域,高斯模板的响应该为1。这样才能确保灰度级为常数的图像区域经过高斯模板处理之后,依旧为其本身,而不是被改变为其他灰度级。

     假设 sigma=1,高斯滤波模板大小为3*3,则计算出来的高斯模板为:

    其权重和为0.999984,假若某一邻域内所有像素的灰度值为255,利用该模板进行卷积之后,求得的模板中心像素灰度值将小于255,为254.9954;

    假设上述权重稍稍修改下,不进行归一化,且其高斯权重之和大于1:

    假若某一邻域内所有像素的灰度值为255(或者其他图像平坦区域,白墙或者灯箱里的灰色背景灯),利用该模板进行卷积之后,求得的模板中心像素灰度值将大于255,当其权重之和等于1.044732,则计算出来的中心像素1.044732*255=266.3148将大于255.

    将上述各权重除以1.044732即可进行归一化。归一化后的权重为:

    此外,sigma(标准差)决定了这个图形的宽度,sigma越大,则图形越宽,尖峰越小,图形较为平缓;sigma越小,则图形越窄,越集中,中间部分也就越尖,图形变化比较剧烈。这其实很好理解,如果sigma也就是标准差越大,则表示该密度分布一定比较分散,由于面积为1,于是尖峰部分减小,宽度越宽(分布越分散);同理,当sigma越小时,说明密度分布较为集中,于是尖峰越尖,宽度越窄!

    即,sigma越大,分布越分散,各部分比重差别不大,于是生成的模板各元素值差别不大,类似于平均模板;sigma越小,分布越集中,中间部分所占比重远远高于其他部分,反映到高斯模板上就是中心元素值远远大于其他元素值,于是自然而然就相当于中间值得点运算。

OpenCV中标准差与窗口大小的换算

对于高斯函数而言,以均值为中心半径为3σ的范围内已经包含了高斯函数97%以上的信息。下图分别是均值为0,σ为1,横纵坐标范围为[-4,4]的一维高斯函数和二维高斯函数图像,可以明显的看到3σ之外的信息基本无用。

3σ范围内一维高斯函数和二维高斯函数图像 由此信息我们可以得出,当我们知道高斯函数σ大小后,高斯核大小可以取
ceil(3·sigma).在OpenCV函数
createGaussianFilter中,若未指定窗口大小,通过σ推算窗口大小方式如下,半径为σ的3或4倍:

     若指定了窗口大小,但未指定σ大小,则通过窗口大小推算σ的方式如下:σ=0.3×((ksize−1)×0.5−1)+0.8具体地,在函数getGaussianKernel中,当ksize不大于7时,直接从内部的small_gaussian_tab取对应大小的高斯核,若大于7,则使用上式计算出σ然后套用高斯公式,最后再归一化。

    在实际使用时,为了高效,卷积核通常取[0,255]范围内的整数(1个Byte),因此高斯核中心最大取值为255时,窗口尺寸的选取只需让高斯核边界值刚好大于0即可。令高斯核尺寸为n,半径为r,,高斯核x轴上边界(r,0)处与中心(0,0)

处数值之比如下:

g_edge / g_center = exp(-(x²+y²)/(2σ²))
                  = exp(-((n-1)/2)²/(2*(0.3((n-1)/2)+0.8)²))

    当n足够大,其极限为:

exp(-1/(2*0.3²)) = 0.00386592

    公式sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8 . 注意到 1/256=0.00390625,图像像素一般按照8bit存储,公式中0.3是为了保证高斯核内所有像素都将影响输出结果。假若中心值为255,则边界值为255∗0.00386592=0.9858096≈1,是合适的。至于公式中的0.8可能是为了保证当n足够小的时候得到合适的输出结果。

四、从另外视角确定高斯滤波标准差与窗口大小关系

    我们知道对于核大小为(2M+1)*(2M+1)的二维高斯滤波函数的权重值可以通过如下公式计算:

  其中,上式表示均值为0,方差为。因为滤波尺寸为(2M+1)*(2M+1),所以滤波器值在截断点为,希望滤波器平滑的降低到0,所以滤波器的最终值应该很小。假设记作为,则参数应该满足如下关系式

 圆圈代表用来在黑色点出计算尺寸为(2M+1)*(2M+1)的平滑滤波器值的高斯函数的等高线。点O为坐标点(0,0)处,有上述公式可知,其结果为1,在5*5的方形外其值都为0.截断导致最大步长的位置为A,B,C,D,在这些点由上述公式,这些点的坐标 为(±M,0)(0,±M)。对于,可计算出M=2时,应该为0.659;M=3时,应该为2.0989,M=4时,应该为1.318.最后其他权重可以通过计算得出。当M=2,3,4确定的权重值为:

    归一化之后的结果为:

    用MATLAB生成的高斯函数模板参数对比为:其中calc Gaussian filter para为按照上述方法计算得到的参数,original Gaussian filter为原始的高斯滤波公式计算得出的结果。当M= 1时,Sigma=0.8时,其,生成的权重值为:

    用于MATLAB生成的高斯函数模板参数对比为:当M= 2时,Sigma=0.8时,其,生成的权重值为:

    用于MATLAB生成的高斯函数模板参数对比为:当M= 3时,Sigma=0.8时,其,生成的权重值为:

参考文献:

http://lps-683.iteye.com/blog/2251180

如何确定高斯滤波的标准差和窗口大小

Calculate the Gaussian filter's sigma using the kernel's size

Image Processing: The Fundamentals  P353

    原文作者:大熊背
    原文地址: https://blog.csdn.net/lz0499/article/details/54015150
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。