《視覺SLAM十四講》課後習題—ch7(更新中……)
參考:https://blog.csdn.net/zilanpotou182/article/details/66478915(SIFT、SURF、ORB三種特征點的區別)
1.除了本書介紹的ORB特征點外,你還能找到哪些特征點?請說說SIFT或SURF的原理,並對比它們與ORB之間的優劣
特征點:圖像裏一些特別的地方
特征點的種類:SIFT、SURF、ORB、FAST
SIFT算法充分考慮了在圖像變換過程中出現的光照、尺度、旋轉等變化,但是這會帶來極大的計算量。
SURF算法的速度遠快於SIFT,SURF的魯棒性很好,特征點識別率較SIFT高,在視角、光照、尺度變化等情形下,大體上都優於SIFT。
ORB算法運算速度與前兩者相比速度最快,但是這種算法尺度方面效果較差,因為ORB不具備尺度變換。
定量比較:計算速度:ORB>>SURF>>SIFT(各差一個量級)
旋轉魯棒性:SURF>ORB~SIFT(表示差不多)
模糊魯棒性: SURF>ORB~SIFT
尺度變換魯棒性: SURF>SIFT>ORB(ORB並不具備尺度變換性)
綜上,我們在選擇特征點時的依據是如果對計算實時性要求非常高,可選用ORB算法,但基本要保證正對拍攝;如果對實行性要求稍高,可以選擇SURF;基本不用SIFT
2.設計程序調用OpenCV中的其他種類特征點。統計在提取1000個特征點時在你的機器上的運行時間。
首先我們要知道如果要調用opencv中的SIFT和SURF特征點,SIFT和SURF都在nonfree模塊中,所以我們就需要nonfree模塊。
但是在opencv3中,SURF/SIFT 以及其它的一些東西被移動到了獨立的庫(opencv_contrib)中。
所以首先我們需要安裝opencv_contrib:(如果你用的是opencv2可以省略安裝opencv_contrib這一步驟)
安裝步驟見:安裝opencv_contrib(ubuntu16.0)
ORB、SIFT、SURF三種特征點提取方法的代碼如下:
1 #include <iostream> 2 #include <opencv2/core/core.hpp> 3 #include <opencv2/features2d/features2d.hpp> 4 //#include <opencv2/nonfree/features2d.hpp> 5 //#include <opencv2/nonfree/nonfree.hpp>//SIFT 6 #include <opencv2/highgui/highgui.hpp> 7 #include <opencv2/xfeatures2d/nonfree.hpp>//SIFT 8 #include <chrono> 9 10 //using namespace xfeatures2d; 11 using namespace std; 12 using namespace cv; 13 14 int main(int argc,char** argv) 15 { 16 if(argc!=2) 17 { 18 cout<<"usage:feature_extraction img1"<<endl; 19 return 1; 20 } 21 22 //讀取圖像 23 Mat img_1=imread(argv[1],CV_LOAD_IMAGE_COLOR); 24 25 //初始化 26 vector<KeyPoint> keypoints_1;//關鍵點,指特征點在圖像裏的位置 27 28 //orb 29 chrono::steady_clock::time_point ORB_t1=chrono::steady_clock::now(); 30 Ptr<ORB> orb=ORB::create(500,1.2f,8,31,0,2,ORB::HARRIS_SCORE,31,20); 31 chrono::steady_clock::time_point ORB_t2=chrono::steady_clock::now(); 32 chrono::duration<double> ORB_time_used=chrono::duration_cast<chrono::duration<double>>(ORB_t2-ORB_t1); 33 cout<<"extract keypoints of ORB costs: "<<ORB_time_used.count()<<" seconds."<<endl; 34 orb->detect(img_1,keypoints_1); 35 36 cout<<"KP1 = "<<keypoints_1.size()<<endl;//特征點的數量 37 Mat outimg1; 38 drawKeypoints(img_1,keypoints_1,outimg1,Scalar::all(-1),DrawMatchesFlags::DEFAULT); 39 imshow("1.png的ORB特征點",outimg1); 40 41 42 // //SIFT 43 // chrono::steady_clock::time_point SIFT_t1=chrono::steady_clock::now(); 44 // Ptr<xfeatures2d::SiftFeatureDetector> siftDetector_1=xfeatures2d::SiftFeatureDetector::create(); 45 // siftDetector_1->detect(img_1,keypoints_1); 46 // chrono::steady_clock::time_point SIFT_t2=chrono::steady_clock::now(); 47 // chrono::duration<double> SIFT_time_used=chrono::duration_cast<chrono::duration<double>>(SIFT_t2-SIFT_t1); 48 // cout<<"extract keypoints of SIFT costs: "<<SIFT_time_used.count()<<" seconds."<<endl; 49 // Mat outImg; 50 // drawKeypoints(img_1,keypoints_1,outImg,Scalar::all(-1),DrawMatchesFlags::DEFAULT); 51 52 // cout<<"KP1 = "<<keypoints_1.size()<<endl; 53 // imshow("1.png的SIFT特征點",outImg); 54 55 // //SURF 56 // chrono::steady_clock::time_point SURF_t1=chrono::steady_clock::now(); 57 // Ptr<xfeatures2d::SurfFeatureDetector> surfDetector_1=xfeatures2d::SurfFeatureDetector::create(); 58 // surfDetector_1->detect(img_1,keypoints_1); 59 // chrono::steady_clock::time_point SURF_t2=chrono::steady_clock::now(); 60 // chrono::duration<double> SURF_time_used=chrono::duration_cast<chrono::duration<double>>(SURF_t2-SURF_t1); 61 // cout<<"extract keypoints of SURF costs: "<<SURF_time_used.count()<<" seconds."<<endl; 62 // Mat outImg; 63 // drawKeypoints(img_1,keypoints_1,outImg,Scalar::all(-1),DrawMatchesFlags::DEFAULT); 64 // cout<<"KP1 = "<<keypoints_1.size()<<endl; 65 // imshow("1.png的SURF特征點",outImg); 66 waitKey(0); 67 68 return 0; 69 }
實驗結果:原始圖像為:
1) ORB
2) SIFT
3) SURF
分析:可見,計算速度是ORB最快,SURF次之,SIFT最慢。
但是為什麽基於同一張圖片提取特征點,三種方法提取出的特征點數目不一樣而且相差還很多呢?應該是因為三種方法的原理決定的吧。
《視覺SLAM十四講》課後習題—ch7(更新中……)