在介绍算法前我们首先放一张效果图来看一看(SURF算法的使用效果),同时这篇文章我们更多的是要讲清楚原理,并不关心具体的数学推导和意义所在,所以文中尽可能省略整个算法中的数学部分,可以作为算法入门的一个简单教程

这里我们感谢浅墨的示例程序,在他的博客中对于SURF算法的使用给了比较详细的说明以及介绍,原文博客

同时也附上程序的源文件(基于VS2013+OpenCV_2.49),源程序下载

在开始正题之前,首先还是要感谢前辈大牛的启发,本文主要参考了如下四篇博客(最后一篇主要是说SIFT和SURF算法的区别),再次拜谢大牛们:

https://www.cnblogs.com/wangguchangqing/p/4853263.html
https://blog.csdn.net/weixin_38404120/article/details/73740612
https://blog.csdn.net/zddblog/article/details/7521424

https://blog.csdn.net/Blateyang/article/details/76512398

       这里我们主要以SIFT算法的原理来进行说明,因为SIFT和SURF的算法比较相似,主要区别在于算法的效率上,具体可以参考上述文献的最后一篇

      好了,接下来我们步入正题,介绍一下特征点匹配的原理:

      在开始之前,我们首先介绍一下SIFT算法的大致步骤,以便读者可以在阅读完一段后参考我们这一段主要是赶了什么,实现了怎样的需求:

问题1:两张照片之所以能匹配得上,是因为其特征点的相似度较高

这个原理其实不难理解,我们在分析两个物体是否匹配的话首先我们要看这两个物体有没有相同的特征,而在看的过程中我们需要换个角度或者换个距离查看以保证我们观测的准确,下面这个图就是一个生动的说明:

     在一定的范围内,无论物体是大还是小,人眼都可以分辨出来。然而计算机要有相同的能力却不是那么的容易,在未知的场景中,计算机视觉并不能提供物体的尺度大小,其中的一种方法是把物体不同尺度下的图像都提供给机器,让机器能够对物体在不同的尺度下有一个统一的认知。在建立统一认知的过程中,要考虑的就是在图像在不同的尺度下都存在的特征点。

引出概念1:尺度空间

   平时生活中,用人眼去看一张照片时,随着观测距离的增加,图像会逐渐变得模糊。那么计算机在“看”一张照片时,会从不同的“尺度”去观测照片,尺度越大,图像越模糊。

   那么这里的“尺度”就是二维高斯函数当中的σ值,一张照片与二维高斯函数卷积后得到很多张不同σ值的高斯图像,这就好比你用人眼从不同距离去观测那张照片。所有不同尺度下的图像,构成单个原始图像的尺度空间。“图像尺度空间表达”就是图像在所有尺度下的描述。

引出概念2:高斯卷积

      这里的高斯卷积更多的是一种获取不同模糊度的工具,因为高斯核是唯一可以产生多尺度空间的核。

     下图为高斯函数在数学坐标系下的图像以及对应的高斯核图像,我们可以看出,经过高斯处理后,中心点的关联性最大,越靠近边缘关联性越小,这样的处理也就产生了“模糊”的效果

不同高斯函数参数下的图片处理效果:

引出概念3:分离的高斯卷积

     在运算过程中,我们使用的高斯核通常是如下图右图所示的方形核,但是这样做会导致运算量大,图像处理速度低,而为了解决这一问题,我们常常采用分离的高斯卷积,具体如左图所示

问题2:为什么要提到高斯模糊与“尺度空间表达”,它们有什么关系呢?

     “尺度空间表达”指的是不同高斯核所平滑后的图片的不同表达,意思就是:原始照片的分辨率,和经过不同高斯核平滑后的照片的分辨率是一样的。但是,对于计算机来说,不同模糊程度,照片“看”上去的样子就不一样了。高斯核越大,图片“看”上去就越模糊。

问题3:图片的模糊与找特征点有关系吗?

      计算机没有主观意识去识别哪里是特征点,它能做的,只是分辨出变化率最快的点。彩色图是三通道的,不好检测突变点。需要将RGB图转换为灰度图,此时灰度图为单通道,灰度值在0~255之间分布。

   无论人眼观测照片的距离有多远,只要能辨认出物体关键的轮廓特征,那就可以大致知道图像所表达的信息。计算机也一样,高斯卷积之后,图像虽然变模糊了。但是整体的像素没有变,依然可以找到灰度值突变的点。

    而这些点,就可以作为候选特征点了,后期再进一步减少点的数量,提高准确率即可。

问题4:除了高斯模糊外,我们还有没有什么方法可以实现不同的尺度空间变换呢?

可以使用图像金字塔

引出概念4:图像金字塔

图像的金字塔模型是指,将原始图像不断降阶采样,得到一系列大小不一的图像,由大到小,从下到上构成的塔状模型。下图就是图像金字塔的示例图片,最左侧是抽样示意图,中间是向下采样(我们称之为高斯金字塔),最左侧是向上采样(我们称之为拉普拉斯金字塔)

好了,有了上文所述的图像金字塔概念以及高斯模糊概念之后我们就可以进行特征匹配中的第一步了

步骤一:使用高斯金字塔完成尺度空间的极值检测

方法1(LOG图像):那么将图像金字塔和高斯模糊结合起来的话,就得到了LOG图像(高斯拉普拉斯变换图像)。其步骤是:先将照片降采样,得到了不同分辨率下的图像金字塔。再对每层图像进行高斯卷积。这样一来,原本的图像金字塔每层只有一张图像,而卷积后,每层又增加了多张不同模糊程度下的照片。

