注释:本文翻译自OpenCV3.0.0 document->OpenCV-Python Tutorials,包括对原文档种错误代码的纠正
1.目标
- 学习SURF的基础知识
- 在OpenCV中看到SURF函数
2.理论
在上一章中,我们看到了SIFT的关键点检测和描述。但速度相对较慢,我们需要更加快速的版本。2006年,Bay, H., Tuytelaars, T. and Van Gool,L等人发布了另一篇文章“SURF,Speeded UpRobust Features”,其中介绍了一种名为SURF的新算法。顾名思义它是SIFT的加速版本。
在SIFT中,Lower用高斯差分近似拉普拉斯高斯分布来寻找尺度空间。SURF走得更远一点,并用Box Filter逼近LoG。下图显示了这种近似的演示。这种近似的一大优点是,利用积分图像可以容易地计算与盒式滤波器的卷积。它可以在不同的尺度下并行完成。
SURF依赖于Hessian矩阵的行列式和位置的行列式。
对于方向分配,SURF使用水平和垂直方向的小波响应来计算6s的领域。足够的guassian权重也适用于它。然后将它们绘制在下图中给出的空间中。通过计算角度60度的滑动取向窗口内的所有响应的总和来估计主导方向。有趣的是,小波响应可以很容易地在任何尺度上用积分图像找出来。对于许多应用来说,不需要旋转不变性,所以不需要找到这个方向,从而加快了处理速度。SURF提供了称为Upright-SURF或U-SURF的功能。它提高了速度,并且在15分钟之前保持稳定。根据标志,OpenCV支持两种标准。如果它是0,则计算方向;如果是1,则方向不计算并且更快。
对于特征描述,SURF使用水平和垂直方向的小波响应(再次,使用积分图像使其更容易)。在尺寸为s的关键点周围拍摄20s×20s的邻域。它分为4x4个分区域。对于每个子区域,采用水平和垂直小波响应并且像这样形成矢量,其中 。这表示为矢量时,SURF特征描述符总共有64个维度。降低维度,提高计算速度和匹配速度,但提供更好的功能独特性。
为了更加独特,SURF特征描述符具有扩展的128维版本。和
的总和分别为
和
.计算。类似地,
和
根据
的符号进行分割,从而使特征的数量加倍。它不会增加很多计算复杂性。 OpenCV支持两种方式,分别为64-dim和128-dim设置扩展标志的值0和1(默认值为128-dim)
简而言之,SURF增加了很多功能来提高每一步的速度。分析表明它比SIFT快3倍,而性能可与SIFT相媲美。 SURF善于处理模糊和旋转的图像,但不擅长处理视点变化和照明变化。
3.OpenCV中的SURF
OpenCV像SIFT一样提供SURF函数。你用一些可选的条件来启动一个SURF对象,比如64/128-dim描述符,Uright/Normal SURF等等。所有细节再文档中都有很好的解释。然后就像我们再SIFT中所做的那样,我们可以使用SURF.detect()、SURF.compute()来查找关键点和描述符。
看下面的这个栗子:
# -*- coding: utf-8 -*-
'''
SURF:
1.上一节中的SIFT找到了关键点和描述,但速度较慢,需要速度更快的版本,SURF比SIFT快3倍,性能可与SIFT媲美。
2.SURF善于处理模糊和旋转的图像,但不擅长处理视点变化和照明变化
3.OpenCV中的SURF:SURF.detect(),SURF.compute()来查找关键点和描述符
'''
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('5.jpg', 0)
surf = cv2.xfeatures2d.SURF_create(20000)
print("help of surf", help(surf))
print("getHessianThreshold", surf.getHessianThreshold())
surf.setUpright(True) # 将所有方向显示为一个方向
kp, des = surf.detectAndCompute(img, None)
print("len of kp", len(kp)) # 显示1253个关键点太多
print('des.shape', des.shape)
img2 = cv2.drawKeypoints(img, kp, None, (255, 0, 0,), 4)
plt.imshow(img2), plt.show()
# 将关键点缩小到50左右以便在图像上绘制,在匹配时,我们可能需要所有这些特征。所以增加hessian阈值
结果: