SURF与SIFT比较分析
?
opencv3.2 SURF實現特征點匹配
opencv3.2中SurfFeatureDetector、SurfDescriptorExtractor、BruteForceMatcher這三個的使用方法已經和原先2.4版本前不一樣了。
使用方法示例如下:
Ptr<SURF> detector = SURF::create(minHessian);detector->detect(img_1, keypoints_1);Ptr<SURF> extractor = SURF::create();extractor->compute(img_1, keypoints_1, descriptors_1);Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce");//這里填寫使用的匹配方式
matcher->match(descriptors_1, descriptors_2, matches);
debug版本detect函數運行時會報錯,內存訪問錯誤什么的,,,,,?
具體原因還不知道,網上查找資料修改圖片type為CV_8U,和給vector手動分配空間,實測沒有用,但是改為release版本可以使用。
代碼:
#include<opencv2/features2d/features2d.hpp>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/xfeatures2d/nonfree.hpp>
#include<opencv2/core/core.hpp>#include<iostream>
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
int main()
{Mat srcImage1 = imread("3.jpg", 1);Mat srcImage2 = imread("4.jpg",1);if (!srcImage1.data || !srcImage2.data){cout << "讀取圖片出錯" << endl;return false;}imshow("原始圖1",srcImage1);imshow("原始圖2", srcImage2);int minHessian = 100;Ptr<SurfFeatureDetector> detector = SurfFeatureDetector::create(minHessian);vector<cv::KeyPoint> key_points_1, key_points_2;Mat dstImage1, dstImage2;detector->detectAndCompute(srcImage1,Mat(), key_points_1,dstImage1);detector->detectAndCompute(srcImage2,Mat(), key_points_2,dstImage2);//可以分成detect和computeMat img_keypoints_1, img_keypoints_2;drawKeypoints(srcImage1,key_points_1,img_keypoints_1,Scalar::all(-1),DrawMatchesFlags::DEFAULT);drawKeypoints(srcImage2, key_points_2, img_keypoints_2, Scalar::all(-1),DrawMatchesFlags::DEFAULT);Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");vector<DMatch>mach;matcher->match(dstImage1,dstImage2,mach);double Max_dist = 0;double Min_dist = 100;for (int i = 0; i < dstImage1.rows; i++){double dist = mach[i].distance;if (dist < Min_dist)Min_dist = dist;if (dist > Max_dist)Max_dist = dist;}cout << "最短距離" << Min_dist << endl;cout << "最長距離" << Max_dist << endl;vector<DMatch>goodmaches;for (int i = 0; i < dstImage1.rows; i++){if (mach[i].distance < 2 * Min_dist)goodmaches.push_back(mach[i]);}Mat img_maches;drawMatches(srcImage1,key_points_1,srcImage2,key_points_2,goodmaches,img_maches);for (int i = 0; i < goodmaches.size(); i++){cout << "符合條件的匹配:" << goodmaches[i].queryIdx << "--" << goodmaches[i].trainIdx << endl;}imshow("效果圖1", img_keypoints_1);imshow("效果圖2", img_keypoints_2);imshow("匹配效果",img_maches);waitKey(0);return 0;
}
?
SURF與SIFT
?
共同點:
SIFT/SURF為了實現不同圖像中相同場景的匹配,主要包括三個步驟:
1、尺度空間的建立;
2、特征點的提取;
3、利用特征點周圍鄰域的信息生成特征描述子
4、特征點匹配。
? 推薦:http://blog.csdn.net/cy513/archive/2009/08/05/4414352.aspx
? ? ? 如果兩幅圖像中的物體一般只是旋轉和縮放的關系,加上圖像的亮度及對比度的不同,要在這些條件下要實現物體之間的匹配,SIFT算法的先驅及其發明者想到只要找到多于三對物體間的匹配點就可以通過射影幾何的理論建立它們的一一對應。
? ? ? 如何找到這樣的匹配點呢?SIFT/SURF作者的想法是首先找到圖像中的一些“穩定點”,這些點是一些特殊的點,不會因為視角的改變、光照的變化、噪音的干擾而消失,比如角點、邊緣點、暗區域的亮點以及亮區域的暗點。這樣如果兩幅圖像中有相同的景物,那么這些穩定點就會在兩幅圖像的相同景物上同時出現,這樣就能實現匹配。因此,SIFT/SURF算法的基礎是穩定點。
? ? ? SIFT/SURF提取的穩定點,首先都要求是局部極值。但是,當兩個物體的大小比例不一樣時,大圖像的局部極值點在小圖像的對應位置上有可能不是極值點。于是SIFT/SURF都采用圖像金字塔的方法,每一個截面與原圖像相似,這樣兩個金字塔中就有可能包含大小最近似的兩個截面了。
? ? ? 這樣找到的特征點會比較多,經過一些處理后濾掉一些相對不穩定的點。
? ? ? 接下來如何去匹配相同物體上對應的點呢?SIFT/SURF的作者都想到以特征點為中心,在周圍鄰域內統計特征,將特征附加到穩定點上,生成特征描述子。在遇到旋轉的情況下,作者們都決定找出一個主方向,然后以這個方向為參考坐標進行后面的特征統計,就解決了旋轉的問題。
?
共同的大問題有以下幾個:
1、為什么選用高斯金字塔來作特征提取?
? ? ? 為什么是DOG的金字塔?因為它接近LOG,而LOG的極值點提供了最穩定的特征,而且DOG方便計算(只要做減法。)
? ? ? 為什么LOG的極值點提供的特征最穩定,有參考文獻,未看。
???? (7.12補充:)直觀理解:特征明顯的點經過不同尺度的高斯濾波器進行濾波后,差別較大,所以用到的是DOG。
? ? ? 但是直觀上怎么理解?如果相鄰Octave的sigma不是兩倍關系還好理解:如果兩幅圖像只是縮放的關系,那么假設第一個Octave找到了小一倍圖像的極值點,那么大一倍圖像的極值點會在下一個Octave找到相似的。但是現在,如果把大一倍圖像進行一次下采樣(這樣和小的圖像就完全一樣了),進行Gauss濾波時,兩個圖像濾波系數(sigma)是不一樣的,不就找不到一樣的極值點了么?不理解。
2、Hessian矩陣為什么能用來篩選極值點?
? ? ? SIFT先利用非極大抑制,再用到Hessian矩陣進行濾除。SURF先用Hessian矩陣,再進行非極大抑制。SURF的順序可以加快篩選速度么?(Hessian矩陣濾除的點更多?)
? ? ? 至于SURF先用Hessian矩陣,再進行非極大抑制的原因,是不管先極大值抑制還是判斷Hessian矩陣的行列式,金字塔上的點的行列式都是要計算出來的。先判斷是否大于0只要進行1次判斷,而判斷是否是極大值點或者極小值點要與周圍26個點比較,只比較1次肯定快。
? ? ? 而在SIFT中,構建的高斯金字塔只有一座(不想SURF是有3座),要進行非極大抑制可以直接用金字塔的結果進行比較。而如果計算Hessian矩陣的行列式,還要再計算Dxx、Dxy、Dyy。因此先進行非極大抑制。這兩個步驟的先后與SIFT/SURF的實際計算情況有關的,都是當前算法下的最佳順序,而不是說哪種先計算一定更好。
3、為什么采用梯度特征作為局部不變特征?
? ? ? 這與人的視覺神經相關。采用梯度作為描述子的原因是,人的視覺皮層上的神經元對特定方向和空間頻率的梯度相應很敏感,經過SIFT作者的一些實驗驗證,用梯度的方法進行匹配效果很好。
4、為什么可以采用某些特征點的局部不變特征進行整幅圖像的匹配?
從直觀的人類視覺印象來看,人類視覺對物體的描述也是局部化的,基于局部不變特征的圖像識別方法十分接近于人類視覺機理,通過局部化的特征組合,形成對目標物體的整體印象,這就為局部不變特征提取方法提供了生物學上的解釋,因此局部不變特征也得到了廣泛應用。
? ? ? 還有:
? ? ? 圖像中的每個局部區域的重要性和影響范圍并非同等重要,即特征不是同等顯著的,其主要理論來源是Marr的計算機視覺理論和Treisman的特征整合理論,一般也稱為“原子論”。該理論認為視覺的過程開始于對物體的特征性質和簡單組成部分的分析,是從局部性質到大范圍性質。
? ? ? SIFT/SURF都是對特征點的局部區域的描述,這些特征點應該是影響重要的點,對這些點的分析更加重要。所以在局部不變特征的提取和描述時也遵循與人眼視覺注意選擇原理相類似的機制,所以SIFT/SURF用于匹配有效果。
?
?
不同點的比較:
總結
| ? | SIFT | SURF |
| 尺度空間 | DOG與不同尺度的圖片卷積 | 不同尺度的box filters與原圖片卷積 |
| 特征點檢測 | 先進行非極大抑制,再去除低對比度的點。再通過Hessian矩陣去除邊緣的點 | 先利用Hessian矩陣確定候選點,然后進行非極大抑制 |
| 方向 | 在正方形區域內統計梯度的幅值的直方圖,找max對應的方向。可以有多個方向。 | 在圓形區域內,計算各個扇形范圍內x、y方向的haar小波響應,找模最大的扇形方向 |
| 特征描述子 | 16*16的采樣點劃分為4*4的區域,計算每個區域的采樣點的梯度方向和幅值,統計成8bin直方圖,一共4*4*8=128維 | 20*20s的區域劃分為4*4的子區域,每個子區域找5*5個采樣點,計算采樣點的haar小波響應,記錄∑dx,?∑dy,∑|dx|,∑|dy|,一共4*4*4=64維 |
?SURF—金字塔僅僅是用來做特征點的檢測。在計算描述子的時候,haar小波響應是計算在原圖像(利用積分圖)。而SIFT是計算在高斯金字塔上(注意不是高斯差分金字塔。)
性能的比較:
論文:A comparison of SIFT, PCA-SIFT and SURF??對三種方法給出了性能上的比較,源圖片來源于Graffiti dataset,對原圖像進行尺度、旋轉、模糊、亮度變化、仿射變換等變化后,再與原圖像進行匹配,統計匹配的效果。效果以可重復出現性為評價指標。
比較的結果如下:
| method | Time | Scale | Rotation | Blur | Illumination | Affine |
| Sift | common | best | best | common | common | good |
| Pca-sift | good | good | good | best | good | best |
| Surf? | best | common | common | good | best | good |
?
????
由此可見,SIFT在尺度和旋轉變換的情況下效果最好,SURF在亮度變化下匹配效果最好,在模糊方面優于SIFT,而尺度和旋轉的變化不及SIFT,旋轉不變上比SIFT差很多。速度上看,SURF是SIFT速度的3倍。
參考:
http://apps.hi.baidu.com/share/detail/32318290
http://blog.csdn.net/ijuliet/archive/2009/10/07/4640624.aspx
http://blog.csdn.net/cy513/article/details/4414352
http://www.cnblogs.com/mysunnyday/archive/2011/08/31/2160298.html
https://blog.csdn.net/xxzxxzdlut/article/details/72926011
?
總結
以上是生活随笔為你收集整理的SURF与SIFT比较分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 医院入职体检多少钱啊?
- 下一篇: SLAM资源整理