天天看点

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介

简介

      FAST特征检测的特点是简单、快速、有效。作者为了在实时帧速率情况下进行高速特征检测,提出FAST特征检测。 相比SIFT、DoG、Harris、SUSAN等比较耗时的特征检测方法,FAST只利用周围的像素进行比较,速度大大加快。注意:FAST只是一种特征点检测算法,并不涉及特征点的特征描述。

       大多数特征检测算法通过在图像上计算角点响应函数(C),然后检测超过阈值(并且是局部最大值)的像素。 如Harris特征使用的角点响应函数: 

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介

其中:

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介

          Shi-Tomasi特征使用的角点响应函数: 

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介

        另一类角点探测器的工作原理是检查一小块图像,看它是否看起来像一个角点。 由于不计算二阶导数,因此不需要降噪步骤(例如高斯平滑)。 因此,这些角点检测器在计算上是有效的,因为对于检测到的每个角点只检查少量的像素。 因此,它们仅具有诸如模糊图像的大尺寸特征。FAST角点检测属于这一类。 

          FAST算法是基于角点检测的图像特征.一个特征点检测的算法的第一步是定义什么是特征点,FAST算法定义特征点是如果某个像素点和他周围领域足够多的像素点处于不同区域,那么这个像素点就是特征点,对于灰度图像来说,也就是该点的灰度值和其周围足够多的像素点的灰度值不同,那么这个像素点就是一个特征点.

FAST算法的步骤:

从图片中选取一个坐标点P,获取该点的像素值,接下来判定该点是否为特征点.

选取一个以选取点P坐标为圆心的半径等于r的Bresenham圆(一个计算圆的轨迹的离散算法,得到整数级的圆的轨迹点),一般来说,这个圆上有16个点,如下所示

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介

使用FAST进行功能检测:

1、p在图像中选择一个被识别为兴趣点的像素。令它的强度为 Ip; 

2、选择一个合适的阈值t; 

3、考虑被测像素周围的16个像素的圆圈。 

4、如果这16个像素中存在一组ñ个连续的像素的像素值,比 Ip+t 大,或比 Ip−t小,则像素p是一个角点。ñ被设置为12。 

5、使用一种快速测试(high-speed test)可快速排除了大量的非角点。这个方法只检测在1、9、5、13个四个位置的像素,(首先检测1、9位置的像素与阈值比是否太亮或太暗,如果是,则检查5、13)。如果p是一个角点,则至少有3个像素比 Ip+t大或比 Ip−t暗。如果这两者都不是这样的话,那么p就不能成为一个角点。然后可以通过检查圆中的所有像素,将全部分段测试标准应用于通过的对候选的角点。这种探测器本身表现出很高的性能,但有一些缺点: 

- 它不能拒绝n <12的候选角点。当n<12时可能会有较多的候选角点出现 

- 检测到的角点不是最优的,因为它的效率取决于问题的排序和角点的分布。 

- 角点分析的结果被扔掉了。过度依赖于阈值

- 多个特征点容易挤到一起。 

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

1、机器学习角点探测器

选择一组用于训练的图像(最好来自目标应用区域),在每个图像中运行FAST算法以查找特征点。对于每个特征点,将其周围的16个像素存储为一个向量。获取所有图像的特征向量P。对于圆上的每个位置x∈{1..16},这16个相对于p的位置(由p→x表示)的像素有以下3种状态: 

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介
  1. 根据这些状态,特征向量P被细分为3个子集 
    OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介
    ,
    OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介
    ,
    OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介
  2. 定义一个新的布尔变量 Kp,若p是一个角点,则为true,否则为false。
  3. 使用ID3算法(决策树分类器)使用变量来查询每个子集,利用 Kp确认其真实类别。通过测量Kp的熵,选择产生关于候选像素是否是一个角点的信息最多的x。
  4. 递归地应用于所有的子集,直到它的熵为零。
  5. 这样创建的决策树用于其他图像的快速检测。

2 非极大抑制

