FAST特征点检测的matlab源码实现

  • 1. 简介
  • 2. FAST的原理介绍
    • 2.1 特征点检测
    • 2.2 极值点抑制
  • 3. matlab源码实现
  • 4. 结果展示

1. 简介

Features From Accelerate Segment Test (FAST) 是一种常用的特征点检测方法。它具有速度快,特征点数量可控的优点。由FAST衍生出来的Oriented FAST and Rotated Brief (ORB)描述子也常常被应用于实时性较强的应用中。OPENCV中有关于FAST实现的源代码,在matlab中也可以直接使用detectFASTFeatures()函数提取FAST特征点。但是matlab中的我们无法看到FAST的实现方式,也无法对其进行优化改进。本文提供了一个关于FAST的matlab版本,帮助那些喜欢matlab的朋友们学习参考。为了让整个博文具有完整性,我会简单地介绍一下FAST的实现原理,便于与后面matlab的源码对应,方便读者的理解与使用,如果熟悉FAST原理的小伙伴可以直接跳过原理部分讲解,阅读源代码,也可以点击下面的链接下载我写的FAST的matlab源码。
https://download.csdn.net/download/qq_35721810/10867848

2. FAST的原理介绍

和大部分特征点提取方法一样,FAST特征点提取主要分为两个步骤:

  1. 特征点检测
  2. 极值点抑制

2.1 特征点检测

从原理的角度讲,FAST并不像如Harris,SIFT,SURF那样具有非常严格的数学背景,它更像是一种基于主观经验判断的方法。其核心思想就是找到一些比周围点的浅或者深的点作为特征点,如图1所示

图1. FAST特征点提取示意图

FAST特征点检测的方法,就是比较检测点的灰度值P0与检测点附近的点的灰度值P1,P2,…,P16之间的关系。这里P1,P2,…,P16是以P0为中心3为半径的Bresenham圆的圆周上点的灰度。读者可以根据自己的需要适当地改变Bresenham圆的半径。
刚才提到的FAST特征点提取是要找到相比周围点浅或者深的点,为了减小图像噪声的干扰,FAST作者提出的方法是将P1,P2,…,P16看成一个循环列表,如果他们中有连续n个点大于P0 + threshold或者连续n个点小于P0 - threshold,则认为该检测点是“可能”的特征点(后面要进行极值点抑制,被抑制的点会从特征点的候选名单里剔除,为了便于表达,下文中我就不严格区别特征点的candidate和真正的特征点)。这里的threshold主要还是为了防止由于图像噪声引起的检测误差,可以是一个相对于P0的比例,也可以是一个具体的灰度值,对于半径为3的Bresenham圆一般n可以取9或者12(大于圆周上一般的点数即可)。下面举几个特征点与非特征点的例子帮助大家理解。

图2. 连续9个及以上的点大于待检测点。该检测点为特征点

假设图2中,检测点的灰度值P0 = 100,用橙色表示,threshold = 10,n = 9,红色的点代表灰度值大于P0 + threshold (110)的点,黄色代表灰度值小于P0 - threshold(90)的点,灰色代表灰度值介于90到110之间的点。从图中可以看到由于P13,P14,P15,P16,P1,P2,P3,P4,P5,P6这10个连续的点都大于P0 + threshold (110),并且连续的点数大于等于n = 9,因此该检测点为特征点。同样的方法可以得到图3中有连续的9个点(P1到P9)小于P0 - threshold(90),因此该检测点也为特征点。

图3. 连续9个及以上的点小于待检测点。该检测点为特征点

下面给出一个反例。如图4所示,虽然P0周围的点都满足|Pi-P0|>thershold,但是没有连续的n个点大于P0+threshold或者没有连续的n个点小于P0-threshold,因此该检测点不是特征点。需要指出的是作者的原文的表述中有一定的奇异性。“n” contiguous pixels out of the 16 need to be either above or below P0 by the threshold, if the pixel needs to be detected as an interest point .[1] 这里容易误解成有n个连续的点满足 |Pi-P0|>thershold,可以认为是特征点。但是我在仔细研读赵春江解读的opencv的FAST源码后[2],发现作者的本意是要求这n个连续的点必须都大于P0+threshold,或者都小于P0-threshold,才满足特征点判定条件。(当然特征点检测算法是人定义的,并没有严格的对与错之分,这里我只是尽可能地还原作者的本意。)

图4. 非特征点的案例

