主要参考:
http://blog.csdn.net/abcjennifer/article/details/7639681
http://www.cnblogs.com/linyunzju/archive/2011/06/14/2080951.html
http://www.360doc.com/content/14/1013/15/18306241_416576994.shtml
对比看着三篇文章,很有收获,更多资料可以wiki:https://en.wikipedia.org/wiki/Scale-invariant_feature_transform#David_Lowe.27s_method,里面有很多经典的参考文章。
sift算法的详细原理可以对比上面的资料分析。这里我只简单写一下关键点。
Sift关键:
1. 尺度空间的表达:Gauss-blur图,尺度sigma,金字塔
2.尺度的连续性:两层octive之间的尺度sigma是连续的。故每一层的模糊图像数目为5最佳,相应的Dog图则为4幅。
3.Dog图是由Gauss-blur图在相邻两张之间的差,所以图像少一张。
4.搜索关键点:在同一层相邻的Dog图的8+9*2=26个邻域中的极值。为了获取亚像素进度,要进行拟合求导。
5.关键点的方向:在Gauss-blur图的关键点的邻域内搜索,统计邻域的梯度方向,此时0~360°的角度可以分箱(比如分成8个bin,则每一个范围为45°),统计的结果并不是简单的增加1.而是考虑这个梯度方向的赋值大小,以及离关键点的距离,所以最终的做法是:首先,计算邻域的梯度+梯度幅值,然后用高斯系数对梯度幅值进行处理(使得离关键点远的点的梯度幅值相应减小,所以统计方向的时候对主方向的影响也变小),最后,统计方向,按变化后的梯度幅值作为影响因子得到统计的直方图。最后,将直方图的最大比重的统计方向作为关键点的方向。
6.描述算子:考虑到旋转不变性,则描述算子的方向都要减去关键点的方向(也就是:描述算子的方向都是相对关键点的方向表示的,这样就具有了旋转不变性),最后统计邻域内的方向直方图,作为特征向量(描述算子)
7.匹配特征:描述算子之间的欧式距离计算
其中:第4,5,6步都涉及邻域,这里并没有提到邻域的大小等,这些在上面的文章中都有详细讲解。
最后,通过引申提到Sift,surf以及PCA-sift算法,这里引用别人的一段总结:
SIFT(Scale-invariant feature transform), Lowe, 2004
PCA-SIFT(Principle Component Analysis), Y.ke, 2004
SURF(Speeded Up Robust Features), Bay, 2006
这三位先后登场各有千秋,算是图像特征点检测领域的宋氏三姐妹了!SIFT鼻祖先宗大佬,PCA-SIFT将SIFT中直方图方法换作主元分析法,SURF取出integral/Hessian两样法宝实现加速,也更易于并行。
下面,先整理SIFT思路:
1. 输入图像,建议做double(width*=2, height*=2, size*=4), 并高斯过滤进行平滑。
2. 由图片size决定建几个塔,每塔几层图像(一般3-5层)。0塔的第0层是原始图像(或你double后的图像),往上每一层是对其下一层进行Laplacian变换(高斯卷积,其中sigma值渐大,例如可以是sigma, k*sigma, k*k*sigma…),直观上看来越往上图片越模糊。塔间的图片是降采样关系,例如1塔的第0层可以由0塔的第3层down sample得到,然后进行与0塔类似的高斯卷积操作。
3. 构建DoG金字塔。DoG金字塔由上一步生成的Gauss金字塔计算得到,塔数相同,每塔层数少1,因为DoG的每一层由Gauss的相邻两层相减得到。
4. 在DoG塔里进行极值点检测,并根据用户预设的对比度阈值、主曲率阈值去除不合法特征点。极值点检测用的Non-Maximal Suppression,即在3*3*3个点中进行灰度值比较,最小或最大才过关。
5. 计算每个特征点的尺度。注意塔间尺度关系,sigma*2.0^(octvs+intvl/intvls)
6. 计算每个特征点的梯度模值和方向。用特征点周围一个矩阵区域(patch)内的点来描述该特征点,用的直方图进行模值统计并寻找主方向,主方向可以不止一个。
7. 最后要生成64D或128D的特征描述符了。对齐主方向,计算方向直方图2D数组,假如每个直方图有8bin,那么64D(2*2*8bin)或128D(4*4*8bin)。
大面儿上说,SURF vs. SIFT:
|
SIFT |
SURF |
特征点检测 |
用不同尺度的图片与高斯函数做卷积 |
用不同大小的box filter与原始图像(integral image)做卷积,易于并行 |
方向 |
特征点邻接矩形区域内,利用梯度直方图计算 |
特征点邻接圆域内,计算x、y方向上的Haar小波响应 |
描述符生成 |
20*20(单位为pixel)区域划分为4*4(或2*2)的子区域,每个子域计算8bin直方图 |
20*20(单位为sigma)区域划分为4*4子域,每个子域计算5*5个采样点的Haar小波响 应,记录∑dx, ∑dy, ∑|dx|,∑|dy|。 |
SURF基于integral image,利用determination of Hessian matrix来描述极值点,也就是可能的特征点。那么什么是积分图像?在这里Hessian矩阵又是什么?怎么求得这个det(H)?它怎么样了就是极值点了?box filter是怎么来地,什么样儿?这里有相关文档和源码下载,很详细很清晰,这里我就不八了,您佬哪里不明白,跟帖交流。我比较好奇的是,Bay是如何发现integral image * box filter与高斯卷积这层近似关系的?为什么他会想到这么做?此外,基于integral image * Haar wavelet filter进行主方向的判定及描述符的生成,这样的卷积结果是什么?又说明了什么?是一种与邻接点差异或变化率的反映?Integral image is so fabulous。有兴趣的朋友一起讨论一下?
Luo Juan对这三种算法进行了实验比较,衡量参数有Processing time/ scale / changes/ rotation/ blur/ illumination/ affine,衡量指标有重复度或RANSAC内点概率,图片库来自这里。下面是大体赛况,您可以搜索"A comparison of SIFT, PCA-SIFT and SURF"看直播。
method |
Time |
Scale |
Rotation |
Blur |
Illumination |
Affine |
Sift |
common |
best |
best |
common |
common |
good |
PCA-sift |
good |
good |
good |
best |
good |
best |
Surf |
best |
common |
common |
good |
best |
good |
另外,SIFT、SURF也分别有了GPU实现,欢迎一起探讨学习!
SIFT on GPU, S.Heymann, 2005
SIFT on GPU(2), Sudipta N.Sinha, 2006
SURF on GPU, Nico Cornelis, 2008
此外,cy513的"SIFT/SURF算法的深入剖析——谈SIFT的精妙与不足"写地很棒,链过去方便大家阅读。
在看这些算法时,接触到Hog算法,做行人检测,所以顺便了解了一下,这里也引用别人的一段话
HOG特征原理:
HOG的核心思想是所检测的局部物体外形能够被光强梯度或边缘方向的分布所描述。通过将整幅图像分割成小的连接区域(称为cells),每个cell生成一个方向梯度直方图或者cell中pixel的边缘方向,这些直方图的组合可表示出(所检测目标的目标)描述子。为改善准确率,局部直方图可以通过计算图像中一个较大区域(称为block)的光强作为measure被对比标准化,然后用这个值(measure)归一化这个block中的所有cells.这个归一化过程完成了更好的照射/阴影不变性。
与其他描述子相比,HOG得到的描述子保持了几何和光学转化不变性(除非物体方向改变)。因此HOG描述子尤其适合人的检测。
通俗的讲:
HOG特征提取方法就是将一个image:
1. 灰度化(将图像看做一个x,y,z(灰度)的三维图像)
2. 划分成小cells(2*2)
3. 计算每个cell中每个pixel的gradient(即orientation)
4. 统计每个cell的梯度直方图(不同梯度的个数),即可形成每个cell的descriptor
再小谈下Hog、SIFT与PCA-SIFT的应用与区别:
Hog没有旋转和尺度不变性,因此计算量小;而SIFT中每个feature需要用128维的向量来描述,因此计算量相对很大。
那么行人检测中怎么应用HOG呢?
对于解决Scale-invariant 的问题:将图片进行不同尺度的缩放,就相当于对模板进行不同尺度scale的缩放
对于解决Rotation-invariant 的问题:建立不同方向的模版(一般取15*7的)进行匹配
总的来说,就是在不同尺度上的图像进行不同方向的模板(15*7)匹配,每个点形成一个8方向的梯度描述。