robhess的sift源碼
『壹』 Rob Hess給出的sift代碼運行出現如下錯誤:error C2198: 「cvKMeans2」: 用於調用的參數太少,請大俠指教
這是源碼里針對找到圖像特徵點進行聚類的函數,運行到這里sift演算法已經結束了。可以試著吧調用kmeans演算法的部分注釋掉,只執行sift演算法然後打出來特徵點看一下效果。我也不明白在一張圖像上對特徵點聚類的意義何在。對多張圖像聚類還有意義。
『貳』 SIFT高斯金字塔問題
SIFT特徵提取前首先要進行預處理,預處理包含對原始圖像進行高斯模糊,SIGMA即是首次進行高斯模糊的系數,後續計算中也是通過它計算每一層圖像所使用的模糊系數,具體公式可以查查高斯核和高斯卷積的計算。
由於對原圖進行高斯模糊會丟失一部分的信息,所以我們首先對圖像進行了一次插值(Rob Hess源碼中使用的是雙三次插值),以彌補信息的損失。而對原圖進行放大一倍的處理,也會導致高斯核的計算過程中需要多乘以4,這部分內容你可以找源碼出來看看。
『叄』 跪求OPENCV的SIFT程序!小女子感激不盡啊!嗚嗚…[email protected]
已發送
裡面有rob hess的c版本sift 還有個和sift差不多的matlab版本opensurf
surf比sift更快,兩者原理類似,個人更推薦surf
『肆』 sift特徵點正確匹配率是怎麼計算出來的
一、特徵點(角點)匹配
圖像匹配能夠應用的場合非常多,如目標跟蹤,檢測,識別,圖像拼接等,而角點匹配最核心的技術就要屬角點匹配了,所謂角點匹配是指尋找兩幅圖像之間的特徵像素點的對應關系,從而確定兩幅圖像的位置關系。
角點匹配可以分為以下四個步驟:
1、提取檢測子:在兩張待匹配的圖像中尋找那些最容易識別的像素點(角點),比如紋理豐富的物體邊緣點等。
2、提取描述子:對於檢測出的角點,用一些數學上的特徵對其進行描述,如梯度直方圖,局部隨機二值特徵等。檢測子和描述子的常用提取方法有:sift,harris,surf,fast,agast,brisk,freak,brisk,brief/orb等。
3、匹配:通過各個角點的描述子來判斷它們在兩張圖像中的對應關系,常用方法如 flann等。
4、消噪:去除錯誤匹配的外點,保留正確的匹配點。常用方法有KDTREE,BBF,Ransac,GTM等。
二、SIFT匹配方法的提出
為了排除因為圖像遮擋和背景混亂而產生的無匹配關系的關鍵點,SIFT的作者Lowe提出了比較最近鄰距離與次近鄰距離的SIFT匹配方式:取一幅圖像中的一個SIFT關鍵點,並找出其與另一幅圖像中歐式距離最近的前兩個關鍵點,在這兩個關鍵點中,如果最近的距離除以次近的距離得到的比率ratio少於某個閾值T,則接受這一對匹配點。因為對於錯誤匹配,由於特徵空間的高維性,相似的距離可能有大量其他的錯誤匹配,從而它的ratio值比較高。顯然降低這個比例閾值T,SIFT匹配點數目會減少,但更加穩定,反之亦然。
Lowe推薦ratio的閾值為0.8,但作者對大量任意存在尺度、旋轉和亮度變化的兩幅圖片進行匹配,結果表明ratio取值在0. 4~0. 6 之間最佳,小於0. 4的很少有匹配點,大於0. 6的則存在大量錯誤匹配點,所以建議ratio的取值原則如下:
ratio=0. 4:對於准確度要求高的匹配;
ratio=0. 6:對於匹配點數目要求比較多的匹配;
ratio=0. 5:一般情況下。
三、常見的SIFT匹配代碼
1、vlfeat中sift toolbox中的vl_ubcmatch.c使用的是普通的歐氏距離進行匹配(該SIFT代碼貢獻自Andrea
Vedaldi)。
2、Lowe的C++代碼中使用的是歐氏距離,但是在matlab代碼中為了加速計算,使用的是向量夾角來近似歐氏距離:先將128維SIFT特徵向量歸一化為單位向量(每個數除以平方和的平方根),然後點乘來得到向量夾角的餘弦值,最後利用反餘弦(acos函數)求取向量夾角。實驗證明Lowe的辦法正確率和耗時都很不錯。
同樣,也可以採用knnsearch函數求最近點和次近點:knnsearch採用euclidean距離時得到的結果與lowe採用的近似方法結果幾乎一致,正好印證了模擬歐氏距離的效果。
3、Rob Hess的OpenSIFT採用了KDTREE來對匹配進行優化。
4、CSDN大神v_JULY_v實現了KDTREE+BBF對SIFT匹配的優化和消除錯誤匹配:從K近鄰演算法、距離度量談到KD樹、SIFT+BBF演算法
- 結構之法 演算法之道 - 博客頻道 - CSDN.NET。
5、OpenCV中features2d實現的SIFT匹配有多種matcher:VectorDescriptorMatcher,BFMatcher(Brute-force descriptor matcher),FernDescriptorMatcher,OneWayDescriptorMatcher,FlannBasedMatcher 等等。目前只知道採用knnsearch,提供了多種距離度量方式,具體區別不懂。
『伍』 RobHess sift用opencv編譯時出現如下,是怎麼回事
應該是依賴的某些lib沒有添加,把opencv有關的lib比如features2d / flann / contrib 什麼的都填進去試試
『陸』 求在vs2010和opencv 2.2環境下 sift匹配圖像源碼,求大神。
#include<ctime>
#include<iostream>
#include"opencv2/core/core.hpp"
#include"opencv2/features2d/features2d.hpp"
#include"opencv2/highgui/highgui.hpp"
#include"opencv2/calib3d/calib3d.hpp"
usingnamespacecv;
usingnamespacestd;
voidreadme();
//主函數
intmain(intargc,char*argv[])
{
if(argc>3)
{
readme();
return-1;
}
//默認參數
if(argc<3)
{
argv[1]="box.png";
argv[2]="box_in_scene.png";
}
//載入圖像
Matimg_object=imread(argv[1],CV_LOAD_IMAGE_GRAYSCALE);
Matimg_scene=imread(argv[2],CV_LOAD_IMAGE_GRAYSCALE);
if(!img_object.data||!img_scene.data)
{
std::cout<<"--(!)Errorreadingimages"<<std::endl;
return-1;
}
doublebegin=clock();
//第一步:用SIFT運算元檢測關鍵點
SiftFeatureDetectordetector;//構造函數採用默認的
std::vector<KeyPoint>keypoints_object,keypoints_scene;//構造2個專門由點組成的點向量用來存儲特徵點
detector.detect(img_object,keypoints_object);//將img_object圖像中檢測到的特徵點存儲起來放在keypoints_object中
detector.detect(img_scene,keypoints_scene);//同理
//在圖像中畫出特徵點
Matimg_keypoints_object,img_keypoints_scene;
//先在內存中繪制
drawKeypoints(img_object,keypoints_object,img_keypoints_object,Scalar::all(-1),DrawMatchesFlags::DEFAULT);//在內存中畫出特徵點
drawKeypoints(img_scene,keypoints_scene,img_keypoints_scene,Scalar::all(-1),DrawMatchesFlags::DEFAULT);
//再顯示
imshow("sift_keypoints_object",img_keypoints_object);
imshow("sift_keypoints_scene",img_keypoints_scene);
//第二步:計算特徵向量
;//定義描述子對象
Matdescriptors_1,descriptors_2;//存放特徵向量的矩陣
//計算特徵向量
extractor.compute(img_object,keypoints_object,descriptors_1);
extractor.compute(img_scene,keypoints_scene,descriptors_2);
//第三步,用FLANN進行匹配特徵向量
FlannBasedMatchermatcher;//定義一個FlannBasedMatcher對象
std::vector<DMatch>matches;
matcher.match(descriptors_1,descriptors_2,matches);
doublemax_dist=0;
doublemin_dist=100;
//計算特徵點間的最大最小距離
for(inti=0;i<descriptors_1.rows;i++)
{
doubledist=matches[i].distance;
if(dist<min_dist)min_dist=dist;
if(dist>max_dist)max_dist=dist;
}
printf("--Maxdist:%f ",max_dist);
printf("--Mindist:%f ",min_dist);
//只保留好的匹配:特徵點距離小於3倍最小距離
std::vector<DMatch>good_matches;
for(inti=0;i<descriptors_1.rows;i++)
{
if(matches[i].distance<3*min_dist)
{
good_matches.push_back(matches[i]);
}
}
//在內存中繪制保留的好的匹配
Matimg_matches;
drawMatches(img_object,keypoints_object,img_scene,keypoints_scene,
good_matches,img_matches,Scalar::all(-1),Scalar::all(-1),
vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
//在場景中定位目標圖像
std::vector<Point2f>obj;
std::vector<Point2f>scene;
std::cout<<"good_matches.size():"<<good_matches.size()<<" ";
for(inti=0;i<good_matches.size();i++)
{
//從好的匹配中找到特徵點
obj.push_back(keypoints_object[good_matches[i].queryIdx].pt);
scene.push_back(keypoints_scene[good_matches[i].trainIdx].pt);
}
//基於匹配的關鍵點找出相應的變換
cv::MatH=cv::findHomography(cv::Mat(obj),cv::Mat(scene),CV_RANSAC);
//找到目標的角點
std::vector<Point2f>obj_corners(4);
obj_corners[0]=cvPoint(0,0);
obj_corners[1]=cvPoint(img_object.cols,0);
obj_corners[2]=cvPoint(img_object.cols,img_object.rows);
obj_corners[3]=cvPoint(0,img_object.rows);
std::vector<Point2f>scene_corners(4);
//映射點群,在場景中獲取目標的坐標
cv::perspectiveTransform(cv::Mat(obj_corners),cv::Mat(scene_corners),H);
//目標的角點之間連線(框出目標)
line(img_matches,scene_corners[0]+Point2f(img_object.cols,0),scene_corners[1]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
line(img_matches,scene_corners[1]+Point2f(img_object.cols,0),scene_corners[2]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
line(img_matches,scene_corners[2]+Point2f(img_object.cols,0),scene_corners[3]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
line(img_matches,scene_corners[3]+Point2f(img_object.cols,0),scene_corners[0]+Point2f(img_object.cols,0),Scalar(0,255,0),4);
//顯示保留的好的匹配
imshow("GoodMatches&Objectdetection-SIFT",img_matches);
imwrite("GoodMatches&Objectdetection-SIFT.png",img_matches);
doubleend=clock();
cout<<" SURF-elapsedtimeis:"<<(end-begin)/CLOCKS_PER_SEC*1000<<"ms ";
waitKey(0);
return0;
}
/**
*@函數readme
*/
voidreadme()
{
std::cout<<"Usage:./cv_sift_demo<img1><img2>"<<std::endl;
}
box_in_scene.png
『柒』 robhess的sift源碼怎麼編譯
這個函數包含整個sift演算法的流程,函數返回值為特徵點的數目,如果沒有找到特徵點則返回-1。img定義為輸入圖像,feat定義為指向結構體feature的指針。
int sift_features( IplImage* img, struct feature** feat )
{
return _sift_features( img,
feat,
SIFT_INTVLS,
SIFT_SIGMA,
SIFT_CONTR_THR,
SIFT_CURV_THR,
SIFT_IMG_DBL,
SIFT_DESCR_WIDTH,
SIFT_DESCR_HIST_BINS );
}
int _sift_features( IplImage* img, struct feature** feat, intintvls,
doublesigma, doublecontr_thr, intcurv_thr,
intimg_dbl,intdescr_width, intdescr_hist_bins)
{
IplImage* init_img;
IplImage***gauss_pyr, *** dog_pyr;
CvMemStorage*storage;
CvSeq* features;
intoctvs, i, n = 0;
『捌』 8點演算法 需要哪些sift數據
一、特徵點(角點)匹配圖像匹配能夠應用的場合非常多,如目標跟蹤,檢測,識別,圖像拼接等,而角點匹配最核心的技術就要屬角點匹配了,所謂角點匹配是指尋找兩幅圖像之間的特徵像素點的對應關系,從而確定兩幅圖像的位置關系。角點匹配可以分為以下四個步驟:1、提取檢測子:在兩張待匹配的圖像中尋找那些最容易識別的像素點(角點),比如紋理豐富的物體邊緣點等。2、提取描述子:對於檢測出的角點,用一些數學上的特徵對其進行描述,如梯度直方圖,局部隨機二值特徵等。檢測子和描述子的常用提取方法有:sift,harris,surf,fast,agast,brisk,freak,brisk,brief/orb等。3、匹配:通過各個角點的描述子來判斷它們在兩張圖像中的對應關系,常用方法如flann等。4、消噪:去除錯誤匹配的外點,保留正確的匹配點。常用方法有KDTREE,BBF,Ransac,GTM等。二、SIFT匹配方法的提出為了排除因為圖像遮擋和背景混亂而產生的無匹配關系的關鍵點,SIFT的作者Lowe提出了比較最近鄰距離與次近鄰距離的SIFT匹配方式:取一幅圖像中的一個SIFT關鍵點,並找出其與另一幅圖像中歐式距離最近的前兩個關鍵點,在這兩個關鍵點中,如果最近的距離除以次近的距離得到的比率ratio少於某個閾值T,則接受這一對匹配點。因為對於錯誤匹配,由於特徵空間的高維性,相似的距離可能有大量其他的錯誤匹配,從而它的ratio值比較高。顯然降低這個比例閾值T,SIFT匹配點數目會減少,但更加穩定,反之亦然。Lowe推薦ratio的閾值為0.8,但作者對大量任意存在尺度、旋轉和亮度變化的兩幅圖片進行匹配,結果表明ratio取值在0.4~0.6之間最佳,小於0.4的很少有匹配點,大於0.6的則存在大量錯誤匹配點,所以建議ratio的取值原則如下:ratio=0.4:對於准確度要求高的匹配;ratio=0.6:對於匹配點數目要求比較多的匹配;ratio=0.5:一般情況下。三、常見的SIFT匹配代碼1、vlfeat中sifttoolbox中的vl_ubcmatch.c使用的是普通的歐氏距離進行匹配(該SIFT代碼貢獻自AndreaVedaldi)。2、Lowe的C++代碼中使用的是歐氏距離,但是在matlab代碼中為了加速計算,使用的是向量夾角來近似歐氏距離:先將128維SIFT特徵向量歸一化為單位向量(每個數除以平方和的平方根),然後點乘來得到向量夾角的餘弦值,最後利用反餘弦(acos函數)求取向量夾角。實驗證明Lowe的法正確率和耗時都很不錯。同樣,也可以採用knnsearch函數求最近點和次近點:knnsearch採用euclidean距離時得到的結果與lowe採用的近似方法結果幾乎一致,正好印證了模擬歐氏距離的效果。3、RobHess的OpenSIFT採用了KDTREE來對匹配進行優化。4、CSDN大神v_JULY_v實現了KDTREE+BBF對SIFT匹配的優化和消除錯誤匹配:從K近鄰演算法、距離度量談到KD樹、SIFT+BBF演算法-結構之法演算法之道-博客頻道-CSDN.NET。5、OpenCV中features2d實現的SIFT匹配有多種matcher:VectorDescriptorMatcher,BFMatcher(Brute-forcedescriptormatcher),FernDescriptorMatcher,OneWayDescriptorMatcher,FlannBasedMatcher等等。目前只知道採用knnsearch,提供了多種距離度量方式,具體區別不懂。
『玖』 緊急求助:在運行SIFT源碼時,由於是matlab和vc混編的,設置了mex後還是顯示找不到c文件。
嘗試將'imsmooth.c' 也mex,把相關文件拷到vc。編譯出來的好像是.mexw32.混編會遇到諸多問題,若還未解決,多貼出些相關信息。我現在也在做混編,不過是基於COM的。
『拾』 如何本地安裝SIFT
SIFT的實現有很多版本,具體方式都是那麼幾個,找個好用的不太容易,因為對於代碼不熟練者各種版本用起來都有點水土不服,需要調整調整才行。本人是在VS2010下使用的Rob Hess的源碼。
一、前提
安裝Opencv,詳見:VS2010+Opencv-2.4.0的配置攻略(該版本SIFT是基於Opencv的)。
下載SIFT源碼,見Rob Hess的主頁(別告訴我不懂英文不知道下載鏈接在哪,下那個Windows VC++的版本 sift-latest_win.zip)。
二、測試
1、解壓sift源碼,發現有如下文件:
5、C語法設定:分別打開imgfeatures.h和sift.h,讓所有函數包含在
#ifdef __cplusplusextern"C"{#endif
和
#ifdef __cplusplus }#endif
之間。例如:
View Code
... #ifdef __cplusplusextern"C"{#endif...externintsift_features( IplImage* img,structfeature**feat ); ...externint_sift_features( IplImage* img,structfeature** feat,intintvls,doublesigma,doublecontr_thr,intcurv_thr,intimg_dbl,intdescr_width,intdescr_hist_bins ); #ifdef __cplusplus }#endif#endif
PS:我只是用了_sift_features(...)等幾個函數,所以只加了兩個頭文件的C語法聲明,如果是用了其他的頭文件,均需要添加。
6、綜上,你應該可以直接使用sift相關函數了,參照siftfeat.c中的寫法,用用_sift_features(...)試試!
實際上如果只需要使用SIFT特徵提取的函數,前面幾步只需要復制imgfeatures.c imgfeatures.h sift.c sift.h utils.c utils.h這6個文件就夠了