一. FAST基本原理
1. 在图像中选取一个像素点,来判断它是否为关键点。表示像素点的灰度值。
2. 选择适当的阈值。
3. 在像素点的周围选择16个像素点进行测试。
4. 如果在这16个像素点中存在个连续像素点的灰度值都高于,或者低于,那么像素点被认为是一个角点。如上图中的虚线所示,选取的值为12。
5. 一种更加快的改进是首先检测像素点周围的四个点(1,5,9,12)中是否有三个点满足阈值要求。如果不满足,则直接跳过,如果满足,则继续使用前面的算法,全部判断16个点中是否有12个满足条件。
上述算法效率很高,但是缺点如下所示:
1. 当时获得的候选点比较多。
2. 检测出来的角点不是最优的,因为它的效果取决于要解决的问题和角点的分布情况。
3. 对于角点分析的结果被丢弃了。
4. 检测到的很多角点都是连在一起的。
前3个问题可以通过机器学习的方法解决,最后一个问题可以使用非最大值抑制的方法解决。
二. 机器学习的角点检测器
1. 选取进行角点提取的应用场景下的一组训练图像。
2. 使用FAST角点检测算法找出训练图像上的所有角点。
3. 对于每一个角点,将其周围的16个像素存储成一个向量。对所有图像都这样做构建一个特征向量。
4. 每一个角点的16像素点都属于下列三类中的一种。
5. 根据这些像素点的分类,特征向量被分为3个子集:,,。
6. 定义一个新的布尔变量,如果是角点就设置为True,否则就设置为False。
7. 使用ID3算法来查询每一个子集。
8. 递归计算所有的子集直到它的熵为0。
9. 被构建好的决策树用于其它图像的FAST检测。
三. 非极大值抑制
使用极大值抑制[Non-Maximal Suppression,NMS]的方法可以解决检测到的角点相连的问题。如下所示:
1. 对所有检测到的角点构建一个打分函数。就是像素点与周围16个像素点差值的绝对值之和。
2. 考虑两个相邻的角点,并比较它们的值。
3. 值较低的角点将会被删除。
四. FAST优点和缺点
FAST算子比其它角点检测算法都快,但是当图像中的噪点较多时,它的健壮性并不好,而且算法的效果还依赖于阈值。并且FAST算子不产生多尺度特征而且FAST角点没有方向信息,这样就会失去旋转不变性。
五. OpenCV中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)
输出结果,如下所示:
参考文献:
[1] Machine learning for high-speed corner detection
[2] Faster and better:a machine learning approach to corner detection
[3] FAST Algorithm for Corner Detection:http://docs.opencv.org/3.0-