SIFT的来龙去脉-&- 个人代码实现(opencv3;C++)

/*
*copyright : 刘振.南京大学
*time : 2018.07.20
*/

SIFT(Scale Invariant Feature Transform)是一种提取图像中稳定特征点的算法,具有。它在1999年由David.G.Lowe提出,并于2004年改进,想精准理解SIFT思想的童鞋建议阅读一下论文 ,Lowe论文地址:http://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf 。

内容简介:
1. 角点检测
2. 尺度、图像金字塔
3. LOG、DOG算子
4. sift的流程概述
5. sift细节点
6. 代码实现

一、角点检测

这个暂时不多说,参考这篇博客。https://blog.csdn.net/linolzhang/article/details/54342610

二、尺度空间

{ 尺度,一般表示物体的尺寸与尺码,也用来表示处事或看待事物的标准。
} ———以上摘自百度百科。

尺度是特征的尺度,离开尺度谈特征都是耍流氓。拿山水图举个例,“此处有座山”是在一个宏大的尺度上提取,而“此处有个人” 尺度就相对很小,“此处有个蚂蚁”就是更小的尺度了。 提取”山“这个大尺度特征,要求我们忽略小尺度细节,这里到底有没有人、有没有蚂蚁这些细节都不影响结果。因此提取图像特征、或者确定特征点都是在一定尺度上进行的,可将尺度看作特征的一个参数。
当然上一段是人类大脑思考的过程,具体图像处理中,我们的特征提取算子都是基于固定像素级别、且对所有图所有位置所有像素权值共享的(事实上sift中 特征点检测算子的大小固定、特征描述算子的大小有所浮动)。也就是说对所有图算子提取的尺度都几乎相同,这可如何是好?
不打紧,既然特征大小固定、那就改变图像,两种方法。1)滤波,一般采用高斯滤波。滤波会消除图像的细节、增大算子的感知野。相当于变相增加了算子提取的特征的尺度。2)缩放图像。算子f 提取的1/2大小图像特征,相当于原图中两倍尺度的特征。 采用高斯模糊和图像缩放组合生成的一系列图,使得同样的算子能提取原图的不同尺度特征,我们将这些尺度称为 对应的图像的尺度。

必须一提的是,在sift中图像的尺度统一由高斯滤波的程度σ来度量,图像1/2下采样并改变其尺度,原因是因为:1)sift中特征描述算子的”宽度大小”并不固定,而是与图像的大小、图像的尺度成线性关系。假设图像a特征描述算子宽度为L,下采样图像b尺度不变,算子宽度为L*1/2*1=L/2。 L/2在b中提取的特征的尺度 和L在a中提取的特征的尺度是一样的。
2)经过足够程度的高斯模糊,局部细节已经完全抹去,下采样不会损失任何细节。

至此,我们将特征的尺度变成了图像的尺度,并为SIFT高斯金字塔的定义做好了铺垫。

二、高斯金字塔与DOG金字塔

对一张图像:1)先进行数次高斯卷积使得模糊程度不断增加 ,过程中得到一组/Octave的图像。2)对该组倒数第三张图片 进行1/2下采样使得图像缩小。对下采样的图像重复上述操作。
这个过程中生成的所有Octave的图像组合在一起就是高斯金字塔。
一般来说,高斯金字塔有4个Octave,一个Octave有5或6层,本文中我们设定为5层即5张图 。
对于高斯金字塔的每个Octave,相邻的两幅图像依次相减,即得到DOG高斯差分金字塔–Difference Of Gaussian

注意,上述过程中,每次卷积不是基于原图卷积,而是基于上一副图片卷积,这么做是为了建塔的方便。不过根据高斯卷积的可拆分性,得到的图像等价于对原图做一个尺度的卷积
高斯卷积的可拆分性: 对图像img做Gauss(a)的卷积再做Gauss(b)的卷积,等价于做Gauss(√(a^2+b^2) )的卷积

SIFT的来龙去脉-&- 个人代码实现(opencv3;C++)_第1张图片

sift中尺度由高斯滤波程度σ来度量。根据Lowe的论文,每一层的尺度公式为:

x显示结果

其中O为所在Octave(从0开始),s是图像所在层数(从0开始),S=Octave的总层数-3 ,本文中S=2。S的具体意义是最终在S个层上找DOG极值点。
金字塔尺度分布具体如下图所示:

令k^S=2,k=2^(1/S) 
可以看到,因为是1/2下采样的关系,高斯金字塔每组第一张和上组倒数第三张图像 尺度是相同的。
高斯金子塔的尺度顺序   :     OCTAVE1:    σ  ,  kσ , k^2σ, k^3σ, k^5σ
                            OCTAVE2:   k^2σ, k^3σ, k^4σ, k^5σ, k^6σ
                            OCTAVE3:   k^3σ, k^4σ, k^5σ, k^6σ, k^7σ

DOG金字塔的尺度顺序  :      OCTAVE1:    σ  ,  kσ , k^2σ, k^3σ,
                            OCTAVE2:   k^2σ, k^3σ, k^4σ, k^5σ
                            OCTAVE3:   k^3σ, k^4σ, k^5σ, k^6σ

