【OpenCV3.3】编译源码并搭建VS2017+Windows开发环境

         OpenCV 3.3在8月3号正式Release,带来了许多优化改进和新特性,包括备受关注的深度神经网络(DNN)模块被正式引入主仓库,标志着OpenCV对DNN有了更深层次的优化与支持; 支持通过宏ENABLE_CXX11启用对C++ 11特性的支持;默认包含大量SSE4.X和AVX/AVX2指令集优化;内置Intel IPP版本升级至2017.2,官方测试显示有近15%的性能提升...等等,更多细节可以参考http://opencv.org/opencv-3-3.html,另外如果你现有代码基于OpenCV 3.x的话,建议进行版本升级~

        编译OpenCV的源码并不复杂,或者说十分简单(相对于部分老项目而言),并且对Visual Studio的支持也很友好,但首次编译的话对整个流程以及过程中一些开关可能会存在一些疑问。如果你不想自行编译也可以使用官方预编译好的文件,但是有些模块可能是用不到的,所以我们还是希望能尽可能自定义模块。

        本文假设读者已经安装了 CMake 和 Python (2.x或3.x)

     一、准备资源

  1. opencv-3.3.0-vc14.exe,建议使用sourceforge下载,因为相比github这玩意有直链并且有不同镜像可选,可以直接使用第三方下载器下载,速度比较快。

     二、准备源码

         直接运行下载好的exe,选择解压到的目录,并提取sources文件夹,目录结构大概如下:


     三、生成项目

         打开CMake GUI,设定好目录选择Configure,然后选好IDE(Visual Studio 2017 WIN64)并Finish,等待初始配置完成(生成cvconfig.h)...


         正常情况下直到Configuring done是不会发生错误的,然后上面配置项是红色的,提示有些东西需要人工改动,基本步骤就是查看输出,如果发现有外部库找不到,比如"A library with XXX API not found"或者"Could NOT find XXX (missing XXX)"之类的,根据需求把相应的库的路径加上,或者不需要的话直接去掉相关依赖的编译,还可以做到0 warnings多好的事情~

         这里大概有几个提示:

  1. 首先因为我们是当成库使用,不会去调试OpenCV本身,所以把和最后开发无关的开关关掉,比如BUILD_DOCS,BUILD_EXAMPLES,BUILD_XXX_TESTS,BUILD_opencv_ts(一些单元测试代码),BUILD_PACKAGE (CPACK_BINARY_XXX,CPACK_SOURCE_XXX),INSTALL_XXX
  2. 前面说了C++ 11特性支持,当然是选择打开它,ENABLE_CXX11
  3. 为了方便项目配置和调试,在生产环境中建议打开BUILD_opencv_world,把各OpenCV模块编译成一个世界模块,这样最后生成的只有一个.lib或者.dll(后者需要打开BUILD_SHARED_LIBS开关),但在发行版本中建议按需引入相应模块以减少体积(除非你每个模块都有使用到)。
  4. 如果你不涉及音视频处理,可以关掉相关模块,大概包括BUILD_opencv_video,BUILD_opencv_videoio,BUILD_opencv_videostab,WITH_1394,WITH_GSTREAMER_XXX

部分编译开关解释