这里有一个问题:为什么要与圆周上的点的灰度值做比较?而不是直接与检测点相邻的每一个点进行比较呢?我认为可能是FAST的作者希望能予以特征点一些相对冗余的包容度(这一点恰好与基于一阶导数差分或者二阶导数差分判断的特征点方法相反)。图像特征点其实并不是一个非常精确的概念,随着光影,摄像头焦距的变化,特征点很可能会在原本位置附近“浮动”,因此跳开检测点相邻区域,只比较圆周上的点,可以忽略特征点这种浮动带来的影响。如果相邻区域出现多个特征点可以通过极值点抑制的方法来剔除。
上述过程是用于判定待定点是否为特征点的方法,根据FAST特征点的定义判定一个检测点是否为特征点,需要依次查看周围16个点的连续9个点是否大于P0 + threshold以及小于P0 - threshold的情况,每一个检测点最糟情况是进行2169次判断。如果这样的操作需要遍历全图每一个点,显然计算量也不小,FAST的作者提出了一个“偷懒”的方法。即优先判断上下左右四个点P1,P5,P9,P13。并且作者还引入了一个阈值列表来加速该过程的判断,具体细节可以参考赵春江解读的opencv的FAST源码[2]。不过需要指出的是作者的这种优化思想主要是针对CPU逐点计算的优化思想(大部分点不是特征点),对于FPGA,GPU等并行加速设计时,if语句的判断操作并不适用。下面的matlab实现中,为了让代码看起来更容易理解,我只注重原理的实现,并不追求时效性。

2.2 极值点抑制

极值点抑制是指把上述过程中提取出来可能的特征点,通过一定的逻辑进行筛选。留下那些更具有代表性的点。Harris,SIFT,和SURF的极值点抑制是利用Hessian矩阵的行列式计算特征点边界特性,边界特性强的点其特征相似度较大,会被剔除。
FAST方法的特征提取相对更加显获一些。FAST的作者把“更具代表性的点”理解为在一定区域内相比与周围环境更浅或者更深的点。
如何让算法找到这些灰度更浅或者更深的点?首先就必须给这些特征点进行打分,其次在一定的区域内进行筛选(分数最高的留下,分数低的淘汰)。
第一,FAST的打分方法是改变threshold,找到最大的一个threshold使该点恰好满足特征点判定的条件,即满足n个以上连续的点大于P0 + threshold,或者P0-threshold*。这个threshold即为该点的得分值V = threshold。如果图像的像素是UINT类型,V一定为圆周上某个与特征点差值的绝对值减一,即V=|Pk-P0|-1,k为1到16中的某一个点。算法实现过程中只需要遍历这16个点找到满足条件的最大的thershold*即可。

图5. 特征点打分

假设特征点的灰度值P0 = 100,threshold = 10,当threhsold* = 11时,灰度值为111的点不再满足大于P0 + threshold* 的条件。但是还是有9个连续的点满足大于P0 + threshold*。当threshold* = 14时,该检测点恰好不满足特征点的判定条件,因此threshold*的最大值为V = 14 -1 = 13。我们可以遍历整张图片如果该点不是特征点V(i,j) = 0,如果该点为特征点V(i,j) >= threshold。
第二,极值点抑制方法。刚才的方法可以得到一个特征点打分V(i,j)的map,遍历每一个可能的特征点,如果该特征点的V不是在以它为中心3x3的区域内最大值,则删除该点,如果是则保留。

3. matlab源码实现

matlab的源代码可以通过以下的链接下载:
https://download.csdn.net/download/qq_35721810/10867848
文件中有一张png的测试图片和三个.m文件。如下图所示

图5 文件说明

matlabFast.m是使用matlab中自带的detectFASTFeatures()函数提取的FAST特征点,可以用于对比实验。myFAST.m是FAST特征点检测的实现。testMyFAST.m是FAST检测的一个用例。读者可以直接运行testMyFAST.m看到FAST源码的实现结果。

下面我主要针对myFAST.m进行解读。
myFAST是一个实现FAST特征点检测的类,这个类中有四个properties

    propertiesnumInChain = 12;threshold = 0.3;img;featureMap;end

