为要做一个简单的摄像头蔽障,考虑用OpenCV做图像处理比较方便,用Windows Form做个简单的界面非常快速。就想在Windows Form里用OpenCV的函数库.我的编辑环境是VC++2005(VC++8/VS2005)。把我的一些经验发上来希望能给别人提供一点帮助。
首先安装OpenCV.
具体安装步骤以及OpenCV的下载可以去OpenCV 中文论坛 www.opencv.org.cn 找到,网上也有非常多的博客和论坛有介绍。这里提醒一点,无论是否在安装时钩上了添加环境变量都要再手动添加一次。(是OpenCV的小BUG)。具体方法:右击我的电脑—属性—高级—环境变量—path—你OpenCV的安装路径下/OpenCV/bin.
在VC++2005下设置OpenCV
也不再啰嗦,去OpenCV 中文论坛 www.opencv.org.cn 很好找,很详细.各种C++编辑环境下的都有.一步步照着来.
MOST IMPORTANT
在Win32控制台以及MFC下都可以直接添加cv.h以及OpenCV的其他头文件,但是在Windows Form似乎不可以.在论坛里也看到有人发问是不是在Windows Form里不能使用OpenCV.其实是可以的.很简单,Windows Form默认是"纯 MSIL 公共语言运行库支持(/clr:pure)"要改成"公共语言运行库支持(/clr)".具体位置:在解决方案里,右击你的工程—属性—配置属性—常规,然后就能看到"公共语言运行库支持"的配置了.
现在就可以在Windows Form下使用OpenCV的函数库啦!!
因为OpenCV 从视频设备采集图像的函数cvCaptureFromCAM 使用的是vfw,采用消息机制,速度较慢,测试发现fps只有 9-12左右,太慢了.使用DirectShow后速度可以提升到60帧/s.
首先下载DirectX
提别提醒:别下最新版的!!下DirectX 9.0b SDK或者DirectX 9.0a SDK,因为DirectX 9.0c SDK 之后的版本把DirectShow去掉了!!
配置DirectShow开发环境
我当时是参考一篇博客“LGS的BLOG” 设置的,里面写的很详细,在这里要向李大哥表示感谢.我把这篇博文贴过来,供大家参考。我对原文里一个地方有异议,所以在下面修改了(红色标注)。
以下转自LGS的BLOG
首先,就是编译baseclasses,什么是baseclasses?打开你的dx的sdk安装目录,例如:
D:/DX90SDK/Samples/C++/DirectShow/
这里就有一个叫baseclasses的工程,为安全起见,请先备份此工程。
1,双击baseclasses.sln打开,提示我们需要转换工程,按提示转换就是了,编译
提示错误:
1>D:/Microsoft Visual Studio 8/VC/PlatformSDK/include/winnt.h(222) : error C2146: syntax error : missing ';' before identifier 'PVOID64'
1>D:/Microsoft Visual Studio 8/VC/PlatformSDK/include/winnt.h(222) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:/Microsoft Visual Studio 8/VC/PlatformSDK/include/winnt.h(5940) : error C2146: syntax error : missing ';' before identifier 'Buffer'
1>D:/Microsoft Visual Studio 8/VC/PlatformSDK/include/winnt.h(5940) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:/Microsoft Visual Studio 8/VC/PlatformSDK/include/winnt.h(5940) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:/DX90SDK/Samples/C++/DirectShow/BaseClasses/ctlutil.h(278) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
2,在Tools->Options->Projects and solutions->vc++ directories->show directories for里选择include files
然后增加
D:/DX90SDK/Include
D:/DX90SDK/Samples/C++/DirectShow/BaseClasses
D:/DX90SDK/Samples/C++/Common
可能会问题依旧,调整一下include files的顺序吧,把他们都放在最上面(原文是都放在最后,但我认为应该放在最上面),例如我的环境:
D:/DX90SDK/Include
D:/DX90SDK/Samples/C++/DirectShow/BaseClasses
D:/DX90SDK/Samples/C++/Common
$(VCInstallDir)include
$(VCInstallDir)atlmfc/include
$(VCInstallDir)PlatformSDK/include
$(FrameworkSDKDir)include
然后在project->BaseClasses properties->configuration->C/C++ -> General->Additional Include Directories里面的内容(.,../../../../include)删掉,重新编译,PVOID64的错误消失,原因如下:
POINTER_64是一个宏,在64位编译下起作用,它包含在SDK目录下的BASETSD.H中(Microsoft Visual Studio 8/VC/PlatformSDK/Include/basetsd.h(23):#define POINTER_64 __ptr64),但DXSDK自己也带了一个basetsd.h,里面没有定义POINTER_64,从而导致出错,只需要改变include files的优先级即可。当然,也可以改写winnt.h中的代码,在下面这两行:typedef void *PVOID;
typedef void *POINTER_64 PVOID64;
之前增加一行:
#define POINTER_64 __ptr64
3,到目前为止,还剩下:
BaseClasses/ctlutil.h(278) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
这个错误,解决方法如下:
打开project->BaseClasses properties->configuration->C/C++ ->Command Line,增加/wd4430选项。
4,接着编译,提示error C2065: 'Count' : undeclared identifier等等错误,这个是微软的历史遗留问题了,C++标准语法的问题,因为在之前在for循环内定义的变量可以在for之外的地方使用,即在第一个for里for(int i,...),以后的for再使用i不必再声明,解决方法也很简单,打开project->BaseClasses properties->configuration->C/C++->Language->Force Comformance in For Loop Scrope设置为No即可。当然,也可以手动改代码,增加一个声明就是了。
经过上面几个步骤,应该是可以顺利编译了,对于其它版本的工程,照样设置就可以了,总共编译出下面4个文件备用:
BaseClasses/Debug/strmbasd.lib
BaseClasses/Debug_Unicode/strmbasd.lib
BaseClasses/Release/STRMBASE.lib
BaseClasses/Release_UnicodeSTRMBASE.lib
需要在Tools->Options->Projects and solutions->vc++ directories->show directories for->library files里把它们加进去。
赶快编译DX90SDK/Samples/C++/DirectShow/Players/PlayDMO工程试试看吧。
以上转自LGS的BLOG.
可能会遇到的一个问题
编译头文件 WXDebug.h 时可能会报错:
d:/dxsdk/samples/c++/directshow/baseclasses/wxdebug.h(334) : error C2146: syntax error : missing ';' before identifier 'm_pString'
1>d:/dxsdk/samples/c++/directshow/baseclasses/wxdebug.h(331) : error C2065: 'm_pString' : undeclared identifier
解决方法:在上面增加一句:typedef WCHAR *PTCHAR;
最后一点说明
使用OpenCV时可能会遇到一个警告:
1>final.obj : warning LNK4248: 无法解析 typeref 标记(01000029)(为“CvCapture”);映像可能无法这会导致你在分步调试时遇到问题,不过不用担心,运行时不会出问题.以前在外国网站上看到过解决这个警告的方法,有心的可以上Google搜搜.