與opencv2.3.1版本的sift演算法的程式設計方法有所不同,貌似opencv2.4版本之後將sift、surf演算法移到了nonfree區。
所以,需要包換的標頭檔案:
#include
#include
opencv_nonfree249d.lib和opencv_features2d249d.lib
具體sift演算法的運算過程是這樣的:
1、用featuredetector建立相應的特徵檢測器,並呼叫featuredetector::detect()函式,來求取特徵點,並儲存在keypoint的vector容器中。
特徵檢測器如下:
ptrdetector = featuredetector::create( "sift" );//建立sift特徵檢測器
其中featuredetector::create()函式的引數可選:
• "fast" – fastfeaturedetector
• "star" – starfeaturedetector
• "sift" – sift (nonfree module)
• "surf" – surf (nonfree module)
• "orb" – orb
• "brisk" – brisk
• "mser" – mser
• "gftt" – goodfeaturestotrackdetector
• "harris" – goodfeaturestotrackdetector with harris detector enabled
• "dense" – densefeaturedetector
• "******blob" – ******blobdetector
keypoints特徵點類定義如下:
class keypoint
2、用descriptorextractor建立相應的特徵向量生成器,並呼叫descriptorextractor::compute()函式,來求取特徵矩陣,儲存在mat型變數中。
特徵向量生成器定義如下:
ptrdescriptor_extractor = descriptorextractor::create( "sift" );//建立特徵向量生成器
其中descriptorextractor::create()函式的引數如下:
• "sift" – sift
• "surf" – surf
• "brief" – briefdescriptorextractor
• "brisk" – brisk
• "orb" – orb
• "freak" – freak
3、用descriptormatcher建立特徵匹配器,並呼叫descriptormatcher::match()函式,求取兩幅影象之間的匹配點,並儲存在dmatch的vector容器中。
特徵匹配器定義如下:
ptrdescriptor_matcher = descriptormatcher::create( "bruteforce" );//建立特徵匹配器
其中descriptormatcher::create()函式的引數如下,對應不同的匹配演算法:
– bruteforce (it uses l2 )
– bruteforce-l1
– bruteforce-hamming
– bruteforce-hamming(2)
– flannbased
dmatch結構體定義如下:
struct dmatch
dmatch(int _queryidx, int _trainidx, float _distance ) :
queryidx( _queryidx),trainidx( _trainidx), imgidx(-1),distance( _distance) {}
dmatch(int _queryidx, int _trainidx, int _imgidx, float _distance ) :
queryidx(_queryidx), trainidx( _trainidx), imgidx( _imgidx),distance( _distance) {}
intqueryidx; //此匹配對應的查詢影象的特徵描述子索引
inttrainidx; //此匹配對應的訓練(模板)影象的特徵描述子索引
intimgidx; //訓練影象的索引(若有多個)
float distance; //兩個特徵向量之間的歐氏距離,越小表明匹配度越高。
booloperator < (const dmatch &m) const;
};
4、呼叫drawmatches()函式繪製匹配結果。
例程如下:
#include #include #include #include #include #include using namespace cv;
using namespace std;
int main()
{ /*sift演算法*/
mat image1=imread("e:\\test\\lena.bmp",0);
mat image2=imread("e:\\test\\lena_match.bmp",0);
initmodule_nonfree(); //初始化模組,使用sift或surf時用到
ptrdetector = featuredetector::create( "sift" );//建立sift特徵檢測器
ptrdescriptor_extractor = descriptorextractor::create( "sift" );//建立特徵向量生成器
ptrdescriptor_matcher = descriptormatcher::create( "bruteforce" );//建立特徵匹配器
if( detector.empty() || descriptor_extractor.empty() )
cout<
//檢測特徵點
vectorvkkeypoints1,vkkeypoints2;
detector->detect(image1,vkkeypoints1);
detector->detect(image2,vkkeypoints2);
cout<
descriptor_extractor->compute(image2, vkkeypoints2, mdescriptors2);
cout<
descriptor_matcher->match(mdescriptors1,mdescriptors2,vdmatches);
//篩選匹配結果
//距離是指兩個特徵向量間的歐式距離,表明兩個特徵的差異,值越小表明兩個特徵點越接近
int nmindis=100,nmaxdis=0;
for (int i=0;ivdmatches[i].distance)
nmindis=vdmatches[i].distance;
if (nmaxdisvdgoodmatches;
for (int i=0;i
注:如果僅僅想畫出特徵點,可呼叫
drawkeypoints()函式實現,如:drawkeypoints(img1,keypoints1,img_keypoints1,scalar::all(-1),0); 。
執行結果:
參考:
sift的opencv簡易實現
實驗室的mac下xcode scale invariant feature transform sift 特點 穩定 獨特 多量 高速 可擴充套件 步驟 1.多尺度空間極點檢測 2.關鍵點 keypoints 定位 3.關鍵點的方向確定 4.描述子生成 細節 高斯卷積為多尺度空間唯一線性核 l x,...
使用OPENCV自帶的sift提取特徵
最近在使用opencv中自帶的sift特徵提取器,學藝不精導致很簡單的東西搞了好幾天沒出來,今天解決了特意紀錄下 opencv empty proj.cpp 定義控制台應用程式的入口點。include stdafx.h include include include include include ...
使用OPENCV自帶的sift提取特徵
原文 最近在使用opencv中自帶的sift特徵提取器,學藝不精導致很簡單的東西搞了好幾天沒出來,今天解決了特意紀錄下 opencv empty proj.cpp 定義控制台應用程式的入口點。include stdafx.h include include include include inclu...