8.4. 角点检测的快速算法¶
8.4.1. 目标¶
8.4.2. 理论¶
我们看到了几个特征检测器,其中很多非常好。但从实时应用的角度来看,它们还不够快。一个最好的例子是SLAM(同时定位和映射)移动机器人,它的计算资源有限。
为了解决这一问题,Edward Rosten和Tom Drummond在2006年的论文《高速角点检测的机器学习》中提出了FAST算法(加速段测试的特征)。算法的基本总结如下。更多细节请参阅原稿(所有图片均取自原稿)。
快速特征检测¶
选择像素 \(p\) 在图像中是否被识别为兴趣点。让它的强度 \(I_p\) .
选择适当的阈值 \(t\) .
假设被测像素周围有一个16像素的圆。(见下图)
> <img src="images/fast_speedtest.jpg" alt="A corner in the image" class="align-center" />
现在是像素 \(p\) 如果存在一组 \(n\) 圆圈中的连续像素(16像素),其亮度均大于 \(I_p + t\) ,或者比 \(I_p − t\) . (在上图中显示为白色虚线)。 \(n\) 被选为12岁。
A high-speed test 被提议排除大量非拐角。此测试仅检查1、9、5和13处的四个像素(如果第一个1和9太亮或太暗,则测试它们)。如果是,则检查5和13)。如果 \(p\) 是一个角落,那么至少有三个角落比 \(I_p + t\) 或者比 \(I_p − t\) . 如果这两个都不是,那么 \(p\) 不能是角落。然后,通过检查圆中的所有像素,可以将全段测试标准应用于通过的候选对象。这种探测器本身表现出高性能,但有几个弱点:
> - It does not reject as many candidates for n < 12.
> - The choice of pixels is not optimal because its efficiency
> depends on ordering of the questions and distribution of
> corner appearances.
> - Results of high-speed tests are thrown away.
> - Multiple features are detected adjacent to one another.
前三点是用机器学习方法解决的。最后一个是使用非最大抑制来处理。
角点检测的机器学习¶
选择一组要训练的图像(最好来自目标应用程序域)
在每个图像中运行快速算法以找到特征点。
对于每个特征点,将其周围的16个像素存储为向量。对所有图像进行此操作以获得特征向量 \(P\) .
每个像素(比如 \(x\) )在这16个像素中,可以具有以下三种状态之一:
> <img src="images/fast_eqns.jpg" alt="FAST equation" class="align-center" />
根据这些状态,特征向量 \(P\) 分为3个子集, \(P_d\) , \(P_s\) , \(P_b\) .
定义一个新的布尔变量, \(K_p\) ,如果 \(p\) 是一个角落,否则就错了。
使用ID3算法(决策树分类器)使用变量查询每个子集 \(K_p\) 为了了解真正的班级。它选择 \(x\) 它产生了关于候选像素是否是角点的最大信息,由 \(K_p\) .
它递归地应用于所有子集,直到其熵为零。
这样生成的决策树用于其他图像的快速检测。
非最大抑制¶
在相邻位置检测多个兴趣点是另一个问题。采用非最大值抑制法求解。
计算得分函数, \(V\) 所有检测到的特征点。 \(V\) 是 \(p\) 以及16个周围像素值。
考虑两个相邻的关键点并计算它们 \(V\) 价值观。
丢弃较低的那个 \(V\) 价值。
8.4.3. OpenCV中的快速特征检测¶
它被称为OpenCV中的任何其他特征检测器。如果需要,可以指定阈值、是否应用非最大抑制、要使用的邻域等。
对于邻里,定义了三个标志, cv2.FAST_FEATURE_DETECTOR_TYPE_5_8
, cv2.FAST_FEATURE_DETECTOR_TYPE_7_12
和 cv2.FAST_FEATURE_DETECTOR_TYPE_9_16
. 下面是一个关于如何检测和绘制快速特征点的简单代码。
>>> %matplotlib inline
>>>
>>> import numpy as np
>>> import cv2 as cv
>>> from matplotlib import pyplot as plt
>>> img = cv.imread('/cvdata/simple.jpg',0)
>>> # Initiate FAST object with default values
>>> fast = cv.FastFeatureDetector_create()
>>> # find and draw the keypoints
>>> kp = fast.detect(img,None)
>>> img2 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
>>> # Print all default params
>>> print( "Threshold: {}".format(fast.getThreshold()) )
>>> print( "nonmaxSuppression:{}".format(fast.getNonmaxSuppression()) )
>>> print( "neighborhood: {}".format(fast.getType()) )
>>> print( "Total Keypoints with nonmaxSuppression: {}".format(len(kp)) )
>>> cv.imwrite('xx_fast_true.png',img2)
Threshold: 10
nonmaxSuppression:True
neighborhood: 2
Total Keypoints with nonmaxSuppression: 431
True
>>> plt.imshow(img2)
<matplotlib.image.AxesImage at 0x7fbf813879b0>
>>> # Disable nonmaxSuppression
>>> fast.setNonmaxSuppression(0)
>>> kp = fast.detect(img,None)
>>> print( "Total Keypoints without nonmaxSuppression: {}".format(len(kp)) )
>>> img3 = cv.drawKeypoints(img, kp, None, color=(255,0,0))
>>> cv.imwrite('xx_fast_false.png',img3)
Total Keypoints without nonmaxSuppression: 1575
True
>>> plt.imshow(img3)
<matplotlib.image.AxesImage at 0x7fbf813fec50>
看看结果。第一幅图像显示的是非轴抑制的快速图像,第二幅图像显示的是非轴抑制的快速图像:
8.4.4. 额外资源¶
Edward Rosten和Tom Drummond,“用于高速拐角检测的机器学习”,第9届欧洲计算机视觉会议,2006年第1卷,第430-443页。
Edward Rosten、Reid Porter和Tom Drummond,在IEEE Trans中,“更快更好:角点检测的机器学习方法”。模式分析和机器智能,2010年,第32卷,第105-119页。