1.FAST(featuresfrom accelerated segment test)算法
http://blog.csdn.net/yang_xian521/article/details/7411438
特征點檢測和匹配是計算機視覺中一個很有用的技術。在物體檢測,視覺跟蹤,三維常年關鍵等領域都有很廣泛的應用。很多傳統的算法都很耗時,而且特征點檢測算法只是很多復雜圖像處理里中的第一步,得不償失。FAST特征點檢測是公認的比較快速的特征點檢測方法,只利用周圍像素比較的信息就可以得到特征點,簡單,有效。
FAST特征檢測算法來源於corner的定義,這個定義基於特征點周圍的圖像灰度值,檢測候選特征點周圍一圈的像素值,如果候選點周圍領域內有足夠多的像素點與該候選點的灰度值差別夠大,則認為該候選點為一個特征點。
其中I(x)為圓周上任意一點的灰度,I(p)為圓心的灰度,Ed為灰度值差得閾值,如果N大於給定閾值,一般為周圍圓圈點的四分之三,則認為p是一個特征點。
為了獲得更快的結果,還采用了額外的加速辦法。如果測試了候選點周圍每隔90度角的4個點,應該至少有3個和候選點的灰度值差足夠大,否則則不用再計算其他點,直接認為該候選點不是特征點。候選點周圍的圓的選取半徑是一個很重要的參數,這里我為了簡單高效,采用半徑為3,共有16個周邊像素需要比較。為了提高比較的效率,通常只使用N個周邊像素來比較,也就是大家經常說的FAST-N。我看很多文獻推薦FAST-9,作者的主頁上有FAST-9、FAST-10、FAST-11、FAST-12,大家使用比較多的是FAST-9和FAST-12。上個圖說明的更形象一些
OpenCV里對FAST的使用也非常簡單,先聲明一組特征點,構建FAST特征檢測,接下來調用detect函數檢測圖像中的特征點,最后把特征點繪制到圖片上。上代碼說的清楚些
Features From Accelerated Segment Test
1. Fast算法原理
博客中已經介紹了很多圖像特征檢測算子,我們可以用LoG或者DoG檢測圖像中的Blobs(斑點檢測),可以根據圖像局部的自相關函數來求得Harris角點(Harris角點),后面又提到了兩種十分優秀的特征點及它們的描述方法SIFT特征與SURF特征。
SURF特征算是為了提高運算效率對SIFT特征的一種近似,雖然在有些實驗環境中已經達到了實時,但是我們實踐工程應用中,特征點的提取與匹配只是整個應用算法中的一部分,所以我們對於特征點的提取必須有更高的要求,從這一點來看前面介紹的的那些特征點方法都不可取。
為了解決這個問題,Edward Rosten和Tom Drummond在2006年發表的“Machine learning for high-speedcorner detection[1]”文章中提出了一種FAST特征,並在2010年對這篇論文作了小幅度的修改后重新發表[2]。FAST的全稱為Features From Accelerated SegmentTest。Rosten等人將FAST角點定義為:若某像素點與其周圍領域內足夠多的像素點處於不同的區域,則該像素點可能為角點。
也就是某些屬性與眾不同,考慮灰度圖像,即若該點的灰度值比其周圍領域內足夠多的像素點的灰度值大或者小,則該點可能為角點。
2. FAST算法步驟
- 從圖片中選取一個像素$P$,下面我們將判斷它是否是一個特征點。我們首先把它的亮度值設為$I_p$。
- 設定一個合適的閾值$t$。
- 考慮以該像素點為中心的一個半徑等於3像素的離散化的Bresenham圓,這個圓的邊界上有16個像素(如圖1所示)。
圖1 FAST特征點示意圖
- 現在,如果在這個大小為16個像素的圓上有$n$個連續的像素點,它們的像素值要么都比$I_p + t$大,要么都比$I_p - t$小,那么它就是一個角點。(如圖1中的白色虛線所示)。$n$的值可以設置為12或者9,實驗證明選擇9可能會有更好的效果。
上面的算法中,對於圖像中的每一個點,我們都要去遍歷其鄰域圓上的16個點的像素,效率較低。我們下面提出了一種高效的測試(high-speed test)來快速排除一大部分非角點的像素。該方法僅僅檢查在位置1,9,5和13四個位置的像素,首先檢測位置1和位置9,如果它們都比閾值暗或比閾值亮,再檢測位置5和位置13。如果$P$是一個角點,那么上述四個像素點中至少有3個應該必須都大於$I_p+t$或者小於$I_p-t$,因為若是一個角點,超過四分之三圓的部分應該滿足判斷條件。
如果不滿足,那么$p$不可能是一個角點。對於所有點做上面這一部分初步的檢測后,符合條件的將成為候選的角點,我們再對候選的角點,做完整的測試,即檢測圓上的所有點。
上面的算法效率實際上是很高的,但是有點一些缺點:
- 當$n<12$時不能拒絕許多的候選點;
- 檢測出來的角點不是最優的,這是因為它的效率取決於問題的排序與角點的分布;
- 對於角點分析的結果被丟棄了;
- 多個特征點容易擠在一起。
4.非極大值抑制
從鄰近的位置選取了多個特征點是另一個問題,我們可以使用Non-Maximal Suppression來解決。
- 為每一個檢測到的特征點計算它的響應大小(score function)$V$。這里$V$定義為點$p$和它周圍16個像素點的絕對偏差的和。
- 考慮兩個相鄰的特征點,並比較它們的$V$值。
- $V$值較低的點將會被刪除。
5. OpenCV中進行FAST特征檢測
在OpenCV中進行FAST特征提取的函數為FAST。它一共有4個參數,第一個參數是輸入的圖像,第二個是返回的特征點,第三個是定義的閾值,第四個決定是否使用非極大值抑制。
void FAST(InputArray image,vector<KeyPoint>& keypoints,int threshold,boolnonmaxSuppression=true )
C++:void FASTX(InputArray image,vector<KeyPoint>& keypoints,int threshold,boolnonmaxSuppression, int type)
另外還有一個接口為FASTX,它提供了第五個參數type用來指定FAST檢測中像素鄰域圓的參數:TYPE_9_16、TYPE_7_12、TYPE_5_8。
6.總結
FAST算法比其他已知的角點檢測算法要快很多倍,但是當圖片中的噪點較多時,它的健壯性並不好,而且算法的效果還依賴於一個閾值$t$。
而且FAST不產生多尺度特征而且FAST特征點沒有方向信息,這樣就會失去旋轉不變性。
[1] Edward Rosten and Tom Drummond, “Machine learning for high speedcorner detection” in 9th European Conference on Computer Vision, vol. 1, 2006,pp. 430–443.
[2] Edward Rosten, Reid Porter, and Tom Drummond, “Faster and better: amachine learning approach to corner detection” in IEEE Trans. Pattern
Analysisand Machine Intelligence, 2010, vol 32, pp. 105-119.
在FAST特征提出之后,實時計算機視覺應用中特征提取性能才有顯著改善。目前以其高計算效率(computational performance)、高可重復性(high repeatability)成為計算機視覺領域最流行的角點檢測方法。
1997年,Simth提出了SUSAN角點檢測方法[1]。網址http://users.fmrib.ox.ac.uk/~steve/susan/.
在SUSAN方法的基礎上,2005年, Rosten在論文[2]中提出基於The segment test criterion的角點檢測方法,全稱“Features fromAccelerated Segment Test”,簡稱FAST。
2006
年,Rosten在[3]中使用機器學習對FAST的一些缺點進行改進,他的主頁http://www.edwardrosten.com/work/fast.html提供的FAST實現即基於此論文。后續在2009年提出性能增強(可重復性增強、計算效率下降)的FAST-ER[4]。
2010
年,Mair在ECCV會議論文[5]中提出AGAST特征。對FAST底層的the accelerated segment test進行改進,通過在擴展配置空間尋找最優決策樹,使用特定樹的組合獲得自適應並且通用的accelerated segment test。對FAST 9-16 detector提速約13%,對FAST 7-12 detector提速最高30%,對FAST 5-8 detector提速最高50%。AGAST項目網址http://www6.in.tum.de/Main/ResearchAgast.
2011
年,S. Leutenegger在BRISK描述子[6]中提出multi-scale AGAST detector, 並用實驗證明與SURF detector有等效的可重復性(equivalentrepeatability)。對Graffiti序列的第一幅圖檢測時間為17.20ms,約為SURF detector消耗時間的16%,SIFT detector消耗時間的1%.BRISK項目地址http://www.asl.ethz.ch/people/lestefan/personal/BRISK.
參考文獻:
[1]S. M. Simth, J. M. Brady, Susan - a new approach to low level imageprocessing. International Journal of Computer Vision 23, 1997.
[2]E. Rosten, T. Drummond, Fusing points and lines for high performancetracking. IEEE International Conference on Computer Vision, 2005.
[3]E. Rosten, T. Drummond, Machine learning for high-speed corner detection,ECCV 2006.
[4]E. Rosten, R. Porter, T. Drummond, Faster and better: A machine learningapproach to corner detection, IEEE PAMI, 2009.
[5]E. Mair, G. D. Hager, Adaptive and generic corner detection based on theaccelerated segment test, ECCV 2010.
[6]S. Leutenegger, et.al. Brisk:Binary robust invariant scalable keypoints,ICCV 2011.
代碼:
<span style="font-family:SimSun;font-size:24px;">// feature_detection.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <opencv2/core/core.hpp> #include <opencv2/features2d/features2d.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/nonfree/nonfree.hpp> // sift特征在這個頭文件中 #include <vector> #pragma comment(lib,"opencv_core2410d.lib") #pragma comment(lib,"opencv_highgui2410d.lib") #pragma comment(lib,"opencv_imgproc2410d.lib") #pragma comment(lib,"opencv_features2d2410d.lib") #pragma comment(lib,"opencv_nonfree2410d.lib") using namespace std; using namespace cv; //struct DrawMatchesFlags //{ // enum { // DEFAULT = 0, // 輸出圖像將被創建(Mat::create), // // 只畫出特征點,而不畫出周圍的circle包含特征點的大小和方向. // DRAW_OVER_OUTIMG = 1, // 輸出圖像將被創建(using Mat::create),匹配點將被畫在輸出圖像的內容上. // NOT_DRAW_SINGLE_POINTS = 2, // 單個的點不畫出. // DRAW_RICH_KEYPOINTS = 4 // 對每個特征點周圍的circle,包含特征點的大小和方向將被畫出. // }; //}; void fast_feature() { Mat image; image = imread("swan.jpg"); // vector of keyPoints std::vector<KeyPoint> keyPoints; // construction of the fast feature detector object FastFeatureDetector fast(80); // 檢測的閾值為80 // feature point detection fast.detect(image,keyPoints); drawKeypoints(image, keyPoints, image, Scalar::all(-1), DrawMatchesFlags::DRAW_OVER_OUTIMG); imshow("FAST feature", image); //cvWaitKey(0); } bool sift_feature() { Mat image = imread("swan.jpg", 1); if(!image.data) { cout << "Fail to load image" << endl; return 0; } vector<KeyPoint> keypoints; // 存放關鍵點 // 其中0.03代表特征的閥值:用於去除低對比度的關鍵點 10是用於降低直線敏感度的閥值:去除不穩點的邊緣響應點 SiftFeatureDetector sift(0.03, 10.0); sift.detect(image, keypoints); drawKeypoints(image, keypoints, image, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); namedWindow("sift"); imshow("sift", image); } void main() { sift_feature(); fast_feature(); waitKey(0); }</span>
參考文獻:
http://blog.csdn.net/yang_xian521/article/details/7411438
http://blog.csdn.net/cy513/article/details/4285579
http://blog.csdn.net/sunanger_wang/article/details/7949202