DOG空间极值点所在尺度:      OCTAVE1:          kσ , k^2σ
                            OCTAVE2:         k^3σ, k^4σ
                            OCTAVE3:         k^4σ, k^5σ

下面讨论一下建塔过程中,每一步所采用的高斯卷积系数的取值。
高斯金字塔Octave1内的图像名字依次为 a1,a2,a3,a4,a5。
高斯金字塔Octave2内的图像名字依次为 b1,b2,b3,b4,b5。
a1-a2,a2-a3,a3-a4,a4-a5的卷积系数依次为: σ√(k^2−1) ,σk√(k^2−1) ,σk^2√(k^2−1) ,σk^3√(k^2−1)
作用于图像b1-b2,b2-b3,b3-b4,b4-b5的卷积系数和上面一样。但根据高斯卷积拆分公式,这里好像不对啊?不要紧,下面给出解释:

问题的关键:σ卷积作用于1/2图像上,相当于2σ卷积作用于原图上。这个大家自行推公式理解。
基于此,对图像b1-b2做 σ√(k^2−1)的卷积,b1尺度为k^2σ,k^=2。 新得图像的尺度为:σ√(4*k^2-4+k^4) = σ2√2 =σ k^3


构造金字塔完毕,下面说一说Sift如何检测特征点。

首先介绍一下LOG算子和DOG算子。
Sobel、Canny等1阶边缘检测算子对噪声敏感、且极大值求解复杂,而Laplace算子是二阶边缘检测算子,它的零点就是边缘点。对Laplace算子引入高斯抑制噪声就成了高斯-拉普拉斯算子(LOG算子)。
LOG算子其实就是:先对图像进行高斯模糊,然后再求二阶导数,二阶导数等于0处对应的像素就是图像的边缘。LOG算子具体公式如下:

SIFT的来龙去脉-&- 个人代码实现(opencv3;C++)_第2张图片

这两个等号的推导,可以看这里 http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html 。

上面说到LOG算子的零点代表了边缘点,此外LOG极值点一般用于检测Blob斑点(具体参考超链接)。Log(σ) 对 r= σ√ 2 的斑点响应极值最大,因此σ 可作为Log(σ)检测的特征点尺度。
如果我们在不同尺度上 进行Log算子的计算,并且真实存在一个直径大小是2√2σ的斑点,那这个斑点在多个尺度上都会是(x,y)平面内的极值点,并且极值响应在尺度σ图像的(x1,y1)点达到最大。
总结来说,(x1,y1,σ)就是三维空间内LOG算子的极值点,这个三维空间称为尺度空间,该极值点体现的是斑点特征,特征尺度为2√2σ。因此,LOG算子尺度空间作为特征点检测是合理的。

DOG是对LOG的近似:
DoG算子是高斯函数的差分,具体到图像中,就是将图像在不同参数下的高斯滤波结果相减,得到差分图。

SIFT的来龙去脉-&- 个人代码实现(opencv3;C++)_第3张图片
( k-1)σ^2是个常数,所以LOG可用DOG近似

至此,我们知道sift是通过LOG算子的近似DOG算子,只需要在早已得到的DOG金字塔中找极值点,就能得到斑点特征点。
该部分参考资料:
斑点检测 ; LOG与DOG;

图像金字塔还有 *Laplacian 金字塔*,有兴趣的可以了解一下,主要用于图像融合。

四、sift流程总结

前面我们讲述了尺度空间、高斯金字塔的构造方法、LOG/DOG算子求特征极值点等概念。 下面我完整系统地 把sift算法的流程写出来。
src: 原图
1. 图像预处理
src 线性插值上采样 ——> doublesized_img
doublesized_img 初始滤波降噪 ——> init_img
2. 金字塔构建
根据src尺寸计算金字塔组数 ——> num_octaves= Min{ 4, log2 [min(cols,rows)] - 2 }
以init_img为底层图像,构建高斯金字塔、DOG金字塔 ——> GaussPyr & DogPyr
金字塔构造方法前面已有叙述
3. 特征点检测
DOG金字塔的每个Octave有S+2层,[2,S+1]层中寻找周围空间极值点p ——> p
对极值点p进行筛选 ——> p :

1)pass掉 DOG值为0的极值点以及小于一定阈值的 不显著点。【DOG图中低灰度区域的极值点。原图中 这种点附近是平坦区域,是为不具有显著性特征的极值点】
2) pass掉 边缘的不稳定响应点。【当上面的非显著极值点存在于边缘处时,由于边缘效应,DOG函数响应值很大,响应阈值筛选不掉。这种边缘点,在垂直边缘的单方向具有极大响应,在边缘方向响应较小,我们采用Hessian矩阵根据这一比值 进行筛选。】 SIFT的来龙去脉-&- 个人代码实现(opencv3;C++)_第4张图片

4. 特征点主方向检测

5. 特征描述子生成

五、其他细节说明

sift提取特征描述符,不是恢复到原图上去提取的。

六、代码实现

代码太长,贴在下一篇文章:

参考链接:
角点检测算法及其描述子评估介绍

你可能感兴趣的:(传统视觉算法)