在VS2010中应用SIFT(C)源码
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个文件就够了。