这一次,我将较为深入地探讨高斯滤波,包括参数的影响、参数的选取、高斯模板的形成以及自行编程实现高斯滤波的效果与openCV函数实现效果比对。
首先,我们接(一)中最后所述的内容继续开始探讨。在(一)中,我们最后探讨了一下关于高斯函数中的sigma的选取对于模板生成的影响和对滤波效果的影响,但是我在(一)中我未给详细地解释,这里我想比较通俗地并且具体地阐述一下这些影响的成因:
上回书说道“sigma表示的是标准差,如果标准差比较小,这是就相当于图像点运算,则平滑效果不明显;反之,标准差比较大,则相当于平均模板,比较模糊”,那么这么说可能很多人包括一开始的我并不是很理解,这是为什么呢,那么我们需要从高斯函数谈起:
这样一个高斯函数的概率分布密度如下图所示:
我们要理解好这个图,横轴表示可能得取值x,竖轴表示概率分布密度F(x),那么不难理解这样一个曲线与x轴围成的图形面积为1。sigma(标准差)决定了这个图形的宽度,我给出下述结论:sigma越大,则图形越宽,尖峰越小,图形较为平缓;sigma越小,则图形越窄,越集中,中间部分也就越尖,图形变化比较剧烈。这其实很好理解,如果sigma也就是标准差越大,则表示该密度分布一定比较分散,由于面积为1,于是尖峰部分减小,宽度越宽(分布越分散);同理,当sigma越小时,说明密度分布较为集中,于是尖峰越尖,宽度越窄!
理解好上述结论之后,那么(一)中的结论当然也就顺理成章了,sigma越大,分布越分散,各部分比重差别不大,于是生成的模板各元素值差别不大,类似于平均模板;sigma越小,分布越集中,中间部分所占比重远远高于其他部分,反映到高斯模板上就是中心元素值远远大于其他元素值,于是自然而然就相当于中间值得点运算。
程序也可以验证如下:
窗口尺寸:3*3 sigma = 0.1
窗口尺寸:3*3 sigma = 0.8
窗口尺寸:3*3 sigma = 2
接着,我们来重点讨论下高斯模板,在初学高斯滤波的时候,用得最多的也是最经典的一个3*3模板就是 1 2 1
[ 2 4 2 ]
1 2 1
,当时我就很纳闷这个模板是怎么出来的,后来我经过多方查找资料,基本得到了如下的解释:高斯模板实际上也就是模拟高斯函数的特征,具有对称性并且数值由中心向四周不断减小,这个模板刚好符合这样的特性,并且非常简单,容易被大家接受,于是就比较经典!但是这样一个简单的矩阵是远远不能满足我们对图像处理的要求的,我们需要按照自己的要求得到更加精确的模板,那么接下来我们就编程实现自己想要的高斯模板。部分关键函数如下:
double** createG(int iSize, double sigma)
{
double **guass;
double sum = 0;
double x2 = 0;
double y2 = 0;
int center = (iSize - 1) / 2;
guass = new double*[iSize];//注意,double*[k]表示一个有10个元素的指针数组
for (int i = 0; i < iSize; ++i)
{
guass[i] = new double[iSize];
}
for (int i = 0; i<iSize; i++)
{//使用x2,y2降低了运算速度,提高了程序的效率