By狗头军师猪千戒DoggerAndPiggerJeffery第1页共12页使用VS2015编译以及静态编译opencv3记录一直不知道怎样静态编译opencv并连接使用,网上的教程很零散,这里做个总结记录。下载opencv3gitclone打开CMAKE-GUI,选择源码路径和构建路径点击configure,选择合适的编译器,有两个选项可选,x86以及x64。编译两个版本的时候需要分别选择。点击Finish后By狗头军师猪千戒DoggerAndPiggerJeffery第2页共12页取消以下的一些选项上边是对应于编译动态链接库版本的,如果编译静态链接库版本,需要取消以下选项为了opencv的最终生成的库打包成一个world,需要选择如下选项最后点击generate即可在VS2015里点击生成,批生成By狗头军师猪千戒DoggerAndPiggerJeffery第3页共12页选择如上两个INSTALL,点击生成。然后再到目录下边查看install目录即可把文件复制到指定目录,然后把x86/vc14/bin添加到path里。下边记录使用静态编译以及动态链接库的不同一般来说,一旦在cmake设置了BUILD_SHARE_LIBRARY选项,就是要编译dll,此时,在VS2015里,对于各个编译的解决方案,有的是编译成lib,有的是dll,譬如如下两项他们在代码生成都是MDd(Debug),MD(release)也就是vs2015的组件也是动态链接的。By狗头军师猪千戒DoggerAndPiggerJeffery第4页共12页而库的生成方式有同时也有一些是编译成静态库,但是这些配置不统一,最后出来的用的是动态链接的库。此时不能随意更改选项,我原来这里以为改了选项就可以编译成静态库,这样是会编译错误的,因为cmake配置好的是动态库的选项。如果需要配置静态库的选项,则需要重新运行cmake,取消如下选项,这个时候,所有的代码生成配置就是MTd,或者MT。也就是说VS2015的组件库是静态链接进去的,在裸机上不会提示说缺少vsxxx140d.dll之类。By狗头军师猪千戒DoggerAndPiggerJeffery第5页共12页这个时候,可以发现所有都是lib静态库配置编译完成后,静态库会在staticlib文件夹中出现而动态编译的时候,则出现By狗头军师猪千戒DoggerAndPiggerJeffery第6页共12页在bin目录会出现opencv的dllBy狗头军师猪千戒DoggerAndPiggerJeffery第7页共12页对于在实际编程后配置的时候如果是静态的配置,单击右键,属性设置如图所示的包含目录以及库目录,如果是用到静态库,就包含staticlib,如果是用到动态库,就只包含lib,同时包含会出现问题。特别是在这两个文件夹里都有相同名字的时候,链接器没有那么聪明。By狗头军师猪千戒DoggerAndPiggerJeffery第8页共12页然后设置附加依赖项对于我这种情形,静态编译如果是debug,写入ippicvmt.libopencv_ts310d.libopencv_world310d.libIlmImfd.liblibjasperd.liblibjpegd.liblibpngd.liblibtiffd.liblibwebpd.libZlibd.lib静态编译如果是release写入opencv_ts310.libopencv_world310.libIlmImf.liblibjasper.liblibjpeg.liblibpng.liblibtiff.liblibwebp.libzlib.libBy狗头军师猪千戒DoggerAndPiggerJeffery第9页共12页如果同时把两个加在一起,在动态链接编译的时候是不会有问题的,但是静态编译会出现问题,假如某个版本的库放在前面,比如是debug,如果编译release,那么因为debug的库在前面,会去连接debug的库,结果出现版本错误。此时,还需要设置解决方案的代码生成如果是release,则选择MT然后编译即可。对于动态的情形,我这里在依赖项里只是添加如下四项即可。opencv_ts310d.libopencv_world310d.libopencv_ts310.libopencv_world310.lib具体情况取决于编译出来文件夹里有什么。X64的配置基本一样,只是在cmake选择编译器的时候不同而已。附上一段测试样例,计算DFT://CVL_5_5_dft.cpp:定义控制台应用程序的入口点。//OPENCV3.0离散傅里叶变换显示变换后幅值示例程序//进行傅里叶变换的图像一般都使用灰度图像/*基本步骤:1、使用getOptimalDFTSize函数获取最佳DFT的行列数2、使用copyMakeBorder函数给原图像添加0边到最佳DFT的行列数3、声明多通道数组并融合,然后调用dft函数,最后在分离通道4、把两个通道的值使用magnitude函数求幅值5、对变换后图像加1后log6、去除变换后图像的奇数行列,使得图像只有偶数行列7、以中点分隔图像区域为四块,重新排列图像,使得中心点为原点*/By狗头军师猪千戒DoggerAndPiggerJeffery第10页共12页#includestdafx.h#includeopencv2/opencv.hppusingnamespacecv;intmain(){MatsrcImage=imread(src.jpg,CV_LOAD_IMAGE_GRAYSCALE);if(!srcImage.data)return-1;namedWindow(原始图像,WINDOW_NORMAL);imshow(原始图像,srcImage);intm=getOptimalDFTSize(srcImage.rows);intn=getOptimalDFTSize(srcImage.cols);Matpadded;copyMakeBorder(srcImage,padded,0,m-srcImage.rows,0,n-srcImage.cols,BORDER_CONSTANT,Scalar::all(0));Matplanes[]={Mat_float(padded),Mat::zeros(padded.size(),CV_32F)};MatcomplexI;merge(planes,2,complexI);dft(complexI,complexI);split(complexI,planes);MatmagnitudeImage;magnitude(planes[0],planes[1],planes[0]);magnitudeImage=planes[0];magnitudeImage+=Scalar::all(1);log(magnitudeImage,magnitudeImage);//保证奇数行和奇数列magnitudeImage=magnitudeImage(Rect(0,0,magnitudeImage.cols&-2,magnitudeImage.rows&-2));intcx=magnitudeImage.cols/2;intcy=magnitudeImage.rows/2;Matp0(magnitudeImage(Rect(0,0,cx,cy)));Matp1(magnitudeImage(Rect(cx,0,cx,cy)));Matp2(magnitudeImage(Rect(0,cy,cx,cy)));Matp3(magnitudeImage(Rect(cx,cy,cx,cy)));Matptemp;p0.copyTo(ptemp);p3.copyTo(p0);ptemp.copyTo(p3);p1.copyTo(ptemp);p2.copyTo(p1);ptemp.copyTo(p2);normalize(magnitudeImage,magnitudeImage,0,1,NORM_MINMAX);namedWindow(频谱幅值,WINDOW_NORMAL);By狗头军师猪千戒DoggerAndPiggerJeffery第11页共12页imshow(频谱幅值,magnitudeImage);waitKey();return0;}在xp虚拟机上静态编译测试,当然这里要设置编译器为兼容xp那个,发现程序大小比较大,运行没有提示缺少dll:By狗头军师猪千戒DoggerAndPiggerJeffery第12页共12页在静态编译的时候,连接的时候需要时间长一点,平时用动态链接测试,需要发布的时候再静态编译。