Fast检测角点算法

1.角点定义

  角点是一种局部特征,具有旋转不变性和不随光照条件变化而变化的特点,一般将图像中曲率足够高或者曲率变化明显的点作为角点。检测得到的角点特征通常用于图像匹配、目标跟踪、运动估计等方面。

2.Fast检测角点

1)基本思想

  E.Rosten和T.Drummond两位大佬在06年一篇文章中提出了FAST特征算法,基本思想十分简单:以某个像素点为圆心,某半径的圆周上其他像素点与圆心像素点特性差异达到某种标准时即认为该点就是角点。

2)数学模型

  

  经过测试发现,选取的圆形半径为3时可以兼顾检测结果和效率。如上图所示,点p与半径为3的圆周上的16个像素点比较其灰度差,若灰度差绝对值大于某阈值的点数超过设定数目(一般可以取9/10/11/12),则认为该点是角点。

使用小技巧加速该算法,这里取设定数目为12。

  (1)判断点1和点9灰度值与点p差值绝对值是否都大于阈值,如果是则继续;否则pass该点

(2)判断点1、点5、点9、点13四点与点p灰度值差值大于阈值的数目是否大于2,如果是则继续;否则pass该点

(3)判断圆周上16点与点p灰度值差值大于阈值的数目是否不小于12,如果是则认为该点是候选点;否则pass该点

  对图像中所有像素点进行上述操作后,得到候选点点集。通常使用非极大值抑制过滤局部非极大值点,在这之前需要先计算各候选点的score,score就定义为16个点与中心点灰度值差值的绝对值总和

3.opencv实现

个人使用vs2012+opencv2.4.13作为开发环境,具体实现如下

  1 #include <iostream>
  2 #include <core/core.hpp>
  3 #include <highgui/highgui.hpp>
  4 #include <imgproc/imgproc.hpp>
  5 #include <features2d/features2d.hpp>
  6
  7 using namespace std;
  8 using namespace cv;
  9
 10
 11 int getSum(uchar *p, int length)
 12 {
 13     int sum = 0;
 14     for(int i=0;i<length; i++)
 15     {
 16         sum += *(p+i);
 17     }
 18     return sum;
 19 }
 20
 21 int main(int argc, char* argv[])
 22 {
 23     /* 1.读入图像 */
 24     Mat image = imread("../church01.jpg", 0);
 25     if(!image.data)
 26         return 0;
 27
 28     namedWindow("Original Image");
 29     imshow("Original Image", image);
 30
 31     Mat fastImg(image.size(), CV_8U, Scalar(0));//用于保存Fast特征点候选点
 32     Mat fastScore(image.size(), CV_32F, Scalar(0));//用于计算候选点score
 33     vector<Point> points;
 34     int rows, cols, threshold;
 35     rows = image.rows;
 36     cols = image.cols;
 37     threshold = 50;
 38
 39     /* 2.检测Fast特征点 */
 40     for(int x = 3; x < rows - 3; x++)
 41     {
 42         for(int y = 3; y < cols - 3; y++)
 43         {
 44             uchar delta[16] = {0};
 45             uchar diff[16] = {0};
 46             delta[0] = (diff[0] = abs(image.at<uchar>(x,y) - image.at<uchar>(x, y-3))) > threshold;
 47             delta[8] = (diff[8] = abs(image.at<uchar>(x,y) - image.at<uchar>(x, y+3))) > threshold;
 48             if(getSum(delta, 16) == 0)
 49                 continue;
 50             else
 51             {
 52                 delta[12] = (diff[12] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-3, y))) > threshold;
 53                 delta[4] = (diff[4] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+3, y))) > threshold;
 54                 if(getSum(delta, 16) < 3)
 55                     continue;
 56
 57                 else
 58                 {
 59                     delta[1] = (diff[1] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+1, y-3))) > threshold;
 60                     delta[2] = (diff[2] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+2, y-2))) > threshold;
 61                     delta[3] = (diff[3] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+3, y-1))) > threshold;
 62
 63                     delta[5] = (diff[5] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+3, y+1))) > threshold;
 64                     delta[6] = (diff[6] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+2, y+2))) > threshold;
 65                     delta[7] = (diff[7] = abs(image.at<uchar>(x,y) - image.at<uchar>(x+1, y+3))) > threshold;
 66
 67                     delta[9] = (diff[9] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-1, y+3))) > threshold;
 68                     delta[10] = (diff[10] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-2, y+2))) > threshold;
 69                     delta[11] = (diff[11] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-3, y+1))) > threshold;
 70
 71                     delta[13] = (diff[13] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-3, y-1))) > threshold;
 72                     delta[14] = (diff[14] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-2, y-2))) > threshold;
 73                     delta[15] = (diff[15] = abs(image.at<uchar>(x,y) - image.at<uchar>(x-1, y-3))) > threshold;
 74
 75                     if(getSum(delta, 16) >= 12)
 76                     {
 77                         points.push_back(Point(y,x));
 78                         fastScore.at<float>(x,y) = getSum(diff, 16);
 79                         fastImg.at<uchar>(x,y) = 255;
 80                     }
 81                 }
 82             }
 83         }
 84
 85     }
 86
 87     vector<Point>::const_iterator itp = points.begin();
 88     while(itp != points.end())
 89     {
 90         circle(image, *itp, 3, Scalar(255), 1);
 91         ++itp;
 92     }
 93     //未进行非极大值抑制之前的特征点检测结果
 94     namedWindow("Fast Image");
 95     imshow("Fast Image", image);
 96
 97     /* 3.对特征点候选点进行非极大值抑制 */
 98     image = imread("../church01.jpg", 0);
 99     Mat dilated(fastScore.size(), CV_32F, Scalar(0));
