【OpenCV-Python】教程:4-6 FAST (Features from Accelerated Segment Test)算法角点检测

OpenCV Python FAST(Features from Accelerated Segment Test) 算法角点检测

【目标】

  • 理解FAST算法的理论基础;
  • 用OpenCV里的FAST 检测角点;

【理论】

我们看到了几个特征检测器,其中很多都非常好。但是从实时应用程序的角度来看,它们还不够快。一个最好的例子是SLAM ( Simultaneous Localization and Mapping ) 移动机器人,它的计算资源有限。

作为一种解决方案,FAST (feature from Accelerated Segment Test) 算法由Edward Rosten 和 Tom Drummond 在2006年的论文《Machine learning for high-speed corner detection 》中提出,(后来在2010年进行了修订)。下面是对该算法的基本总结。详情请参考原论文(所有图片均取自原论文)。

利用FAST进行特征检测

  1. 选择一个像素 p(被判断是否为感兴趣的点), 设它的亮度为 Ip;
  2. 选择一个适当的阈值 t;
  3. 假定该点的 16 邻域将被用于测试;

【OpenCV-Python】教程:4-6 FAST (Features from Accelerated Segment Test)算法角点检测_第1张图片

  1. 如果 p 周围有n个连续点亮于 p, 或者 暗于 p, 则该点为 FAST 的角点。n 一般选择为 12;
  2. 一个快速的去除非角点的方法是,只测试考虑1、9、5、13等点,亮度同时超过或低于 p 点的像素超过3个,则认为是角点,否则为非角点。它有以下缺点:
    • 当 n < 12 时,它不会拒绝尽可能多的候选;
    • 像素的选择不是最有的,因为它的效率取决于问题的顺序和角点的分布;
    • 高速测试的结果被丢弃;
    • 多个特征点相邻;

前三点是用机器学习方法解决的。最后一个是使用非最大抑制来解决的。

机器学习角点检测器

  1. 选择一批图像用于训练,最好是选择应用领域的图像;
  2. 运行FAST算法在每张图像中找到特征点。
  3. 对于每个特征点,存储其 16 个邻域像素为一个 vector,对所有图像都进行;
  4. 对于每个像素来说,都可能存在3种以下情况:

【OpenCV-Python】教程:4-6 FAST (Features from Accelerated Segment Test)算法角点检测_第2张图片

  1. 基于这些状态,这些特征向量被分为3个子集 P d , P s , P b P_d,P_s,P_b Pd,Ps,Pb
  2. 定义一个布尔向量, K p K_p Kp, 如果 p p p 是角点,则为真,否则为假;
  3. 利用ID3算法 (决策树分类器)使用变量 K p K_p Kp查询每个子集
  4. 这将递归应用所有子集,直到熵为零;
  5. 这样创建的决策树用于其他图像的快速检测;

非极大抑制

在相邻位置检测多个兴趣点是另一个问题。采用非极大抑制法求解。

  1. 为所有检测到的特征点计算一个评分函数 V V V V V V p p p 与周围16个像素值的绝对差值之和;
  2. 考虑两个相邻的关键点并计算它们的 V V V值。
  3. 丢弃 V V V值较低的。

总结

该算法比其他的角点检测快几倍;但是对于噪声来说并不鲁棒,依赖于阈值;

【代码】

【OpenCV-Python】教程:4-6 FAST (Features from Accelerated Segment Test)算法角点检测_第3张图片

import numpy 
import cv2 
from matplotlib import pyplot as plt

# 读取图片
img = cv2.imread("assets/blox.jpg", 0)
colorim = cv2.imread("assets/blox.jpg", 1)

# 创建Fast检测
fast = cv2.FastFeatureDetector_create()

# Fast 特征检测
kp = fast.detect(img, None)

# 画特征点
img2 = cv2.drawKeypoints(img, kp, None, color=(255,0,0))

# 打印所有参数
print( "Threshold: {}".format(fast.getThreshold()) )
print( "nonmaxSuppression:{}".format(fast.getNonmaxSuppression()) )
print( "neighborhood: {}".format(fast.getType()) )
print( "Total Keypoints with nonmaxSuppression: {}".format(len(kp)) )

# 关闭非极大值抑制
fast.setNonmaxSuppression(0)
kp = fast.detect(img, None)
print("Total Keypoints without nonmaxSuppression: {}".format(len(kp)))
img3 = cv2.drawKeypoints(img, kp, None, color=(255, 0, 0))

cv2.imshow("img2", img2)
cv2.imshow("img3", img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 输出
Threshold: 10
nonmaxSuppression:True
neighborhood: 2
Total Keypoints with nonmaxSuppression: 431
Total Keypoints without nonmaxSuppression: 1575

【接口】

  • FastFeatureDetector_create
cv2.FastFeatureDetector_create(	[, threshold[, nonmaxSuppression[, type]]]	) ->	retval
  • type: FastFeatureDetector::DetectorType; TYPE_5_8/TYPE_7_12/TYPE_9_16
# 获得算法名称ID,
# Reimplemented in cv::AKAZE, cv::KAZE, cv::SimpleBlobDetector, cv::GFTTDetector, cv::AgastFeatureDetector, cv::FastFeatureDetector, cv::MSER, cv::ORB, cv::BRISK, cv::SIFT, and cv::AffineFeature.
cv.FastFeatureDetector.getDefaultName(		) ->	retval

# 是否采用了非极大值抑制
cv.FastFeatureDetector.getNonmaxSuppression(		) ->	retval

# FAST的阈值
cv.FastFeatureDetector.getThreshold(		) ->	retval

# FAST Detector 类型
cv.FastFeatureDetector.getType(		) ->	retval

# 设置非极大值抑制
cv.FastFeatureDetector.setNonmaxSuppression(	f	) ->	None

# 设置阈值
cv.FastFeatureDetector.setThreshold(	threshold	) ->	None

# 设置类型
cv.FastFeatureDetector.setType(	type	) ->	None

【参考】

  1. OpenCV 官方文档
  2. Edward Rosten and Tom Drummond, “Machine learning for high speed corner detection” in 9th European Conference on Computer Vision, vol. 1, 2006, pp. 430–443.
  3. Edward Rosten, Reid Porter, and Tom Drummond, “Faster and better: a machine learning approach to corner detection” in IEEE Trans. Pattern Analysis and Machine Intelligence, 2010, vol 32, pp. 105-119.
  4. FastFeatureDetector Class Reference

你可能感兴趣的:(#,OpenCV-Python,教程,python,opencv,算法,FAST)