FAST特征点检测算法由E.Rosten和T.Drummond在2006年在其论文“Machine Learning for High-speed Corner Detection”中首次提出。英文全称是“Features from Accelerated Segment Test”,可以翻译成“基于加速分割测试的特征”。从论文名字可以看出FAST是一种高效的特征点(角点)检测算法,基本上可以满足实时检测系统要求,是计算机视觉领域最主流的角点检测算法之一。虽然FAST特征检测速度很快,但首字母刚好拼成fast,实在是一个美丽的巧合。
FAST算子
FAST算子的基本原理是:若某像素点与其周围领域内足够多的连续的像素点存在某一属性差异,并且该差异大于指定阈值,则可以断定该像素点与其邻域像素有可被识别的不同之处,可以作为一个特征点(角点);对于灰度图像,FAST算子考察的属性是像素与其邻域的灰度差异。
这个检查过程可以用下图更清楚的描述:对于图像上所有像素点,考察其7*7邻域内以该点为圆心,半径是3的圆周上的共计16个像素点和中心点的差异。如果有连续的12(或9)个像素点与中心点的灰度差的绝对值大于某一给定阈值,则该点被检测为FAST特征点。
为了提高检测速度,FAST提出分割测试的概念,不是逐个遍历考察圆周上的16个像素点,而是先考察垂直和水平方向上的4个点,对上图来说就是第2、10、6、14点。基于FAST算子要求圆周上最少有12(或9)个连续的差异较大的点,如果垂直和水平方向上4个点中有2个或2个以上不满足要求的点,则可以直接判断该点不是FAST特征点,这样可以排除绝大部分非FAST特征点。进过初步筛选,在对剩下的符合条件的点实施FAST算子进行特征点检测,最后进过非极大值抑制后得到最终的特征点检测结果。
FAST算子是通过邻域像素的比对来检测特征点,所以没有多尺度的问题。 并且FAST算子检测的不单单是“角点”这一个特征,还可以检测其他符合要求的特征点,如孤立的噪点等,健壮性不是很好。这就引入一个问题就是当图片中的噪点较多的时候,会产生较多误检的特征点。但基于其“fast”的特点,仍然是一些实时性要求较高场景的新宠。
Opencv中FAST特征检测类是在features2d.hpp中定义的,使用前要加上头文件“opencv2/features2d/features2d.hpp”
#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include <opencv2/features2d/features2d.hpp>
using namespace cv;
int main(int argc,char*argv[])
{
Mat image=imread(argv[1]);
vector<KeyPoint> keyPoints; //特征点向量
FastFeatureDetector fastDetecrtor(50); //设置检测阈值50
fastDetecrtor.detect(image,keyPoints); //FAST特征点检测
drawKeypoints(image,keyPoints,image,Scalar::all(-1)); //特征点绘制
imshow("Corner Detected",image);
waitKey();
return 0;
}
设置阈值为50时检测效果:
随着阈值越来越小,更多的角点被检测出来:
KeyPoint特征点类
保存特征点各种信息的KeyPoint类在使用中是不透明的,我们来看看KeyPoint类的主要属性:
class KeyPoint
{
Point2f pt; //特征点坐标
float size; //特征点邻域直径
float angle; //特征点的方向,值为0~360,负值表示不使用
float response; //特征点的响应强度,代表了该点是特征点的程度,可以用于后续处理中特征点排序
int octave; //特征点所在的图像金字塔的组
int class_id; //用于聚类的id
}
主要包含的特征点信息有:位置、邻域直径、特征的方向、响应强度、多尺度信息和分类等。特征点匹配的实现就是通过逐个匹配特征点的这些信息。
drawKeypoints特征点绘制
opencv提供了一个快速绘制特征点的函数drawKeypoints,函数原型:
void drawKeypoints( const Mat& image, const vector<KeyPoint>& keypoints, CV_OUT Mat& outImage,
const Scalar& color=Scalar::all(-1), int flags=DrawMatchesFlags::DEFAULT );
第二个参数keypoints:特征点向量,向量内每一个元素是一个KeyPoint对象,包含了特征点的各种属性信息;
第三个参数outImage:特征点绘制的画布图像,可以是原图像;
第四个参数color:绘制的特征点的颜色信息,默认绘制的是随机彩色;
第五个参数flags:特征点的绘制模式,其实就是设置特征点的那些信息需要绘制,那些不需要绘制,有以下几种模式可选:
DEFAULT:只绘制特征点的坐标点,显示在图像上就是一个个小圆点,每个小圆点的圆心坐标都是特征点的坐标。
DRAW_OVER_OUTIMG:函数不创建输出的图像,而是直接在输出图像变量空间绘制,要求本身输出图像变量就 是一个初始化好了的,size与type都是已经初始化好的变量
NOT_DRAW_SINGLE_POINTS:单点的特征点不被绘制
DRAW_RICH_KEYPOINTS:绘制特征点的时候绘制的是一个个带有方向的圆,这种方法同时显示图像的坐 标,size,和方向,是最能显示特征的一种绘制方式。