尺度不变特征变换(Scale-invariant feature transform, 简称SIFT)是图像局部特征提取的现代方法——基于区域/图像块的分析。在上篇笔记里咱们使用的图像之间对应点的匹配方法,不适用于不一样尺度的图像。有许多应用场景须要对不一样尺度(即分辨率、缩放、旋转角度、亮度等均可能存在不一样)的图像进行特征识别和匹配,这就须要一种特征提取方法,经过这种方法提取出来的特征描述,能够不受尺度的影响,SIFT算法就是这种方法的实现。SHIT算法有以下的特色:html
SIFT特征是图像的局部特征,其对旋转、尺度缩放、亮度变化保持不变性,对视角变化、仿射变换、噪声也保持必定程度的稳定性;算法
独特性(Distinctiveness)好,信息量丰富,适用于在海量特征数据库中进行快速、准确的匹配;数据库
多量性,即便少数的几个物体也能够产生大量的SIFT特征向量;segmentfault
高速性,经优化的SIFT匹配算法甚至能够达到实时的要求;dom
可扩展性,能够很方便的与其余形式的特征向量进行联合。学习
SIFT算法的应用很是普遍,包括物体识别、机器人地图感知与导航、全景拼接、3D建模、手势识别、影像追踪和动做比对等,原书后面章节的算法也会屡次用到它。SIFT算法的过程较复杂,本文只是粗略介绍其关键步骤,以便引出SURF——基于SIFT的改进算法。优化
SIFT的算法仍是比较复杂的,但也让人大开眼界,权威的和详细的介绍应该直接看英文论文,个人笔记记录的也只是其算法的要点,目的是为了理解算法的思想,为了对涉及到的数学有一个大概的了解。url
降采样或隔点采样,将一幅图像降为一半大小的图像,连续使用几回降采样,每次获得的图像大小都降为前一张大小的一半,最后获得一组降采样的图像。降采样的目的是为了综合全部不一样清晰度的图像进行关键点提取,这种关键点携带了不一样清晰度的信息,对缩放具备不变性。spa
在以前的笔记介绍过,原图像与高斯核(2维高斯算子)做卷积(高斯滤波)的结果即为模糊图像,实为平滑效果,高斯滤波属于低通滤波,它能够过滤掉必定的噪声。若是把两张使用不一样sigma的模糊图像记为Bσ和Bkσ, DOG操做即为两张模糊图像之差,记:code
Gσ = Bkσ - Bσ
Gσ为DOG图像,它包含的特征是目标的轮廓。
SIFT先对降采样后的每张图像使用不一样的sigma进行高斯模糊,结果是每一个降采样图像对应一组模糊图像:
而后对每组模糊图像的相邻图像做DOG,结果是每一个降采样图像对应一组DOG图像,如图:
把每一组图像堆叠起来,位于塔底的是第一组(first octave),往上是第二组,第三组...每一组的图像大小为前一组的一半,看起来像金字塔:
如图Gaussian列(左边)称为高斯金字塔,DOG列(右边)称为DOG金字塔。
SIFT分别对每组DOG图像提取关键点,以第一组为例,将第一组DOG图像上下对齐叠加在一块儿,造成DOG空间,DOG空间有两个域:图像域和尺度域。图像域指图像自己的二维平面像素,尺度域指垂直于图像域的第三维度构成的像素。SIFT使用局部极值检测来定位找到关键点,以下图所示:
X位置所在像素即为当前要检测的点,以X为中心的周围像素(包括图像域和尺度域)造成了一个局部空间(像3X3魔方),若是X为此局部空间的极值(最大值或最小值),那么X即为关键点之一。
SIFT的提取的特征(关键点)须要对尺度保持不变性,因此这里讲的关键点,比以前笔记介绍的角点和兴趣点稍为复杂些,SIFT关键点须要携带尺度信息,包括缩放、方向等信息,主要由它周围的像素来贡献。若是用一个向量来存储这些信息,此向量称为关键点描述(key point descriptor,简称KPD),KPD生成步骤:
在关键点所在图像上,划出以关键点为中心的16x16的矩形图像:
将16x16矩形图像划分为16小格,每小格为4x4,并计算每一个像素的梯度和幅度(即像素值变化的方向及大小):
对每一个小格进行统计,统计8个方向的幅度,造成幅度直方图:
将16小格的幅度直方图链接起来,用向量表示,即为KPD,共有128(8x16)维:
使用向量表示为: R = (r1, r2, ..., r128)
为了让关键点对方向具备不变性,在选取16x16矩形区域的时候,将矩形的方向旋转到与关键点主方向一致。SIFT定义关键点主方向为:以关键点为中心的周围像素所贡献的主方向。
可采用梯度直方图统计法,统计以关键点为原点,必定区域内的图像像素点对关键点方向生成所做的贡献,贡献最大的那个方向即为关键点主方向。
关键点的匹配问题,已经转为KPD的匹配问题,两KPD的类似程度,使用欧式距离进行计算。设有两个KPD分别为R = (r1, r2, ..., r128)和S = (s1, s2, ..., s128),R与S的欧式距离计算公式为:
d = sqrt((r1 - s1)^2 + (r2 - s2)^2 + ... + (r128 - s128)^2)
因此,要找出两张不一样尺度图像间的对应点(具备对应关系的关键点),分下面几步:
分别检测两张图像的关键点,并计算出每一个关键点的KPD,分别获得两个KPD集合SET1和SET2
为SET1中每一个KPD,从SET2找最佳匹配(即欧式距离最小的为最佳匹配),而后反过来,为SET2每一个KPD,从SET1中找最佳匹配,只有彼此认为是最佳匹配的那些KPD对才是对应点
为提升匹配准确率,能够设定一个阈值,欧式距离大于此阈值的那些匹配对,将不考虑。
为提升算法效率,可使用kd树和RANSAC( Random Sample Consensus, 随机抽样一致)方法。
SURF(Speeded Up Robust Features)是对SIFT的一种改进,主要特色是快速。SURF与SIFT主要有如下几点不一样处理:
SIFT在构造DOG金字塔以及求DOG局部空间极值比较耗时,SURF的改进是使用Hessian矩阵变换图像,极值的检测只需计算Hessian矩阵行列式,做为进一步优化,使用一个简单的方程能够求出Hessian行列式近似值,使用盒状模糊滤波(box blur)求高斯模糊近似值。
SURF不使用降采样,经过保持图像大小不变,但改变盒状滤波器的大小来构建尺度金字塔。
在计算关键点主方向以及关键点周边像素方向的方法上,SURF不使用直方图统计,而是使用哈尔(haar)小波转换。
SIFT的KPD达到128维,致使KPD的比较耗时,SURF使用哈尔(haar)小波转换获得的方向,让SURF的KPD降到64维,减小了一半,提升了匹配速度。
SIFT算法是有专利的,正规使用是要交专利费的,因此有人提出了一种可做为SIFT替代的算法——ORB,ORB没有专利问题,考虑到本文篇幅过长,图片过多,此算法的介绍和示例将在下一笔记介绍。
可能也是由于专利问题,skimage库有ORB算法,但没有SIFT和SURF。虽然OpenCV都包含了上述算法,但OpenCV目前不在个人学习计划中。
原书示例使用了一个第三方实现的SIFT算法库,我认为在实际使用可能价值不高,另外,书上也没有介绍ORB(也许是由于在写此书时,ORB尚未出来),但我认为ORB更有研究的必要,由于无专利问题,它将会是一个被普遍使用的算法,因此本文没有给出SIFT代码示例,但计划在下篇笔记介绍ORB和给出示例。
你还能够看我其它的笔记。