100     Mat localMax;
101     Mat element(7, 7, CV_8U, Scalar(1));
102     dilate(fastScore, dilated, element);
103     compare(fastScore, dilated, localMax, CMP_EQ);
104     bitwise_and(fastImg, localMax, fastImg);
105
106     for(int x = 0;x < fastImg.cols; x++)
107     {
108         for(int y = 0; y < fastImg.rows; y++)
109         {
110             if(fastImg.at<uchar>(y,x))
111             {
112                 circle(image, Point(x,y), 3, Scalar(255), 1);
113
114             }
115         }
116     }
117     //进行非极大值抑制之后的特征点检测结果
118     namedWindow("Fast Image2");
119     imshow("Fast Image2", image);
120
121     waitKey();
122     return 0;
123 }

  代码运行结果如下,比较第2/3张图可以发现,非极大值抑制具有过滤掉局部区域中非极大值角点的作用。

4.算法小结

该算法思想简单,运算量很小,适合实时检测方面的应用。不过也有缺点,主要表现为对于边缘点与噪点区分能力不强,当然后面也有很多人在此基础上加以改进提高算法的稳定性。

5.参考文献

[1]《opencv2计算机视觉编程手册》

[2]【特征检测】FAST特征检测算法(http://blog.csdn.net/hujingshuang/article/details/46898007)

时间: 2024-11-05 18:44:51

Fast检测角点算法的相关文章

图像特征检测之Harris角点算法

        图像检测是图像分割,图像识别的基础,也是不可缺少的关键.在视觉计算理论框架中,抽取二维图像的边缘.角点.纹理等基本特征,是整个框架的第一步:本文章对Harris角点算法做了比较详细的理论介绍以及相关实现. Part One:角点类型介绍 在现实世界中,角点对应于物体的拐角,道路的十字路口.丁字路口等.从图像分析的角度来定义角点可以有以下两种定义: 角点可以是两个边缘的角点: 角点是邻域内具有两个主方向的特征点                                    

联合人脸检测、校准算法介绍

联合人脸检测.校准算法介绍 人脸检测(detection)在opencv中早就有直接能拿来用的haar分类器,基于Viola-Jones算法.但是毕竟是老掉牙的技术,Precision/Recall曲线渣到不行,在实际工程中根本没法给boss看,作为MSRA脑残粉,这里介绍一种MSRA在14年的最新技术:下载   [ECCV 2014] Joint Cascade Face Detection and Alignment.这篇文章直接在30ms的时间里把detection和alignment都给

基于人体部件小边特征的多行人检测和跟踪算法

基于人体部件小边特征的多行人检测和跟踪算法 detection tracking edgelet feature multiple occluded human Bayesian combination 读"B. Wu, R. Nevatia. Detection and tracking of multiple, partially occluded humans by Bayesian combination of edgelet based part detectors[J],IJCV,7

Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理

1.1. 图像边缘一般都是通过对图像进行梯度运算来实现的1 1.2. Remark: 1 1.3.  1.失焦检测. 衡量画面模糊的主要方法就是梯度的统计特征,通常梯度值越高,画面的边缘信息越丰富,图像越清晰.1 1.4. 利用边缘检测 ,模糊图片边缘会较少2 1.5. 通过dct比较.Dct分离出的低频信号比较2 1.6. 参考资料2 1.1. 图像边缘一般都是通过对图像进行梯度运算来实现的 1.2. Remark:   1)肉眼可以分辨以上五幅图像的质量排名为:img42 > img81 >

