版权声明:对于本博客所有原创文章,允许个人、教育和非商业目的使用,但务必保证文章的完整性且不作任何修改地以超链接形式注明原始作者、出处及本声明。
博客地址:http://blog.csdn.net/shuxiao9058
原始作者:季亚
当我们需要测试程序,或者想将程序发给其他同事或者同学,以让同事或者同学运行以测试程序性能或者逻辑是否恰当时,是不是还要他人也要像你当初开发程序时一样一步一步的配置OpenCV运行环境!?如果不做这些,还会提示像图1所示的系统错误(无法启动程序,因为计算机中丢失“opencv_highgui241d.dll。尝试重新安装该程序以解决此问题”),这是不是太麻烦了,其实我们可以将程序以静态链接的方式编译,如此便少去了配置运行时环境的步骤了。
图1 动态编译的程序在未配置OpenCV的机器上运行提示系统错误
静态编译,也就是说编译后的程序可以直接拷贝到其他机器上并能直接运行。而不需附带链接库和配置环境变量。
由于OpenCV自2.3.0版本开始就提供了OpenCV-2.3.x -win-superpack.exe或OpenCV-2.4.x.exe文件,该文件解压后我们会发里面有个名为“build”的文件夹,其中有各个平台的链接库,而且还提供了Windows平台下的静态链接库,本文主要讲述一个例子以说明如何配置使用该静态链接库。
像前面(OpenCV2.3.x/2.4.x在Visual Studio2005/2008和Visual Studio2010配置方法详解)放置OpenCV库文件配置VC++目录选项,并且配置环境变量(这一步可以不配置,但要在VC++目录中将OpenCV的“bin”目录添加到“VC++ 可执行文件”目录选项中),注意这里使用的库目录是“staticlib”而不是“lib”,这里不多赘述。
配置完Visual Studio 2008中的VC++目录后便可以编写代码了。
(1)编辑代码
“新建项目”,选择“Visual C++-空项目”,输入项目名“StaticOpenCV”,“添加新项-代码-C++ 文件”,输入文件名“StaticOpenCV.cpp”,编辑代码,这里本人使用的测试代码如下所示:
#include <opencv/highgui.h> int main( int argc, char** argv ) { IplImage*img = cvLoadImage( argv[1] ); cvNamedWindow("OpenCV", CV_WINDOW_AUTOSIZE ); cvShowImage("OpenCV", img ); cvWaitKey(0); cvReleaseImage(&img ); cvDestroyWindow("OpenCV" ); return( 0 ); }(2)添加附加依赖项有两种方法,见《 OpenCV 2.3.x/2.4.x在Visual Studio 2005/2008和Visual Studio 2010配置方法详解》一文。
OpenCV-2.4.1库文件列表(使用的时候适当选择,这里我要用的是libjasperd.lib、libjpegd.lib、libpngd.lib"、libtiffd.lib、zlibd.lib(注意这几个必须要用的,因为这些是OpenCV所使用的第三方库)和opencv_highgui241d.lib、opencv_core241d.lib库文件。
libjasper.lib libjasperd.lib libjpeg.lib libjpegd.lib libpng.lib libpngd.lib libtiff.lib libtiffd.lib opencv_calib3d241.lib opencv_calib3d241d.lib opencv_contrib241.lib opencv_contrib241d.lib opencv_core241.lib opencv_core241d.lib opencv_features2d241.lib opencv_features2d241d.lib opencv_ffmpeg241.dll opencv_flann241.lib opencv_flann241d.lib opencv_gpu241.lib opencv_gpu241d.lib opencv_haartraining_engine.lib opencv_haartraining_engined.lib opencv_highgui241.lib opencv_highgui241d.lib opencv_imgproc241.lib opencv_imgproc241d.lib opencv_legacy241.lib opencv_legacy241d.lib opencv_ml241.lib opencv_ml241d.lib opencv_nonfree241.lib opencv_nonfree241d.lib opencv_objdetect241.lib opencv_objdetect241d.lib opencv_photo241.lib opencv_photo241d.lib opencv_stitching241.lib opencv_stitching241d.lib opencv_ts241.lib opencv_ts241d.lib opencv_video241.lib opencv_video241d.lib opencv_videostab241.lib opencv_videostab241d.lib zlib.lib zlibd.lib
为方便我们知道到我们到底需要使用哪些库文件,这里我们使用《OpenCV2.3.x/2.4.x在Visual Studio2005/2008和Visual Studio2010配置方法详解》一文中所讲述的第二种方法添加程序依赖库。我们在头文件与主函数之间添加如下代码:
#pragma comment( lib,"libjasperd.lib" ) #pragma comment( lib,"libjpegd.lib" ) #pragma comment( lib,"libpngd.lib" ) #pragma comment( lib,"libtiffd.lib" ) #pragma comment( lib, "zlibd.lib") #pragma comment( lib,"opencv_highgui241d.lib" ) #pragma comment( lib,"opencv_core241d.lib" )编译程序,会发发现程序不能正常编译(错误如图2所示),这主要与MSVCRT.lib(MSVCR90.dll)有关。
图2 编译产生很多错误
经过查询相关资料可知,需要对项目属性进行如下配置:右击项目名称,选择“属性-配置属性-C/C++-代码生成”,这里我们发现“运行库”选项默认值选项为“多线程调试 DLL (/MDd)”,同时这里有四个选项(/MT,/MTd, /MD, /MDd),前两个一组,为静态链接运行时库,运行时不需要运行时库的支持,代码直接插入到程序中去;后两个一组,为动态链接运行时库,运行时需要MSVCR90.dll或MSVCP90.dll支持。
所以,这里我们将“运行库”选项设置为“多线程(/MT)”或“多线程调试(/MTd)”(注意你的编译模式(Debug还是Release)),如图3所示,设置完成全单击确定。
图3 将“运行库”选项设置为“多线程调试(/MTd)”
然后我们再次编译程序,发现还有两个错误,如图4所示。
图4 编译程序还有两个错误
这是因为我们的程序是win32程序的问题,我们还需要添加vfw32.lib和comctl32.lib这两个依赖库文件,最终代码如下所示:
#include <opencv/highgui.h> // 这几个依赖库文件必须要添加, // 因为这些是OpenCV所使用的第三方库 #pragma comment( lib, "libjasperd.lib" ) #pragma comment( lib, "libjpegd.lib" ) #pragma comment( lib, "libpngd.lib" ) #pragma comment( lib, "libtiffd.lib" ) #pragma comment( lib, "zlibd.lib" ) // 这里根据你的程序添加依赖库文件 #pragma comment( lib, "opencv_highgui241d.lib" ) #pragma comment( lib, "opencv_core241d.lib" ) // 添加这两个是因为win32程序 #pragma comment( lib, "vfw32.lib" ) #pragma comment( lib, "comctl32.lib" ) int main( int argc, char** argv ) { IplImage* img = cvLoadImage( argv[1] ); cvNamedWindow( "OpenCV", CV_WINDOW_AUTOSIZE ); cvShowImage( "OpenCV", img ); cvWaitKey(0); cvReleaseImage( &img ); cvDestroyWindow( "OpenCV" ); return ( 0 ); }
再次编译,成功了!!!此时,我们可以将编译后的执行程序复制到其他机器(没有配置OpenCV函数库及环境变量)以测试是否OK。
备注:
1.根据需要可能还需要忽略libcmt库;
2.静态编译后的可执行程序比动态编译后的可执行程序大得多;
3.不能静态编译C++版本的OpenCV程序,可能和VS有关;
4.参考链接:http://blog.csdn.net/shuxiao9058/article/details/7525067