模块 功能
BUILD_opencv_superres 基于视频的图像超分辨率重建,通过系列低分辨率图像得到高分辨率图像,http://www.docs.opencv.org/3.3.0/d7/d0a/group__superres.html,这里附上两篇很好玩的文章,小心开车,提高驾驶技术:用GAN去除(爱情)动作片中的马赛克和衣服用一个玩具例子说明基于视频的超分辨率重建的基本思想
BUILD_JASPER 编译3rdparty/libjasper项目用于 JPEG-2000 图像编解码支持,http://www.ece.uvic.ca/~frodo/jasper/
BUILD_OPENEXR 编译3rdparty/openexr项目用于 HDR 图像编解码支持,http://www.openexr.com/
WIHT_IPP 添加Intel IPP算法加速支持,包含SSE、AVX/AVX2等SIMD系列指令集优化以及Intel的黑科技,在AMD核上同样可用,但是加速效果不如Intel CPU明显
WIHT_IPP_A 添加Intel® IPP Asynchronous C/C++异步支持,非内置需要额外安装,http://docs.opencv.org/master/dc/d0e/tutorial_how_to_use_ippa_conversion.html
BUILD_IPP_IW 编译Intel IPP集成包装,Intel(R) Integrated Performance Primitives Integration Wrappers
BUILD_ITT / WITH_ITT 编译/添加Intel® Instrumentation and Tracing Technology (Intel® ITT)支持,代码性能检测用,比如游戏开发中关键性能数据收集,因为ITT API 有开销,不需要的可以关闭
WITH_LAPACK 添加线性代数软件包LAPACK(Linear Algebra PACKage)支持,其包含了大部分计算科学中常见的数值线性代数问题求解支持,依赖于基本线性代数运算库BLAS (Basic Linear Algebra Subprograms),并未内置
WITH_1394 添加对计算机标准接口IEEE1394的支持,俗称火线接口,是由APPLE和TI公司开始的高速串行接口标准,主要用于视频的采集,在INTEL高端主板与数码摄像机(DV)上可见
WITH_EIGEN 添加C++线性代数模版库Eigen(C++ template library for linear algebra)的支持,其包含矩阵、向量、矢量数值运算、数值分析及相关线性代数算法
WITH_GSTREAMER 添加开源多媒体框架GStreamer(open source multimedia framework)的支持,其目标在于简化音/视频应用程序开发,支持范围从简单的Ogg/Vorbis音频播放、音/视频流技术到复杂的混合音频、视频(非线性编辑)处理等
WITH_VTK 添加可视化开发工具包VTK(The Visualization Toolkit)的支持,依赖自三维可视化引擎模块opencv_viz
OPENCV_ENABLE_NONFREE 启用专利保护算法的支持,如SIFT和SURF,从功能上来说这两个算法属于opencv_features2d模块,但由于它们都是受专利保护的,想在项目中可能需要专利方许可)
部分OpenCV模块介绍

