引言
本人采用的是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:
参考资料