我记得在刚毕业那会一次去面试一个图像算法工程师岗位,面试官问了一个关于高斯滤波的问题。这个再熟悉不过,可是当时我的脑子里只有关于这个滤波的效果如何以及如何使用opencv调用,它的公式却怎么也写不完整,更不用说这个公式中的期望和方差这两个参数的作用了。
经过这次面试我回去好好恶补了一下关于高斯函数的公式,回去对照着函数图,深刻的理解了这个公式的含义,并且对其中的期望和方差这些参数也做了研究,明白了它们是如何对这个函数进行影响的。很快我又收到了下一个公司的面试机会。同样也是和图像算法方面相关的,这次我很轻松的回答出了出了高斯函数并且对其参数做了一定的分析,就当我自信满满的准备拿下这个offer的时候,面试官又问了那高斯滤波原理是如何进行卷积的?当时心想完蛋了,这个知识点又忘看了。经过这样几次之后我总结出了一个问题,每次我在学习的时候经常是很难全面的学习和把握知识,那么到底如何克服这个问题呢?经过不断的总结归纳,我总结了一套知识点的学习思路和方法,对于知识点尤其是opencv采用算法原理+API实现+源码实现的方式就可以全方面的了解每个知识点,做到深入到毛发的程度。我们还是以这个高斯滤波为例。先来看下算法原理,即高斯函数的公式。
这是一个标准的高斯函数公式,以及该公式所对应的函数图。从图中可以看出,根据输入的取值不同,输出是一个满足正态分布的曲线,同时根据当前期望和方差的不同,输出曲线会有一定程度的差异,总体来说期望影响的是对称轴,方差影响的是幅度。而二维的高斯函数最终会形成一个模版矩阵。
算法原理我们搞清楚了,那么API如何调用呢?opencv中高斯滤波的API非常的简单:void GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0, int borderType=BORDER_DEFAULT )
src和dst当然分别是输入图像和输出图像。Ksize为高斯滤波器模板大小,sigmaX和sigmaY分别为高斯滤波在横线和竖向的滤波系数(有点晦涩,等下解释)。borderType为边缘点插值类型。ok到这一步我们的API也已经掌握了,下面就是源码实现。源码实现的关键是实现图片卷积。比如我们上面的3×3的图片模版,用一个3×3的图片框和当前模版对应元素相乘,将最终求的的9个乘法结果相加,最终得到一个值。用这个值取代3×3图片框中的中心像素,最终得到的结果就是这个3×3中心像素经过滤波之后的值。是不是很好理解呢? 其实我们本这这个思路,通过算法原理+API+源码思想基本上可以透彻的掌握每一个我们想掌握的内容。