numInChain代表连续点的数量,即上文中提到的n。threshold代表判断特征点超出的阈值,这里我使用的是比例。img是图像,下面初始化的时候,我会把原始图像转成灰度图并保存在img中。featureMap就是上文提到的V,它是一个与原图一样大小的map,如果该点不是特征点featureMap(i, j) = 0,如果该点是特征点featureMap(i, j) 即为该点的打分值。
methods中的第一个函数为myFAST的构造函数。

        function obj = myFAST(img_)if ndims(img_) == 3obj.img = rgb2gray(img_);elseobj.img = img_;endend

img_为原始图像,构造函数把原始图像转为灰度图,并存在类的img中。
函数operate()是FAST实现的主要函数。

        % FAST的实现function [corners] = operate(obj)corners = []; % 特征点tempCorners = []; % 特征点的candidate[m, n] = size(obj.img);obj.featureMap = zeros(m, n); %特征点的打分值,如果不是特征点打分为0for i = 4:m-4for j = 4:n-4% p0为检测点p0 = obj.img(i,j);% 依次提取当前点半径为3的Bresenham圆圆周上的点,检测点正上方为p(1)p = [];p(end + 1) = obj.img(i - 3 ,j    );  %p1p(end + 1) = obj.img(i - 3 ,j + 1);  %p2p(end + 1) = obj.img(i - 2 ,j + 2);  %p3p(end + 1) = obj.img(i - 1 ,j + 3);  %p4p(end + 1) = obj.img(i     ,j + 3);  %p5p(end + 1) = obj.img(i + 1 ,j + 3);  %p6p(end + 1) = obj.img(i + 2 ,j + 2);  %p7p(end + 1) = obj.img(i + 3 ,j + 1);  %p8p(end + 1) = obj.img(i + 3 ,j    );  %p9p(end + 1) = obj.img(i + 3 ,j - 1);  %p10p(end + 1) = obj.img(i + 2 ,j - 2);  %p11p(end + 1) = obj.img(i + 1 ,j - 3);  %p12p(end + 1) = obj.img(i     ,j - 3);  %p13p(end + 1) = obj.img(i - 1 ,j - 3);  %p14p(end + 1) = obj.img(i - 2 ,j - 2);  %p15p(end + 1) = obj.img(i - 3 ,j - 1);  %p16thr = obj.threshold*p0;%判断该点是否为特征点的candidate%featureFlag = 1 代表周围有n个以上的点大于p0 + thr%featureFlag = 2 代表周围有n个以上的点小于p0 - thrfeatureFlag = FastFeaturePointDetect(p0,p,thr,obj.numInChain);if featureFlag == 1 || featureFlag == 2  %如果是特征点,计算特征点的打分值val = ExtremeSuppression(p0,p,thr, obj.numInChain,featureFlag);tempCorners(end + 1).x = j;tempCorners(end).y = i;tempCorners(end).val = val;obj.featureMap(i,j) = val;endendend%极值点抑制for k = 1:length(tempCorners)j = tempCorners(k).x;i = tempCorners(k).y;tempList(1) = obj.featureMap(i - 1,j - 1);tempList(2) = obj.featureMap(i - 1,j    );tempList(3) = obj.featureMap(i - 1,j + 1);tempList(4) = obj.featureMap(i    ,j - 1);tempList(5) = obj.featureMap(i    ,j + 1);tempList(6) = obj.featureMap(i - 1,j - 1);tempList(7) = obj.featureMap(i - 1,j    );tempList(8) = obj.featureMap(i - 1,j + 1);%如果特征点的打分值是附近3*3区域里最大的则将tempCorners(k)付给cornersif tempCorners(k).val > max(tempList)corners(end+1).x = tempCorners(k).x;corners(end).y = tempCorners(k).y;corners(end).val = tempCorners(k).val;endendendend
end

函数operate()中有两个大循环,第一个循环会遍历全图(由于Bresenham圆半径为3,因此中心点从(4,4)开始),依次判断图中每一个像素是否为特征点的candidate,如果是,则将该点的坐标保存下来,并且为该特征点打分,并且记录在featureMap中。第二个循环遍历每一个特征点的candidate,判断是否是3x3区域中打分值最大的。如果是,则保留存入corners里,如果不是,则删除。
第一个循环中有两个主要的函数: FastFeaturePointDetect()和ExtremeSuppression()。FastFeaturePointDetect()是用来判断该点是否为特征点;ExtremeSuppression()是用来给特征点打分的(这里名命为ExtremeSuppression极值点抑制,可能写代码时有欠考虑,但其实这个函数的作用只是为特征点打分,抑制是operate()的第二个大循环实现的)

