【翻译:OpenCV-Python教程】SURF (Speeded-Up Robust Features) 介绍

⚠️由于自己的拖延症,3.4.3翻到一半,OpenCV发布了4.0.1了正式版,所以接下来是按照4.0.1翻译的。

⚠️除了版本之外,其他还是照旧,Introduction to SURF (Speeded-Up Robust Features),原文

目标

在本章中,

  • 我们将看到SURF的基本知识
  • 我们将在OpenCV中看到SURF功能

理论

在上一章,我们看到了用于关键点检测和描述的SIFT算法。但它的速度相对较慢,人们需要一个更加速的版本。在2006年,三个人,Bay H.,Tuytelaars T. 还有 Van Gool L,发表了另外一个论文,"SURF:Speeded Up Robust Features",它引入了一种叫做SURF的新算法。就好像这个算法名字提出的那样,它是一个SIFT加速以后的版本(speeded-up version of SIFT)。

在SIFT算法中,Lowe(译者注:上篇里提到的论文作者之一) 的方案是用高斯差分算子近似计算拉普拉斯-高斯算子。SURF算法则更进一步,选择使用箱式过滤器来近视计算拉普拉斯-高斯算子。下图展示了这种近似的演示。这种近似计算有一个很大的优点,盒式过滤器的卷积可以在积分图像的帮助下非常容易的计算。而且它可以在不同的放缩比下并行进行。而且SURF在放缩和位置上都依赖于海塞矩阵的行列式。

surf_boxfilter.jpg

而对于方向指定,SURF使用在水平和垂直方向上对半径为6s(译者注:这里s应该是指放缩比)领域内的微波响应。适当的高斯权重也应用在它上面。然后它们被绘制在如下图所示的空间中。主导的方向通过计算所有60度滑动方向窗口内响应的总和来估计算。

有趣的是,微波响应在任何放缩比上都可以用积分图像轻易的算出来。对于许多应用场景,旋转不变性不是必需的,因此不需要找到这个方向,从而加快了这个过程。SURF 这样的一个功能被称作是 Upright-SURF 或者是 U-SURF。It improves speed and is robust upto ±15°(译者注,这句保留的原文,大意是说它提升了速度和保证了健壮性,但没太明白±和°这个两个符号的意义是什么)。

OpenCV根据标识upright的不同,将两者都支持,如果标识为0,则计算方向,如果为1,则不计算方向并且速度更快。(译者注:如果不需要旋转不变性就传入1)。

surf_orientation.jpg

为了描述功能,SURF使用水平和垂直方向的微波响应(再重申,使用积分图像使事情更容易)。取一个围绕着关键点的 20sX20s 的邻域,这里s是指大小。它被分为4x4个子区域。对于每个子区域,取水平和垂直方向的微波响应,并且向量像应该是像这样的格式,v = (∑dx,∑dy,∑|dx|,∑|dy|)。当其以向量表示时,它提供了总共64个维度的SURF特性描述符。降低维数,会提高计算和匹配速度,但能够提供了更好的特征区分度。

为了更清晰,SURF特性描述符有一个扩展到128维的版本。对于dy<0和dy≥0,分别用来计算dx和|dx|的和。同样地,dy和|dy|的和根据dx的正负符号被分割,从而使特征的数量加倍。它不会增加太多的计算复杂度。OpenCV两者都支持,通过为设置extended这个标识参数为0和1来分别表示64维和128维(默认为128维)。

另一个重要的改进是将拉普拉斯符号(黑塞矩阵的迹(译者附:矩阵的迹))用于潜在的兴趣点。它不增加任何计算成本,因为它已经在检测期间计算过了。拉普拉斯算子的符号是区分黑暗背景上的明亮斑点和相反的情况。在匹配阶段,我们只比较那些“具有相同类型的对比”的特征(如下图所示)。这个最小的信息允许更快的匹配,而不会降低描述符的性能。

surf_matching.jpg

简单的说,SURF增加了很多特性来提高每一步的速度。分析表明,在效果与SIFT相当的情况下,它比SIFT快了3倍。SURF擅长处理模糊和旋转的图像,但不擅长处理视角变化和亮度变化。

OpenCV里的SURF

OpenCV 提供的SURF功能,和SIFT几乎一样。你通过一些可选的条件,比如64或128维描述符,使用Upright-SURF或是普通的SURF等等,来初始化一个SURF对象。然后就像我们在SIFT里做的那样,我们可以使用 SURF.detect(),SURF.compute() 等等来找出关键点和描述符。

首先我们会看一个简单的示例,如何算出关键点和描述符,并且把他们画出来。所有的例子都在 Python 终端上写的,毕竟它就是和 SIFT 完全一样的而已。

>>> img = cv.imread('fly.png',0)
# Create SURF object. You can specify params here or later.
# Here I set Hessian Threshold to 400
>>> surf = cv.xfeatures2d.SURF_create(400)
# Find keypoints and descriptors directly
>>> kp, des = surf.detectAndCompute(img,None)
>>> len(kp)
699

1199 个关键点显示在一张图里实在是太多了。我们把它缩小到50个,来画在图像上。在匹配时,我们可能需要所有这些特性,但不是现在。所以我们提升了黑塞阈值。

# Check present Hessian threshold
>>> print( surf.getHessianThreshold() )
400.0
# We set it to some 50000. Remember, it is just for representing in picture.
# In actual cases, it is better to have a value 300-500
>>> surf.setHessianThreshold(50000)
# Again compute keypoints and check its number.
>>> kp, des = surf.detectAndCompute(img,None)
>>> print( len(kp) )
47

它小于50了,我们把它画在图像上。

>>> img2 = cv.drawKeypoints(img,kp,None,(255,0,0),4)
>>> plt.imshow(img2),plt.show()

参见下面的结果。你可以看到SURF更像斑点探测器。它能探测到蝴蝶翅膀上的白色斑点。您可以用其他图像测试它。

surf_kp1.jpg

现在我想应用以下U(pright)-SURF,这样我就不会找出方向。

# Check upright flag, if it False, set it to True
>>> print( surf.getUpright() )
False
>>> surf.setUpright(True)
# Recompute the feature points and draw it
>>> kp = surf.detect(img,None)
>>> img2 = cv.drawKeypoints(img,kp,None,(255,0,0),4)
>>> plt.imshow(img2),plt.show()

参见下面的结果。所有的方向都显示在同一个方向上。它的处理速度比以前快了。如果你正在处理的情况下,方向不是一个问题(如全景拼接)等,这是更好的选择。

surf_kp2.jpg

最后我们检查描述符的大小,如果它只有64维,则将其更改为128维。

# Find size of descriptor
>>> print( surf.descriptorSize() )
64
# That means flag, "extended" is False.
>>> surf.getExtended()
 False
# So we make it to True to get 128-dim descriptors.
>>> surf.setExtended(True)
>>> kp, des = surf.detectAndCompute(img,None)
>>> print( surf.descriptorSize() )
128
>>> print( des.shape )
(47, 128)

剩下的部分是匹配,我们将在另一章中来做。

额外资源

练习


上篇:【翻译:OpenCV-Python教程】SIFT(Scale-Invariant Feature Transform) 介绍

下篇:【翻译:OpenCV-Python教程】角点检测的快速(FAST)算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值