OpenCV 4.11.0
开源计算机视觉库
|
在本章中,我们将:
在上一章中,我们学习了用于关键点检测和描述的SIFT算法。但它相对较慢,人们需要速度更快的版本。2006年,Bay, H.,Tuytelaars, T. 和 Van Gool, L.发表了一篇名为“SURF: Speeded Up Robust Features”的论文,介绍了一种称为SURF的新算法。顾名思义,它是SIFT的加速版本。
在SIFT中,Lowe用高斯差分近似高斯拉普拉斯算子来寻找尺度空间。SURF更进一步,用盒式滤波器近似LoG。下图展示了这种近似的示例。这种近似的一个巨大优势是,盒式滤波器的卷积可以用积分图像轻松计算。并且可以针对不同的尺度并行进行。此外,SURF依赖于Hessian矩阵的行列式来确定尺度和位置。
对于方向分配,SURF使用大小为6s的邻域内的水平和垂直方向的小波响应。还应用了适当的高斯权重。然后将它们绘制在如下所示的空间中。通过计算60度角度滑动方向窗口内所有响应的总和来估计主方向。有趣的是,可以使用积分图像非常轻松地在任何尺度上找到小波响应。对于许多应用,不需要旋转不变性,因此不需要找到这个方向,这可以加快处理速度。SURF提供了一种称为Upright-SURF或U-SURF的功能。它提高了速度,并且对±15°的旋转具有鲁棒性。OpenCV支持两者,具体取决于标志`upright`。如果为0,则计算方向;如果为1,则不计算方向,速度更快。
对于特征描述,SURF使用水平和垂直方向的小波响应(同样,使用积分图像使事情变得更容易)。在关键点周围取一个大小为20sX20s的邻域,其中s是大小。将其划分为4x4个子区域。对于每个子区域,获取水平和垂直小波响应并形成一个向量,例如,\(v=( \sum{d_x}, \sum{d_y}, \sum{|d_x|}, \sum{|d_y|})\)。当表示为向量时,它给出了具有总共64维的SURF特征描述符。维度越低,计算和匹配的速度越快,但提供的特征区分度越好。
为了获得更好的区分度,SURF特征描述符具有扩展的128维版本。\(d_x\)和\(|d_x|\)的和分别针对\(d_y < 0\)和\(d_y \geq 0\)计算。同样,\(d_y\)和\(|d_y|\)的和根据\(d_x\)的符号分开,从而使特征数量加倍。它不会增加太多计算复杂度。OpenCV通过设置标志`extended`的值来支持两者,对于64维和128维分别为0和1(默认值为128维)。
另一个重要的改进是使用拉普拉斯算子的符号(Hessian矩阵的迹)来表示潜在的兴趣点。它不会增加计算成本,因为它在检测过程中已经计算出来。拉普拉斯算子的符号区分了暗背景上的亮斑与相反情况。在匹配阶段,我们只比较具有相同对比度的特征(如下面的图像所示)。这些最少的信息允许更快地匹配,而不会降低描述符的性能。
简而言之,SURF添加了许多功能来提高每一步的速度。分析表明,它的速度是SIFT的三倍,而性能与SIFT相当。SURF擅长处理模糊和旋转的图像,但不擅长处理视角变化和光照变化。
OpenCV提供与SIFT类似的SURF功能。您可以使用一些可选条件(例如64/128维描述符、Upright/Normal SURF等)来初始化SURF对象。文档中详细解释了所有细节。然后,就像我们在SIFT中所做的那样,我们可以使用SURF.detect()、SURF.compute()等来查找关键点和描述符。
首先,我们将看到一个简单的演示,说明如何查找SURF关键点和描述符并绘制它。所有示例都在Python终端中显示,因为它与SIFT完全相同。
1199个关键点太多了,无法在一张图片中显示。我们将它减少到大约50个,以便将其绘制到图像上。在匹配时,我们可能需要所有这些特征,但现在不需要。因此,我们增加了Hessian阈值。
少于50个。让我们将其绘制到图像上。
请参见下面的结果。您可以看到SURF更像是一个斑点检测器。它检测蝴蝶翅膀上的白色斑点。您可以使用其他图像进行测试。
现在我想应用U-SURF,这样它就不会找到方向。
请参见下面的结果。所有方向都以相同方向显示。它比之前的版本更快。如果您正在处理方向无关紧要的情况(例如全景拼接)等,则此方法更好。
最后,我们检查描述符大小,如果它是64维的,则将其更改为128。
其余部分是匹配,我们将在另一章中进行。