%判断该点是否为特征点的candidate
function flag = FastFeaturePointDetect(p0,p,thr, numInChain)
flag = 0;
% 遍历16个点,看是否有numInChain个点大于p0 + thr
% 循环列表的index = mod(k-1,length(p))+1
for i = 1:16if p(i) - p0 > thrcounter = 1;for j = 1:numInChain - 1k = i + j;if p(mod(k-1,length(p))+1) - p0 > thrcounter = counter + 1;elsebreak;endendif counter == numInChainflag = 1;returnendelsecontinue;end
end% 遍历16个点,看是否有numInChain个点小于p0 - thr
for i = 1:16if p0 - p(i) > thrcounter = 1;for j = 1:numInChain - 1k = i + j;if  p0 - p(mod(k-1,length(p))+1) > thrcounter = counter + 1;elsebreak;endendif counter == numInChainflag = 2;returnendelsecontinue;end
endend

下面一次给大家讲解上述的两个函数。首先FastFeaturePointDetect(p0,p,thr, numInChain)的输入p0代表待检测点,即上文中的P0,p代表p0周围的16个点,thr代表threshold,numInChain代表n个连续的点数。这个函数中一共有两个二个循环,第一个循环用来判断是否有numInChain个点大于p0 + thr;第二个循环用来判断是否有numInChain个点小于p0 - thr。这里为了让实现更加简单易懂,我并没有严格按照FAST作者推荐的“偷懒”方法去实现(我猜用matlab的朋友们并不关心算法的运行速度)。这里有一个使用循环列表的小技巧,在matlab中循环列表的index可以根据index = mod(k-1,length( p ))+1来实现,用一个例子说明,假设length( p ) = 16,k为17,k此时已经超出了p的长度,可以计算出mod(17 - 1,16)+1 = 1,因此index正好指向p的第一元素。这里的featureFlag为该函数的输出结果,如果结果为1代表有numInChain个点大于p0 + thr,如果结果为2代表有numInChain个点小于p0 - thr,如果结果为0代表该点不是特征点。

%给特征点打分
function [val] = ExtremeSuppression(p0, p,thr, numInChain,featureFlag)
N = length(p);
if featureFlag == 1d = p - double(p0);
elsed = double(p0) - p;
enda0 = thr;%打分的结果一定是d(1)到d(16)中的一个,遍历16次找出最大的满足条件的d(k)for i = 1:16a = min([d(mod(i,N)+1),d(mod(i+1,N)+1),d(mod(i+2,N)+1)]);        if a < a0continue;        end        for j = 4:numInChain-1a = min(a,d(mod(i+j-1,N)+1));enda0 = max(a0,min(a, d(mod(i-1,N)+1) ));a0 = max(a0, min(a, d(mod(i-1,N)+1) ));endval = a0 -1;
end

特征点的打分用ExtremeSuppression(p0, p,thr, numInChain,featureFlag)函数实现。它的基本思想就是打分值一定是这16个点中其中一个,因此遍历这16个点,如果这个点之后的连续9个点中最小的点,大于thr,则将其记录下来。满足上面条件最大的点的灰度值减一,即为所求结果。

4. 结果展示

最后,是我的算法和matlab自带函数的效果对比图,总体效果上看还是差不多的,但是个人感觉matlab里detectFASTFeatures()的特征点提取还是比我自己实现的效果要好一点吧,可能里面的极值点抑制与我的方法有一些差异。

图6. myFAST的实现结果


图7. matlab函数的实现结果

[1]: Features from Accelerated Segment Test, Deepak Geetha Viswanathan
[2]: https://blog.csdn.net/zhaocj/article/details/40301561

