????????FAST算法(Features from Accelerated Segment Test)是一种用于在图像中快速检测角点的算法。它是一种基于像素的检测方法,具有高效、准确的特点,常用于计算机视觉领域中的特征点提取、图像匹配等任务。
????????我们前面学习了几个特征检测器,它们大多数效果都很好。但是从实时处理的角度来看,这些算法都不够快。一个最好例子就是SLAM(同步定位与地图构建)、移动机器人,它们的计算资源非常有限。为了解决这个问题,Edward_Rosten 和Tom_Drummond 在2006 年提出了FAST 算法。我们下面将会对此算法进行一个简单的介绍。你可以参考原始文献获得更多细节,本节中的所有图像都是来源于原始文章。
????????FAST算法的基本思想是通过对像素灰度值的快速比较来判断是否为角点。该算法的主要步骤如下:
1.在图像中选取一个像素点p,来判断它是不是关键点。Ip 等于像素点p的灰度值。
2.选择适当的阈值t。
3.如下图所示在像素点p 的周围选择16 个像素点进行测试。
4.如果在这16 个像素点中存在n 个连续像素点的灰度值高于于Ip + t,或者低于Ip ?t,那么像素点p 就被认为是一个角点。如上图中的虚线所示,n 选取的值为12。
5. 为了获得更快的效果,还采用了额外的加速办法。首先对候选点的周围每个90 度的点:1,9,5,13 j进行测试,(先测1 和19, 如果它们符合阈值要求再测试?5 和13)。如果p 是角点,那么这四个点中至少有3 个要符合阈值要求。如果不是的话肯定不是角点,就放弃。对通过这步测试的点再继续进行测试,看是否有12 的点符合阈值要求。这个检测器的效率很高,但是它有如下几条缺点:
????????? 当n<12 时它不会丢弃很多候选点(获得的候选点比较多)。
????????? 像素的选取不是最优的,因为它的效果取决与要解决的问题点和角点的分布情况。
????????? 告诉测试的结果被抛弃
????????? 检测到的很多特征点都是连在一起的。
? ? ? ? 通过不断研究改进,前3 个问题可以通过机器学习的方法解决,最后一个问题可以使用非最大值抑制的方法解决。
1. 选择一组训练练图片(最好是跟最后应用相关的图片)。
2. 使用FAST 算法找出每幅图像的特征点。
3. 对每一个特征点,将其周围的16 个像素存储构成一个向量。对所有图像都这样做构建一个特征向量?P。
?4. 每一个特征点的16 像素点都属于下列三类中的一种。
5. 根据这些像素点的分类,特征向量?P 也被分为3 个子集:Pd、Ps、Pb
6. 定义一个新的布尔变?Kp,如果p 是角点就设置为Ture,如果不是就设置为False。?
7. 使用ID3 算法(决策树分类器)Use the ID3 algorithm (decisiontree classifier) to query each subset using the variable Kp for theknowledge about the true class. It selects the x which yields the most information about whether the candidate pixel is a corner,measured by the entropy of Kp.
8. This is recursively applied to all the subsets until its entropy is zero.
9. 将构建好的决策树用于其他图像的快速的检测。
????????使用极大值抑制的方法可以解决检测到的特征点相连的问题。
????????和其它特征点检测一样我们可以在OpenCV 中直接使用FAST 特征检测器。如果你愿意的话,你可以设置阈值,是否进行最大值抑制,使用的邻域大小等。邻域可以设置为下列3 中之一:cv2.FAST_FEATURE_DETECTOR_TYPE_5_8, cv2.FAST_FEATURE_DETECTOR_TYPE_7_12和cv2.FAST_FEATURE_DETECTOR_TYPE_9_16。下面是使用FAST 算法进行特征点检测的简单代码。
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('simple.jpg',0)
# Initiate FAST object with default values
fast = cv2.FastFeatureDetector()
# find and draw the keypoints
kp = fast.detect(img,None)
img2 = cv2.drawKeypoints(img, kp, color=(255,0,0))
# Print all default params
print ("Threshold: ", fast.getInt('threshold'))
print ("nonmaxSuppression: ", fast.getBool('nonmaxSuppression'))
print ("neighborhood: ", fast.getInt('type'))
print ("Total Keypoints with nonmaxSuppression: ", len(kp))
cv2.imwrite('fast_true.png',img2)
# Disable nonmaxSuppression
fast.setBool('nonmaxSuppression',0)
kp = fast.detect(img,None)
print ("Total Keypoints without nonmaxSuppression: ", len(kp))
img3 = cv2.drawKeypoints(img, kp, color=(255,0,0))
cv2.imwrite('fast_false.png',img3)
????????结果如下。第一幅图是使用了非最大值抑制的结果,第二幅没有使用非最大值抑制。?
OpenCV的版本不同,常见特征器的方法可能会有不同,以下也可以参考。
在OpenCV-python中,可以使用cv2.FastFeatureDetector()函数来创建FAST角点检测器。该函数的用法如下:
fast = cv2.FastFeatureDetector_create(threshold=10, nonmaxSuppression=True, type=cv2.FAST_FEATURE_DETECTOR_TYPE_9_16, max_npoints=5000)
其中,参数的含义如下:
在创建FAST角点检测器后,可以使用fast.detect()函数来检测图像中的角点。
FAST角点检测器的type参数定义了角点检测算法的类型。在OpenCV-python中,提供了以下几种类型:
使用示例:
import cv2
# 读取图像
image = cv2.imread("image.jpg")
# 创建FAST角点检测器
fast = cv2.FastFeatureDetector_create(threshold=10, nonmaxSuppression=True, type=cv2.FAST_FEATURE_DETECTOR_TYPE_9_16, max_npoints=5000)
# 检测角点
keypoints = fast.detect(image, None)
# 绘制角点
image_with_keypoints = cv2.drawKeypoints(image, keypoints, None, color=(0, 255, 0), flags=0)
# 显示结果
cv2.imshow("FAST", image_with_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
在上述示例中,创建FAST角点检测器时,通过参数设置了阈值为10,进行非最大值抑制,使用16个像素点进行快速比较,并设置最大检测到的角点数量为5000。
?