引言
本人采用的是RobHess的代碼,網上實現該代碼的文章有很多,但大多是在vs2010和vc6.0上實現的,我在用vs2015實現的過程總出現了很多新問題,在這里我將一步步的把出現的所有bug都解決一遍,希望可以給您提供一些幫助。
ps:關於SIFT的原理可以參考SIFT特征提取分析 和一些碩士論文,我就不再說了。此外,我采用的代碼是2010年的版本sift-1.1.2_20101207_win,該代碼可以從我列的參考資料中下載到。
正文
現在我們正式開始一步步的實現SIFT的代碼。解壓縮之后我們可以看到有三個子項目:siftFeat、match、dspFeat。siftFeat是用來提取圖片特征的,match是將兩幅圖像的特征匹配,dspFeat是讀取已經提取的特征並顯示在圖片上。
-
我們首先試着運行siftFeat,提示需要對該項目進行升級,點擊確定升級。
-
進入工程之后我們會看到如下錯誤:
fatal error C1083: 無法打開包括文件: “cxcore.h”: No such file or directory
這是因為我們還沒有配置opencv。
右擊工程,選擇屬性打開屬性頁,選擇VC++目錄,選擇包含目錄,在其中添加如下三個路徑,這是我的opencv安裝路徑,讀者注意添加自己的路徑。
D:\opencv\build\include
D:\opencv\build\include\opencv
D:\opencv\build\include\opencv2
接着選擇庫目錄,添加如下兩個路徑,同樣要添加自己的路徑。
D:\opencv\build\x86\vc12\lib
D:\opencv\build\x86\vc12\staticlib
最后選擇鏈接器,選擇輸入,選擇附加依賴項,把原本的lib都刪除,換成如下兩條。
opencv_ts300d.lib
opencv_world300d.lib
ps:200d是opencv2.0版本的,我們3.0版本當然要用300d了。
300d是debug編譯,300是release編譯,我用的是debug編譯。
配置完成后,該問題解決! -
再次運行程序,發現有如下錯誤:
error C2440: “=”: 無法從“int”轉換為“CvScalar”
error C2440: “初始化”: 無法從“int”轉換為“CvScalar”
雙擊錯誤跳到對應代碼處。
可以看到這句代碼是沒有語法錯誤的,所以只能是頭文件包含錯誤。我們看到imgfeatures.c包含的頭文件如下,其中與CvScalar有關的頭文件是cxcore.h,該頭
文件包含於cv.h,所以改成cv.h或許可以解決問題。
修改之后,該問題解決! -
再次運行程序,發現有如下錯誤:
error LNK2019: 無法解析的外部符號 _va_start,該符號在函數 _fatal_error 中被引用
error LNK2019: 無法解析的外部符號 _va_end,該符號在函數 _fatal_error 中被引用
這時我們只需要在utils.c里加上#include < stdarg.h >即可。
問題再次解決! -
再次運行程序,呵呵,還有錯誤,出現如下錯誤界面:
點擊調試,靜靜等待之后報的錯誤是:
0x10CE0F77 (opencv_world300d.dll) (siftFeat.exe 中)處有未經處理的異常: 0xC0000005: 讀取位置 0x00000020 時發生訪問沖突。
在右下角的調用堆棧界面選擇最后執行的語句轉到出錯的代碼處。
錯誤代碼處:
網上說該錯誤一般是由於空指針引起的,但對於該處好像不太適用。
該行代碼的原意是利用cvGetSize(img)返回img圖片的寬和高,再創建gray32這個新圖片,而創建圖像的函數cvCreateImage用法沒有錯誤,所以只能是cvGetSize這個函數出錯了,也就是說cvGetSize(img)並沒有返回img的寬和高,所以我們可以直接手動把img的寬和高寫出來,即將cvGetSize(img)修改為cvSize(img->width, img->height),同理,把代碼其它地方的cvGetSize修改為相應的cvSize即可。
此時再運行程序,問題得到解決,並出現了讓人感動的松鼠界面。
結束
至此,siftFeat就算運行成功了,為了完整性,我再放兩張match和dspFeat運行后的圖片,作為結束。
match:
dspFeat:
參考資料