生活随笔
收集整理的這篇文章主要介紹了
FAST特征点检测
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
簡介
? ? ? ? 在局部特征點檢測快速發展的時候,人們對于特征的認識也越來越深入,近幾年來許多學者提出了許許多多的特征檢測算法及其改進算法,在眾多的特征提取算法中,不乏涌現出佼佼者。
? ? ? ? 從最早期的Moravec,到Harris,再到SIFT、SUSAN、GLOH、SURF算法,可以說特征提取算法層出不窮。各種改進算法PCA-SIFT、ICA-SIFT、P-ASURF、R-ASURF、Radon-SIFT等也是搞得如火如荼,不亦樂乎。上面的算法如SIFT、SURF提取到的特征也是非常優秀(有較強的不變性),但是時間消耗依然很大,而在一個系統中,特征提取僅僅是一部分,還要進行諸如配準、提純、融合等后續算法。這使得實時性不好,降系了統性能。
? ? ? ? Edward Rosten和Tom Drummond兩位大神經過研究,于2006年在《Machine learning for high-speed corner detection》中提出了一種FAST特征點,并在2010年稍作修改后發表了《Features From Accelerated Segment Test》,簡稱FAST。注意:FAST只是一種特征點檢測算法,并不涉及特征點的特征描述。
FAST詳解
FAST特征的定義
? ? ? FAST的提出者Rosten等將FAST角點定義為:若某像素與其周圍鄰域內足夠多的像素點相差較大,則該像素可能是角點。
FAST算法的步驟
1、上圖所示,一個以像素p為中心,半徑為3的圓上,有16個像素點(p1、p2、...、p16)。
2、定義一個閾值。計算p1、p9與中心p的像素差,若它們絕對值都小于閾值,則p點不可能是特征點,直接pass掉;否則,當做候選點,有待進一步考察;
3、若p是候選點,則計算p1、p9、p5、p13與中心p的像素差,若它們的絕對值有至少3個超過閾值,則當做候選點,再進行下一步考察;否則,直接pass掉;
4、若p是候選點,則計算p1到p16這16個點與中心p的像素差,若它們有至少9個超過閾值,則是特征點;否則,直接pass掉。
5、對圖像進行非極大值抑制:計算特征點出的FAST得分值(即score值,也即s值),判斷以特征點p為中心的一個鄰域(如3x3或5x5)內,計算若有多個特征點,則判斷每個特征點的s值(16個點與中心差值的絕對值總和),若p是鄰域所有特征點中響應值最大的,則保留;否則,抑制。若鄰域內只有一個特征點(角點),則保留。得分計算公式如下(公式中用V表示得分,t表示閾值):
? ? ? ?上面是FAST-9,當然FAST-10、FAST-11、FAST-12也是一樣的,只是步驟4中,超過閾值的個數不一樣。FAST算法實現起來簡單,尤其是以速度快著稱。
? ? ? ?以上便是FAST特征檢測的過程,清晰明了,而對于角點的定義也是做到了返璞歸真,大師就是大師,還原本質的能力很強,估計以前這種簡單想法被很多人忽略了。
實驗
opencv代碼
[cpp]?view plain
?copy #include?<opencv2/core/core.hpp>?? #include?<opencv2/features2d/features2d.hpp>?? #include?<opencv2/highgui/highgui.hpp>?? #include?<cv.h>?? #include?<vector>?? ?? using?namespace?cv;?? using?namespace?std;?? ?? int?main()?? {?? ????Mat?frame=imread("lena.jpg",?1);?? ????double?t?=?getTickCount();?? ????std::vector<KeyPoint>?keyPoints;?? ????FastFeatureDetector?fast(50);????? ?? ????fast.detect(frame,?keyPoints);?? ????drawKeypoints(frame,?keyPoints,?frame,?Scalar(0,0,255),?DrawMatchesFlags::DRAW_OVER_OUTIMG);?? ?????? ????t?=?((double)getTickCount()?-?t)/getTickFrequency();?? ????cout<<"算法用時:"<<t<<"秒"<<endl;?? ?? ????imshow("FAST特征點",?frame);?? ????cvWaitKey(0);?? ?? ????return?0;?? }??
輸出結果:
MATLAB代碼
再上一個自己編寫的MATLAB代碼,沒有進行非極大值抑制,效果不及opencv,而且檢測出的角點有一定的出入,應該是opencv內部做了一定的優化。
[cpp]?view plain
?copy clear?all;?? close?all;?? %%?? pic=imread('lena.jpg');?? img=pic;?? [M?N?D]=size(pic);?? if?D==3?? ????pic=rgb2gray(pic);?? end?? %%?? mask=[0?0?1?1?1?0?0;...?? ??????0?1?0?0?0?1?0;...?? ??????1?0?0?0?0?0?1;...?? ??????1?0?0?0?0?0?1;...?? ??????1?0?0?0?0?0?1;...?? ??????0?1?0?0?0?1?0;...?? ??????0?0?1?1?1?0?0];?? mask=uint8(mask);?? threshold=50;?? figure;imshow(img);title('FAST角點檢測');hold?on;?? tic;?? for?i=4:M-3?? ????for?j=4:N-3%若I1、I9與中心I0的差均小于閾值,則不是候選點?? ????????delta1=abs(pic(i-3,j)-pic(i,j))>threshold;?? ????????delta9=abs(pic(i+3,j)-pic(i,j))>threshold;?? ????????if?sum([delta1?delta9])==0?? ????????????continue;?? ????????else?? ????????????delta5=abs(pic(i,j+3)-pic(i,j))>threshold;?? ????????????delta13=abs(pic(i,j-3)-pic(i,j))>threshold;?? ????????????if?sum([delta1?delta9?delta5?delta13])>=3?? ????????????????block=pic(i-3:i+3,j-3:j+3);?? ????????????????block=block.*mask;%提取圓周16個點?? ????????????????pos=find(block);?? ????????????????block1=abs(block(pos)-pic(i,j))/threshold;?? ????????????????block2=floor(block1);?? ????????????????res=find(block2);?? ????????????????if?size(res,1)>=12?? ????????????????????plot(j,i,'ro');?? ????????????????end?? ????????????end?? ????????end?? ????end?? end?? toc;?? %%??
輸出結果:
參考文獻
1、Machine learning for high-speed corner detection[J],2006.
2、Features From Accelerated Segment Test[J],2010.
3、基于自適應閾值的FAST特征點提取算法[J],2013
總結
以上是生活随笔為你收集整理的FAST特征点检测的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。