FAST特征点检测的matlab实现相关推荐

  1. OpenCV学习笔记(四十六)——FAST特征点检测features2D OpenCV学习笔记(四十七)——VideoWriter生成视频流highgui OpenCV学习笔记(四十八)——PCA算

    OpenCV学习笔记(四十六)--FAST特征点检测features2D 特征点检测和匹配是计算机视觉中一个很有用的技术.在物体检测,视觉跟踪,三维常年关键等领域都有很广泛的应用.这一次先介绍特征点检 ...

  2. 特征点匹配——FAST特征点检测

    FAST算法是ECCV 2006上发表的Machine learning for high-speed corner detection上提出的,从论文名字中就可以看出,这是一种检测特征点的方法. 一 ...

  3. FAST特征点检测算法

    一.FAST算法简介   如今,特征点检测的算法有很多,从最初的Moravec,到Harris,再到SIFT.SUSAN.GLOH.SURF算法,可以说特征点提取算法层出不穷.各种改进算法PCA-SI ...

  4. 【特征检测】FAST特征点检测算法

    简介 在局部特征点检测快速发展的时候,人们对于特征的认识也越来越深入,近几年来许多学者提出了许许多多的特征检测算法及其改进算法,在众多的特征提取算法中,不乏涌现出佼佼者. 从最早期的Moravec,到 ...

  5. C++OpenCV矩形的角点检测与坐标提取,基于fast特征点

    目的:提取图片中某个矩形的四个角点的坐标 方法:采用非极大值抑制的fast特征点检测 流程: 图像滤波(可选) fast角点检测 自己设定矩形大致范围 输出矩形角点坐标 程序: 主函数文件 #incl ...

  6. 【OpenCV-Python】——哈里斯/Shi-Tomas角检测FAST/SIFT/ORB特征点检测暴力/FLANN匹配器对象查找

    目录 前言: 1.角检测 1.1 哈里斯角检测 1.2 优化哈里斯角 1.3 Shi-Tomasi角检测 2.特征点检测 2.1 FAST特征点检测 2.2 SIFT特征检测 2.3 ORB特征检测 ...

  7. brisk matlab,opencv学习笔记三十七:BRISK特征点检测与匹配

    简介 BRISK算法是2011年ICCV上<BRISK:Binary Robust Invariant Scalable Keypoints>文章中,提出来的一种特征提取算法,也是一种二进 ...

  8. fast角点检测 java_米联客 ZYNQ/SOC 精品教程 S04-CH11 快速角点检测之硬件实现

    软件版本:VIVADO2017.4 操作系统:WIN10 64bit 硬件平台:适用米联客 ZYNQ系列开发板 米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!! ...

  9. 基于图像的三维重建——特征点检测与匹配(2)

    文章目录 前言 一.特征点检测 二阶的拉普拉斯高斯边缘提取算法(LOG) 尺度不变特征变换算法(SIFT) 加速稳健特征算法(SURF) Harris角点特征提取算子 加速分割测试特征提取(FAST) ...

最新文章

  1. Linux网络协议栈(四)——链路层(2)
  2. x轴z轴代表的方向图片_游戏中到底是Z轴朝上还是Y轴朝上?
  3. c语言注释参与程序设计的编译,提高C语言程序设计教学的有益探索
  4. flowable工作流 流程变量_互联网架构设计漫谈 (6)-90%的架构师都知道的工作流原理...
  5. 2007年IT技术走向何方 网络将再掀“酷”革命
  6. Java笔记(14):常用对象--正则表达式、GC
  7. Mybtis进行mysql数据库的修改表名操作
  8. 软件供应链安全现状分析与对策建议
  9. FFT蝶形算法的verilog实现专题——FFT的matlab到verilog转化过程——第1部分
  10. 基于javaweb+jsp的小蜜蜂扩音器网上商城系统(java+JSP+Servlet+JDBC+Ajax+mysql)
  11. php+剧影评系统 毕业设计-附源码140859
  12. Android | 安卓好用软件来袭,多御安全浏览器免费又强大
  13. h3c无线认证服务器,H3C无线路由器配置样例之无认证接入
  14. 想知道添加水印的软件哪个好?这2款软件简单又实用
  15. 如何运营一个微信公众号
  16. 格力2代,原厂固件hola1.2.2
  17. 参加“灵狐公司”的技术年会,感受最新MS OFFICE 2007的应用价值!
  18. WEB安全性测试测试用例(基础).doc
  19. 超级搞笑!笑到你肚子疼!!
  20. SpringMVC请求参数和路径变量

热门文章

  1. JQuery选择器之位置选择器
  2. 【电子学会】2019年03月图形化二级 -- 垃圾分类
  3. 中国新能源市场未来可期,零跑汽车将遥遥领先
  4. 程序员这个职业赚钱吗?能赚多少钱?
  5. 光伏农业崭露头角:农田变身太阳能发电场
  6. Oracle 给用户增加权限
  7. 基于华为设备的某大型企业网络规划与实施方案
  8. 一维数组倒序的几种思路
  9. 打印出所有的水仙花数
  10. css实现流星划过的效果