方法2(DOG图像):DOG即高斯差分。构造高斯差分图像的步骤是:在获得LOG图像后,用其相邻的图像进行相减,得到所有图像重新构造的金字塔就是DOG金字塔。

无论采用哪种方法我们的目的都是要获得图像中的极值点,采用的方法是每个像素点与其周围的像素点比较,当其大于或者小于所有相邻点时,即为极值点。

比如说,如下图所示,以黄点为检测点,那么其周围的点,除了同层所包围的8个绿点外,还有上一层的9个点与下一层的9个点。

问题5:DOG运算和LOG运算相比有什么不同?优势在哪里?

DOG的运算量比LOG少很多,可以降低内存占用率,加快图片处理速度。

完成了尺度空间的极值检测后我们就可以进入算法的第二步,关键点的定位

步骤二:关键点的定位

在步骤二中我们主要需要完成两个事情:极值点的精确定位和去除边缘的影响

首先是精确定位:

我们找的的极值点是在高斯差分之后所确定下来的,那么其是属于离散空间上的点,不一定是真正意义上的极值点。

我们需用用到一条曲线来进行拟合。这样就完成了极值点的精确定位。

 

其次是去除边缘影响:

到这一步,得到的极值点是比较精确了,但不够准确。有些极值点不是我们想要的,当中就有一大部分是边缘区域产生的极值点。因为物体的边缘轮廓在灰度图中,存在着灰度值的突变,这样的点在计算中就被“误以为”是特征值。

仔细分析,边缘区域在纵向上灰度值突变很大,但是横向上的变化就很小了。好比你用黑笔在白纸上水平画一条线段。垂直方向看,黑色线与白***域的突变很大。但是水平方向看时,黑色线上某一点的水平临近点仍然是黑点,突变程度非常小。具体可参见Harris角点检测算法。这里附一个写的很好的Blog。

到这一步我们已经找到了图像中的极值点,但是我们需要进行图像匹配的话还需要知道这些极值点的方向,这就进入了我们的第三步

步骤三:方向的确定

经过Harris角点检测算法之后,基本上得到了我们想要的精确特征点了。接下来我们就要求它们的方向。

在DOG 金字塔中,有很多层高斯模糊后的图像。在此,我们对其中一张图像的处理进行说明。当我们精确定位关键点后,需要找到该特征点对应的尺度值σ,根据这一尺度值,将对应的高斯图像的关键点进行有限差分,以3×1.5σ为半径的区域内图像梯度的幅角和幅值,然后利用直方图统计领域内像素对应的梯度和幅值:梯度方向角为横轴刻度,取45度为一个单位,那么横轴就有8个刻度;纵轴是对应梯度的幅值累加值。取幅值最高的方向为主方向。有的时候,会出现第二峰值,因为有较多的关键点是多方向的。如果直接把它忽略掉不加以考虑的话,最后对匹配精度的影响还是蛮大的。所以,为了匹配的稳定性,我们将超过峰值能量的百分之80的方向,称为辅方向。

具体我们可以用这样一张图来表示,左图是我们找到的各个像素的方向,右图是我们使用直方图统计出各个方向的像素所占的比例

完成步骤三之后我们可以得到这样一组对比图:

最后就是完成关键点的描述

步骤四:关键点的描述

这里如果具体细分一般可以分为7步:确定描述子所需要的图像区域、将坐标轴转换为关键点的方向、将子区域内的梯度值分配到八个方向上,计算其权重值、差值计算每个种子点八个方向的梯度、归一化处理、描述子向量门限、按特征点的尺度对特征描述向量进行排序。

因为这篇文章想大家尽可能的了解整个算法的流程,撇开复杂的数学内容,所以这里只简单的介绍如下几点:

1、确定描述子所需要的图像区域

特征描述子与特征点所在的尺度有关,因此,对梯度的求取应在特征点对应的高斯图像上进行。将关键点附近的邻域划分为d*d(Lowe建议d=4)个子区域,每个子区域做为一个种子点,每个种子点有8个方向。如下图所示

2、将坐标轴转换为关键点的方向

这里不做过多的解释说明,放两张图大家就明白了,注意:第二幅图的关键点周边像素的方向,有助于读者理解

3、将子区域内的梯度值分配到八个方向上,计算其权重值

在每子区域内计算8个方向的梯度方向直方图,绘制每个梯度方向的累加值,形成一个种子点。与求特征点主方向时有所不同,此时,每个子区域的梯度方向直方图将0°~360°划分为8个方向范围,每个范围为45°,这样,每个种子点共有8个方向的梯度强度信息。由于存在4X4(Bp X Bp)个子区域,所以,共有4X4X8=128个数据,最终形成128维的SIFT特征矢量。同样,对于特征矢量需要进行高斯加权处理,加权采用方差为mσBp/2的标准高斯函数,其中距离为各点相对于特征点的距离。使用高斯权重的是为了防止位置微小的变化给特征向量带来很大的改变,并且给远离特征点的点赋予较小的权重,以防止错误的匹配。

 在最后,对特征向量进行归一化等处理,去除光照变化的影响,这里更多的是数学方法,这里不再过多的介绍。

到这里SIFI及SURF算法的特征点匹配就基本完成了。