源码下载地址:https://download.csdn.net/download/u014509577/11011793
一、算法流程
1、生成高斯金字塔,并由此生成差分高斯金字塔(DoG),该过程完成尺度空间的构建,以便后续的空间极值点检测。
2、稳定关键点的精确定位、去除不稳定特征点
3、稳定关键点信息分配
4、关键点匹配
二、算法中每一步的算法原理以及源码解释
(一)构建尺度空间
(1)尺度空间及尺度空间的连续性
尺度空间:通过对原始图像进行尺度变换,获得图像多尺度下的尺度空间表示序列,以便对尺度空间的主轮廓提取,获得特征向量,实现边缘、角点检测和不同分辨率上的特征提取。
高斯核是唯一产生多尺度空间的核,使用高斯核对图像模糊不会引入噪声,因此用高斯核构建图像尺度。
一个图像的尺度空间定义为一个变换尺度的高斯函数
和原图像
的卷积,即
其中,,m,n表示高斯模板的维度(
确定)。(x, y)代表图像的像素位置。
是尺度空间因子,值越小表示图像被平滑的越少,相应的尺度也就越小。大尺度对应于图像的概貌特征,小尺度对应于图像的细节特征。
尺度空间,O代表第几个八度(组),S代表八度中的第几层。
尺度空间是自然存在的,不是人为创造的!!高斯卷积只是表现尺度空间的一种形式。
为了让尺度体现其连续性,在简单下采样的基础上添加了多尺度的高斯滤波。一幅图像可以产生几组(Octave)图像,一组图像又包括几层(Interval)图像,并且组数和金字塔的层数相等。
通过在每个八度中多构造三幅高斯图像,达到了尺度空间连续的效果,这一效果带来的直接的好处是在尺度空间的极值点确定过程中,我们不会漏掉任何一个尺度上的极值点,而是能够综合考虑量化的尺度因子所确定的每一个尺度!
(2)构建高斯金字塔
图像金字塔模型是指,将原始图像不断降阶采样,得到一系列大小不一的图像,由大到小,自底向上构成的塔状模型。原始图像为金字塔的第一层,每次降采样得到的新图像为金字塔的一层(每层一张图像)。
高斯金字塔共包含O组图像,每组图像有 S+3S+3 层,,其中M,N分别为原始图像的行数和列数。
构建组的过程:
①扩大图像
②在该尺度上进行高斯模糊,构成一个八度(简单地说八度就是在特定尺寸(长宽)下,经不同高斯核模糊的图像的集合。八度的集合是高斯金字塔。)
③在该八度下最模糊的一幅画降采样,并成为下一个八度的初始图像。
(3)构建差分高斯金字塔
1、步骤:①对同八度的两幅相邻的图像做差得到插值图像
②所有八度的插值图像集合构成差分高斯金字塔
2、意义:差分高斯函数是尺度规范化的高斯拉普拉斯函数的近似,而高斯拉普拉斯函数的极大值和极小值点是一种非常稳定的特征点(与梯度特征、Hessian特征和Harris角点相比)有了这些基础,就可以放开手脚从差分高斯金字塔中找点了!
(二)稳定关键点的精确定位
(1)关键点
关键点是一些十分突出的点,它不会因光照条件的改变而消失,如焦点、边缘点、暗区域的亮点以及亮区域的暗点。关键点是在不同的尺度空间的图像下检测出的具有方向信息的局部极值点,特征点的三个特征是:尺度、方向、大小。
匹配工作就是:提取两幅图片各自的稳定点,然后建立这些点之间的匹配关系。
(2)阈值检测
由于不能保证图片就是完全没有噪声的,所以在推选之前我们要排除一些对比度比较低的点,这些点很不稳定,容易受到干扰,本着宁缺毋滥的原则,先把不稳定因子排除。这个阈值一般是自己设定的,在matlab中设定它为:0.5*T/S,这里的T lowe 定义它为0.04,s是该点所在的层。
(3)极值检测
在sift算法里面极值点的检测方法是对图像中的每一个点进行遍历,判断每一个点是否是极值,判断的标准是,把这个点与相邻的层,上下层9+9=18个点和同一层中8个点,共18+8=26个点进行比较,看这个点是否是最大值,还是最小值,若是,则保留下来进入下一层计算。
(4)极值点精确定位——拟合+去除边缘状的点(去除边缘相应)
计算机中存储的图像数据是离散的,而我们之前找到的极值点也就是离散空间中的极值点,但是离散空间中的极值点并不是真实的连续空间中的极值点。所以在这一轮的选举中,我们的目标就是找到精确的极值点(成仙之前当然要经过考验)其实这里的精确点的位置,是一个亚像素级别的概念,比如一个数的个位十位百位都确定了,要更加精细的去找这个数的小数点后的那个数据,所以首先用插值来计算。
需要对DoG空间进行拟合处理,以找到极值点的精确位置和尺度。通过三元二次函数拟合来精确确定关键点的位置和尺度。高数中提过,函数f(x)在x0处可以进行泰勒展开。于是我们也在这个检测到的极值点处处,对它进行泰勒级数展开(这里只展开到二阶项,高次项砍掉),以此来拟合这个三维二次函数。于是得到
把上面的式子写成矢量的形式:。于是就拟合出来了该点附近的函数了,表示拟合之后连续空间下面的插值点坐标,设则表示:相对于插值中心的偏移量,可以用偏移量表示:
对式子求导,得,让导数等于0,就可以得到极值点下的相对于插值中心的偏移量:
,把该式代入
可以得到该极值点下的极值为
。Ok,其实到这里,已经把精确的极值点找到了!!
一个定义不好的高斯差分算子的极值在横跨边缘的地方有较大的主曲率,而在垂直边缘的方向有较小的主曲率。DOG 算子会产生较强的边缘响应,需要剔除不稳定的边缘响应点。
(三)稳定关键点信息分配
要想进行特征点匹配需要知道特征点的描述向量。之前检测中能解决尺度变化问题,接下来想通过描述来解决旋转问题。旋转的解决方法是寻找一个主方向,这样其他方向可以根据离这个主方向的角度来确定。
(1)寻找主方向。
在特征点附近的一个邻域(圆形区域)内计算每个点的梯度幅值和角度,根据角度作为横坐标计算直方图,直方图纵坐标为幅值的叠加,选取纵坐标最大的方向作为特征点的主方向。
(2)选取主方向后需要得到描述子,为了消除旋转影响,首先将特征点附近需要考虑的邻域根据主方向进行旋转:
然后将这个邻域分为四个子区域(也可以是16个),每个子区域包含4*4区域,每个像素都有梯度方向,利用直方图统计每个子区域在8个方向的梯度值大小的统计值:
这样每个子区域就有8维的向量,连起来就是32维向量,如果是16个子区域就是128维向量,也就是SIFT描述子。 利用关键点邻域像素的梯度方向分布特性为每个关键点指定方参数,使算子具备旋转不变性。
为(x,y)处梯度的模值和方向公式。其中L所用的尺度为每个关键点各自所在的尺度。至此,图像的关键点已经检测完毕,每个关键点有三个信息:位置,所处尺度、方向,由此可以确定一个SIFT特征区域。
梯度直方图的范围是0~360度,其中每10度一个柱,总共36个柱。随着距中心点越远的领域其对直方图的贡献也响应减小.Lowe论文中还提到要使用高斯函数对直方图进行平滑,减少突变的影响。
在实际计算时,我们在以关键点为中心的邻域窗口内采样,并用直方图统计邻域像素的梯度方向。梯度直方图的范围是0~360度,其中每45度一个柱,总共8个柱, 或者每10度一个柱,总共36个柱。Lowe论文中还提到要使用高斯函数对直方图进行平滑,减少突变的影响。直方图的峰值则代表了该关键点处邻域梯度的主方向,即作为该关键点的方向。
直方图中的峰值就是主方向,其他的达到最大值80%的方向可作为辅助方向
由梯度方向直方图确定主梯度方向
该步中将建立所有scale中特征点的描述子(128维)
(四)关键点匹配
关键点的匹配主要是通过将des1中的每一个关键点信息与des2中的每一个关键点求最近邻距离,并通过阈值的限定来进行的。