在筛选出来的候选角点中有很多是紧挨在一起的,需要通过非极大值抑制来消除这种影响。

为所有的候选角点都确定一个打分函数V,V的值可这样计算:先分别计算Ip与圆上16个点的像素值差值,取绝对值,再将这16个绝对值相加,就得到了V 的值。

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介

最后比较毗邻候选角点的V值,把V值较小的候选角点pass掉。

至此,FAST算法结束。

在上面的步骤中我们令n=12,此时是FAST算法中的FAST-12,常用的还有FAST-9,即令n=9。

OpenCV3中FAST方法以FastFeatureDetector类的形式封装,为Feature2D类的子类:

class CV_EXPORTS_W FastFeatureDetector : public Feature2D
{
public:
    enum
    {
        TYPE_5_8 = 0, TYPE_7_12 = 1, TYPE_9_16 = 2,
        THRESHOLD = 10000, NONMAX_SUPPRESSION=10001, FAST_N=10002,
    };
    CV_WRAP static Ptr<FastFeatureDetector> create( 
int threshold=10,                                                    bool nonmaxSuppression=true,
int type=FastFeatureDetector::TYPE_9_16 );
    CV_WRAP virtual void setThreshold(int threshold) = 0;
    CV_WRAP virtual int getThreshold() const = 0;
    CV_WRAP virtual void setNonmaxSuppression(bool f) = 0;
    CV_WRAP virtual bool getNonmaxSuppression() const = 0;
    CV_WRAP virtual void setType(int type) = 0;
    CV_WRAP virtual int getType() const = 0;
};
           

参数说明: Ptr<FastFeatureDetector> create( int threshold=10, bool nonmaxSuppression=true,

                                 int type=FastFeatureDetector::TYPE_9_16 );

  threshold是指比较时边缘轨迹点和中心点的差值,也就是第三步的阈值t, nonmaxSuppression代表是否使用第五步非极大值抑制,如果发现fast检测的结果有聚簇情况,那么可以考虑采用,第三个参数type的取值来自于FastFeatureDetector枚举,有如下取值:

  1. TYPE_5_8 从轨迹中取8个点,当有5个点满足条件,就是特征点.
  2. TYPE_7_12 取轨迹12个点,7个满足条件,就是特征点.
  3. TYPE_9_16 取轨迹16个点,当9个满足条件,就是特征点.

  综上所述我们可以看出,FAST检测算法没有多尺度的问题,所以计算速度相对较快,但是当图片中的噪点较多的时候,会产生较多的错误特征点,健壮性并不好,并且, 算法的效果还依赖于一个阈值t。而且FAST不产生多尺度特征而且FAST特征点没有方向信息,这样就会失去旋转不变性.但是在要求实时性的场合,比如视频监控的物体识别,是可以使用的.

 实例:

#include <opencv2/opencv.hpp>
#include<opencv2/features2d.hpp>
using namespace cv;
using namespace std;

int thre = 40;
Mat src;
void trackBar(int, void*);

int main(int argc, char** argv)
{
    src = imread("E:/image/image/house2.jpg"); 
    if (src.empty())
    {
        printf("can not load image \n");
        return -1;
    }
    namedWindow("input",WINDOW_AUTOSIZE);
    imshow("input", src);  

    namedWindow("output",WINDOW_AUTOSIZE);
    createTrackbar("threshould", "output", &thre,255, trackBar);
    cvWaitKey(0);  
    return 0;
}

void trackBar(int, void*)
{
    std::vector<KeyPoint> keypoints;
    Mat dst = src.clone();
    Ptr<FastFeatureDetector> detector = FastFeatureDetector::create(thre);
    detector->detect(src,keypoints);
    drawKeypoints(dst, keypoints, dst, Scalar::all(-1), DrawMatchesFlags::DRAW_OVER_OUTIMG);  
    imshow("output", dst);  
}
           

结果:

OpenCV3学习(11.5) FAST特征检测器FastFeatureDetector简介

from:https://blog.csdn.net/akadiao/article/details/79189599