PS: 很久沒做CV的事情了,這是很早以前剛入門時候的一篇,以后再有CV相關工作會發布在新的個人站點:http://my.phirobot.com/blog/category/cv.html CV分類下。
update @ 2013-03-17 15:29 from [FreedomShe]
后來才發現Rob Hess修改過源碼了,下載鏈接貌似也改變了,現在提供以前版本源碼(本人修改過后的,可直接運行)的下載鏈接:http://pan.baidu.com/share/link?shareid=355371&uk=321491344。可以跳過修改源碼的步驟。
SIFT的實現有很多版本,具體方式都是那么幾個,找個好用的不太容易,因為對於代碼不熟練者各種版本用起來都有點水土不服,需要調整調整才行。本人是在VS2010下使用的Rob Hess的源碼。
一、前提
安裝Opencv,詳見:VS2010+Opencv-2.4.0的配置攻略(該版本SIFT是基於Opencv的)。
下載SIFT源碼,見Rob Hess的主頁(別告訴我不懂英文不知道下載鏈接在哪,下那個Windows VC++的版本 sift-latest_win.zip)。
二、測試
1、解壓sift源碼,發現有如下文件:
其中有3個是解決方案文件夾:siftFeat、match和dspFeat,siftFeat工程是做SITF特征提取的,一般只會用到這個案例,match是利用SIFT特征做圖像匹配的,desFeat沒用過不說了。
所有源代碼(包括上面3個工程的main)都在文件夾外面,就是那些成對的.h和.c了。
2、可以先試着跑跑siftFeat。
打開siftFeat.sln,配置好Opencv在VS2010中的環境參數(VS2010+Opencv-2.4.0的配置攻略中有述,注意include里面要添加/include/opencv,因為sift源碼直接引用了/include/opencv目錄下的頭文件)。
編譯報錯:
1>utils.obj : error LNK2001: 無法解析的外部符號 _va_end
1>utils.obj : error LNK2001: 無法解析的外部符號 _va_start
說好了源碼里面有些東西是要改的:在utils.c中#include <stdarg.h>就OK了。
F5調試運行,成功顯示:
三、在C++工程中應用SIFT
1、在VS2010中新建自己的C++工程PP。在工程根目錄內添加目錄命名為sift,將sift源碼文件imgfeatures.c imgfeatures.h kdtree.c kdtree.h minpq.c minpq.h sift.c sift.h utils.c utils.h xform.c xform.h(即除了match.c siftfeat.c dspfeat.c的所有源碼文件)復制到\PP\sift內。
2、在VS2010內引入sift源碼:在“資源管理器”視圖里添加“篩選器”,命名為sift,將剛才拷貝過來的sift源文件引入其內:
3、在需要使用sift方法的地方添加對應頭文件:
#include "..\sift\sift.h" #include "..\sift\imgfeatures.h" #include "..\sift\utils.h"
4、取消.c文件的預編譯:同樣在“資源管理器”視圖下面復選sift文件夾內所有.c文件,右鍵選擇“屬性”,選取“C/C++”->“預編譯頭”,在“預編譯頭”選項中選擇“不使用預編譯頭”。
5、C語法設定:分別打開imgfeatures.h和sift.h,讓所有函數包含在
#ifdef __cplusplus extern "C" { #endif
和
#ifdef __cplusplus } #endif
之間。例如:

... #ifdef __cplusplus extern "C" { #endif ... extern int sift_features( IplImage* img, struct feature** feat ); ... extern int _sift_features( IplImage* img, struct feature** feat, int intvls, double sigma, double contr_thr, int curv_thr, int img_dbl, int descr_width, int descr_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個文件就夠了。