一. SURF基本原理
SURF是SIFT的加速版,它善于处理具有模糊和旋转的图像,但是不善于处理视角变化和光照变化。在SIFT中使用
DoG对LoG进行近似,而在SURF中使用盒子滤波器对LoG进行近似,这样就可以使用积分图像了(计算图像中某个
窗口内所有像素和时,计算量的大小与窗口大小无关)。总之,SURF最大的特点在于采用了Haar特征以及积分图像
的概念,大大加快了程序的运行效率。
二. 构建Hessian矩阵
SIFT算子构建一幅图像金字塔,在每一层进行高斯滤波并求取图像差(DoG)进行特征点的提取,而SURF算子用
Hessian矩阵进行特征点的提取。Hessian矩阵的定义,如下所示:
Hessian矩阵的判别式,如下所示:
Hessian矩阵描述函数的局部曲率。假设f(x,y)在M点处的Hessian矩阵为H(M),那么(1)H(M)是正定矩阵,M处是一
个局部的极小值。(2)H(M)是负定矩阵,M处是一个局部的极大值。(3)H(M)是不定矩阵,M处不是极值。
由于特征点需要具备尺度无关性,所以在构造Hessian矩阵前需要进行高斯滤波,如下所示:
其中,是尺度可变高斯函数,
是高斯二阶微分
在点x处与图像I的卷积,
和
含义类似。通过
可以为图像中每个像素计算出其H行列式的值,并用这个值来判别特征点。
将模板与图像产生的卷积转换为盒子滤波运算,需要对高斯二阶微分模板进行简化,使得简化后的模板只是几个矩形
区域组成,矩形区域内填充同一值。在简化模板中白色区域的值为正数,黑色区域的值为负数,灰度区域的值为0,
如下所示:
假设用的高斯二阶微分滤波器,模板尺寸大小为
,那么Hessian矩阵行列式简化如下所示:
其中,是盒子模板与图像的卷积,近似代替
。
表示Frobenius范数。
三. 构建尺度空间
SURF算子不需要直接建立图像金字塔,而是采用不断增大盒子滤波模板尺寸的间接方法。通过不同尺寸盒子滤波模
板与积分图像求取Hessian矩阵行列式的响应图像,然后在响应图像上采用3D非最大值抑制,求取各种不同尺度的特
征点。两种不同尺度的金字塔,如下所示:
所以滤波过程并不会随着滤波模板尺寸的增加而使计算工作量增加。滤波器响应长度l,滤波器尺寸L,组索引o,层索
引s,尺度之间的关系,如下所示:
其中,组索引o,层索引s的值均从0开始。第一组至第三组的滤波器尺寸变化,如下所示:
因为随着尺度的增大,被检测到的特征点数量迅速减少,所以一般进行3-4组即可。为了减少计算量,提高计算的速
度,可以考虑在滤波时将采样间隔设为2。
四. 精确定位特征点
为了在图像不同尺寸中定位特征点,使用3×3×3邻域非最大值抑制,即每个像素点与其三维邻域中的26个点进行大小
比较。局部极大值精确定位采用3维线性插值法得到亚像素级的特征点,同时也去掉小于一定阈值的点。
五. 特征点主方向确定
为了保证特征矢量具有旋转不变性,需要对每一个特征点分配一个主方向。需要以特征点为中心,以半径为(
为
特征点的尺度)邻域内的点在x、y方向的Haar小波(Haar小波边长取)响应。使用
的高斯加权函数对Harr小波的
响应值进行高斯加权,加权后的值分别表示在水平和垂直方向上的方向分量。Harr特征值反应了图像灰度变化的情
况,那么这个主方向就是描述那些灰度变化特别剧烈的区域方向。接着以特征点为中心,张角为π/3的扇形滑动窗
口,步长为0.2弧度左右,旋转这个滑动窗口,计算窗口内的Harr小波响应值dx、dy的累加,如下所示:
主方向为最大的Harr响应累加值所对应的方向,也就是最长矢量所对应的方向,如下所示:
求取主方向时扇形滑动窗口围绕特征点转动,统计Haar小波响应值,并计算方向角示意图,如下所示:
六. 特征点描述子生成
以特征点为中心,沿主方向将的图像划分为4X4个子块,每个子块用尺寸
的Harr模板进行响应值计算,然
后对响应值进行统计、
、
、
形成特征向量。如下所示:
左边为旋转后的图像,右边为旋转前的图像,为利用积分图像进行Haar小波响应计算,并不直接旋转Haar小波模板求
得其响应值,而是在积分图像上先使用水平和垂直的Haar模板求得响应值dx和dy,然后旋转dx和dy与主方向保持一
致。如下所示:
为了求得旋转后Haar小波响应值,首先要得到旋转前图像的位置。根据点旋转方程,旋转前后图像的位置关系,如下
所示:
利用积分图像与水平、垂直Harr小波,求得水平与垂直两个方向的响应值dx和dy并高斯加权处理。根据主方向的角
度,对dx和dy进行旋转变换,从而得到旋转后的dx'和dy'。如下所示:
可以将SURF特征描述子扩展到128维向量表示,具体方法是在求和
时区分
和
的情况,同样在求
和
时区分
和
的情况。为了实现快速匹配,SURF在特征向量中增加了一个新的变量,即特征点的
拉普拉斯响应正负号(即Hessian矩阵迹的正负号)。只有当两个具有相同正负号的特征点才有可能匹配,对于不同
正负号的特征点就不再进行相似性计算。
七. OpenCV中的SURF算子
- import cv2
- import matplotlib.pyplot as plt
- img = cv2.imread('fly.png',0)
- # here set Hessian Threshold to 400
- surf = cv2.SURF(400)
- # Find keypoints and descriptors directly
- kp, des = surf.detectAndCompute(img,None)
- #print len(kp) #699
- # check present Hessian threshold
- # print surf.hessianThreshold #400.0
- # here set it to some 50000
- surf.hessianThreshold = 50000
- # again compute keypoints and check its number.
- kp, des = surf.detectAndCompute(img,None)
- #print len(kp) #47
- img2 = cv2.drawKeypoints(img,kp,None,(255,0,0),4)
- plt.imshow(img2)
- plt.show()
- # check upright flag, if it False, set it to True
- #print surf.upright #False
- surf.upright = True
- # recompute the feature points and draw it
- kp = surf.detect(img,None)
- img2 = cv2.drawKeypoints(img,kp,None,(255,0,0),4)
- plt.imshow(img2)
- plt.show()
- # find size of descriptor
- print surf.descriptorSize() #64
- # that means flag, "extended" is False.
- print surf.extended #False
- # so we make it to True to get 128-dim descriptors.
- surf.extended = True
- kp, des = surf.detectAndCompute(img,None)
- #print print surf.descriptorSize() #128
- #print print des.shape #(47, 128)
cv2.SURF函数原型cv2.SURF([hessianThreshold[, nOctaves[, nOctaveLayers[, extended[, upright]]]]]) →
<SURF object>,如下所示:
(1)hessianThreshold:Threshold for hessian keypoint detector used in SURF.
(2)nOctaves:Number of pyramid octaves the keypoint detector will use.
(3)nOctaveLayers:Number of octave layers within each octave.
(4)extended:Extended descriptor flag (true use 128-element descriptors; false use 64-element descriptors).
(5)upright:Up-right or rotated features flag (true don't compute orientation; false compute orientation).
参考文献:
[1] SURF算法与源码分析:http://www.cnblogs.com/ronny/p/4045979.html
[2] 特征点检测学习(SURF算法):http://www.cnblogs.com/tornadomeet/archive/2012/08/17/2644903.html
[3] SURF算法解析:http://blog.csdn.net/cxp2205455256/article/details/41311013
[4] SURF算法原理总结:https://wenku.baidu.com/view/022c4286312b3169a551a4d1.html
[5] 线性插值&双线性插值&三线性插值:http://www.cnblogs.com/yingying0907/archive/2012/11/21/2780092.html