【转】 运动目标检测跟踪主流算法

不全,需要慢慢补充 一.运动目标检测 (一)背景差 1.帧差 2.GMM 等 背景减算法可以对背景的光照变化.噪声干扰以及周期性运动等进行建模,在各种不同情况下它都可以准确地检测出运动目标.因此对于固定摄像头的情形,目前大多数的跟踪算法中都采用背景减算法来进行目标检测.背景减算法的局限性在于它需要一个静态的固定摄像头. (二)运动场 光流法 光流估计的方法都是基于以下假设:图像灰度分布的变化完全是目标或者场景的运动引起的,也就是说,目标与场景的灰度不随时间变化.这使得光流方法抗噪声能力较差,其应

matlab工具箱之人眼检测+meanshift跟踪算法--人眼跟踪

Viola-Jones 人眼检测算法+meanshift跟踪算法 这次的代码是对视频中的人眼部分进行检测加跟踪,检测用的是matlab自带的人眼检测工具箱 下面是matlab官网介绍这个算法的一些东西: http://cn.mathworks.com/help/vision/examples/face-detection-and-tracking-using-camshift.html?searchHighlight=Viola-Jones http://cn.mathworks.com/hel

线段余弦角+凸包算法

/// /// 根据余弦定理求两个线段夹角 /// /// 端点 /// start点 /// end点 /// double Angle(PointF o, PointF s, PointF e) { double cosfi = 0, fi = 0, norm = 0; double dsx = s.X - o.X; double dsy = s.Y - o.Y; double dex = e.X - o.X; double dey = e.Y - o.Y; cosfi = dsx * de

opencv目标检测之canny算法

canny canny的目标有3个 低错误率 检测出的边缘都是真正的边缘 定位良好 边缘上的像素点与真正的边缘上的像素点距离应该最小 最小响应 边缘只能标识一次,噪声不应该标注为边缘 canny分几步 滤掉噪声 比如高斯滤波 计算梯度 比如用索贝尔算子算出梯度 非极大值抑制 上一步算出来的边缘可能比较粗糙,假设边缘是一条很细的线的话,上面处理完的结果你可以理解为得到一条比较粗的线条,所谓非极大值抑制,就是要在局部像素点中找到变换最剧烈的一个点,这样就得到了更细的边缘. 双阈值检测和连接边缘 前面

Atitit 图像清晰度 模糊度 检测 识别 评价算法 源码实现attilax总结

1.1. 原理,主要使用像素模糊后的差别会变小1 1.2. 具体流程1 1.3. 提升性能 可以使用采样法即可..1 1.4. 实现代码1 1.1. 原理,主要使用像素模糊后的差别会变小 通过计算横向前后俩点像素的差异..然后累加即可.. 1.2. 具体流程 图片灰度化,这样可以只保留hsv分量了...然后读取v分量,就是明亮度了.. Hs色相和饱和度全部去除了..   比较v分量的差异即可.. 1.3. 提升性能 可以使用采样法即可.. 1.4. 实现代码 package com.attila