模块 功能
opencv_core 包含核心功能尤其是底层数据结构和算法实现,定义基本数据结构(包括重要的Mat)及被其他模块所使用的基本函数
opencv_imgproc 即Image Processing图像处理,包括滤波(线性、非线性)、几何变换、颜色空间变换、直方图、形状描述子等
opencv_highgui 高层用户接口(UI)及与QT框架的整合,包含读写图像、视频以及操作用户图形界面相关的函数
opencv_imgcodecs 编解码图像的封装接口,支持的格式取决于编译时指定的解码器,比如BUILD_TIFF打开对TIFF图像的编解码支持
opencv_feature2d 用于2D特征检测(角点对象和平面对象)、特征描述与匹配,包含各种接口统一的特征值检测器及描述子
opencv_calib3d 摄像机校准,包含相机标定(去除相机自身缺陷导致的画面形变),3D信息重建,姿态估计,双目几何及立体视觉函数等
opencv_photo 包含计算摄影学,涉及修复/去噪/高动态范围(HDR)图像等
opencv_stitching 用于图像拼接、制作全景图
opencv_videoio 对于视频捕获和视频编码器是一个易用接口
opencv_videostab Video Stabilization,视频稳像
opencv_video 提供视频分析功能(运动分析估计、背景分离、目标跟踪、卡尔曼滤波等)
opencv_objdetect 用于对象检测,包含Haar分类器、SVM检测器、文字检测以及预定义检测器实例(例如人脸、眼、车等检测)
opencv_ml 机器学习模块,包括统计模型、K最近邻、支持向量机、决策树、神经网络等经典的机器学习算法。
opencv_flann Fast Library for Approximate Nearest Neighbors,最近邻库,包含聚类(K-means)、搜索(KDTree)和计算几何等
opencv_shape 形状距离和匹配算法模块,用于描述形状、比较形状,依赖于opencv_video
opencv_superres 基于视频的超分辨率重建,即从许多帧连续的低分辨率图像中重建出高分辨率图像,恢复单帧低分辨率图像中丢掉的细节
opencv_dnn 深度神经网络,参考官方文档Deep-Learning-in-OpenCV

        知道了上述内容也就对OpenCV整体框架有所了解了,自定义完OpenCV编译模块后我们再次点击Configure修改配置CMake应该就没错误输出也不显示红色了,然后点击Generate生成VS2017项目文件,最后Open Project打开就能回到熟悉的VS环境中了,直接右键解决方案等它Build完就好了(ps: 生成的文件放在 build\lib\ 和 build\bin\ 目录下,最后通过INSTALL这个项目把相关文件(.h、.dll、.lib等)拷贝到CMAKE_INSTALL_PREFIX目录,如果你没有Build INSTALL这个项目是不会拷贝的,跟make之后没执行make install情况一样)。


     四、项目配置

        VS作为几乎公认的宇宙最强IDE大笑,在项目配置上具有十分友好的用户接口,支持导出项目模版或者继承项目属性表.props,避免项目的重新配置以及过度依赖系统环境变量。因为继承项目属性表方式相对而言比较灵活,这里大概讲讲怎样配置一个OpenCV的公共项目属性表,以后新建项目或者移动OpenCV目录只需要引用或者修改这个文件就行了,不需要改动其它配置。

  1. 在VS主界面选择View->Property Manager打开属性管理器视图,选择你要配置的任一个项目,选中全部配置(Debug & Release,这是为了让全部配置都继承同一个属性表),右键,在弹出的框选择Add New Project Property Sheet进行新建属性表 (可以看到引用现有属性表操作类似,但是我们还没有属性表,所以得新建一个):
  2. 然后右键我们刚才新建的属性表打开属性设置,可以看到和项目属性设置界面差不多,就是多了个User Macros,这是用来添加自定义变量的,我们随便添加一个OPENCV_INSTALL_DIR,结果如下:

  3. 接着在VC++ Directories分别设置IncludeLibrary目录 (Evaluated value如果没显示出路径,请检查上一步操作添加的变量名是否正确保存了;此外记得勾选从父项目继承,Inherit from parent or project defaults):
    Include目录: $(OPENCV_INSTALL_DIR)\include
    Library目录: $(OPENCV_INSTALL_DIR)\$(PlatformShortName)\vc15\lib  (vc15比较坑,因为并没有宏的值是vc15或15)

    Include目录配置示例

    Library目录配置示例

  4. 最后记得保存就好了,以后新项目只需要引用刚才新建的属性表就好了。然后在项目中引用相应的lib,但是lib有两种版本,这里提供一个很方便的宏:
    #ifdef _DEBUG
    # define RLIB_IMPORT_LIBRARY(a)       __pragma(comment(lib, a "d.lib"))
    #else
    # define RLIB_IMPORT_LIBRARY(a)       __pragma(comment(lib, a ".lib"))
    #endif // _DEBUG
    
    // 用法如下
    RLIB_IMPORT_LIBRARY("opencv_world320") // world 其实是 All In One
    // RLIB_IMPORT_LIBRARY("opencv_core330")
    // RLIB_IMPORT_LIBRARY("opencv_highgui330")
    // RLIB_IMPORT_LIBRARY("opencv_imgproc330")
    // RLIB_IMPORT_LIBRARY("opencv_imgcodecs330")
    // RLIB_IMPORT_LIBRARY("opencv_features2d330")
    // RLIB_IMPORT_LIBRARY("opencv_calib3d330")
    // RLIB_IMPORT_LIBRARY("opencv_objdetect330")
    
    最后一个问题就是如果你编译的不是静态库而是DLL的话,建议把路径 D:\OpenCV3.3\build\install\x64\vc15\bin 加到系统环境变量PATH里,方便调试,省得每次拷贝DLL到应用程序目录。

     五、参考文献

          太多了,这里就不一一列举了,衷心感谢相关作者的分享。


阅读更多

没有更多推荐了,返回首页