OpenCV 4.4.0源码编译指南:从CMake配置到项目集成全流程

OpenCV 4.4.0源码编译指南:从CMake配置到项目集成全流程 简介OpenCV 4.4.0 的 Windows 编译配套资源面向需要在 VS2015 下生成 x64 库的 C/图像处理开发者解决 OpenCV 源码编译时第三方依赖下载失败、库文件不齐导致环境搭建受阻的问题。压缩包共 575 个文件约 156.61MB以 hpp/h 头文件、dll/lib 运行库、cmake 配置脚本为主另有 ippicv、FFmpeg 插件、ADE、人脸关键点模型等官方下载组件可配合源码完成离线编译与配置。内含基于 VS2015 编译生成的 x64 位库文件涵盖常用头文件、动态库、静态库及 OpenCVModules 等 CMake 配置复制到工程即可引用省去自行编译的漫长等待与踩坑。已有 562 人浏览学习适合需要快速获得可用 OpenCV 4.4.0 运行环境或对照编译过程的开发者。1. 为什么放着官方包不用非要自己编译先把结论放在前面OpenCV 4.4.0的官方Release页面Windows用户直接下载那个几百MB的exe或者zip包解压之后有include目录、lib目录和一堆动态库配好环境就能跑整个过程五分钟结束。那为什么还有那么多人放着现成的包不用非要去源码编译一遍原因很简单官方预编译包满足不了所有人的需求。这个包默认只编译了最常用的一批模块很多功能默认是关闭的。比如SIFT这种受专利保护的特征算法官方包默认不带比如你想用CUDA做GPU加速官方包没有再比如你想看一眼OpenCV内部某个函数的实现带着断点跟进去官方Release包根本没有调试符号完全没法跟。这些场景下源码编译是唯一的选择。另外官方预编译包的编译选项是固定的它是一个通用配置为了兼容绝大多数机器很多指令集优化没有被启用。而你自己编译的时候可以针对当前机器的CPU启用AVX2、AVX512这些指令集优化实测下来某些图像处理函数的性能能提不少。做算法验证、做嵌入式移植、做二次开发的工程师基本都逃不掉自己编译这一步。这篇把OpenCV 4.4.0从源码下载、依赖准备、CMake配置、编译执行到最终拿到库文件并集成进项目的全过程从头到尾过一遍。内容适用Windows和Linux两个平台重点说Windows因为Windows上踩坑的概率比Linux大得多——Linux下包管理装依赖方便基本是apt install一条命令的事Windows下各种依赖和路径问题能把人折腾到怀疑人生。2. 下载源码和准备依赖环境2.1 源码从哪里拿OpenCV 4.4.0这个版本正式发布时间是2020年年中属于4.x系列里比较稳定的一个版本。拿源码有三种方式GitHub Releases页面在opencv/opencv仓库的Releases标签下找到4.4.0下载Source code (tar.gz)或Source code (zip)。这是最推荐的方式因为Release包是打了tag的源码状态是确定的。官网opencv.org主页有Releases入口点进去能找到对应版本。官网下载页现在对老版本的支持做得很差很多历史版本的链接都指向GitHub了。Git克隆git clone https://github.com/opencv/opencv.git然后git checkout 4.4.0。这种方式适合你后面想自己改源码、经常拉更新的情况纯编译一次的话没必要。这里有一个非常重要的细节如果你需要用到opencv_contrib扩展模块仓库包含人脸识别、文本检测、xfeatures2d等非核心功能模块你必须下载和主仓库版本完全一致的opencv_contrib然后编译时通过OPENCV_EXTRA_MODULES_PATH指向它的modules目录。版本对不上编译时大概率直接报错报错信息还很不友好——这一条经验我是靠踩坑换来的第一次搞的时候图省事随便拉了个最新版contrib配4.4.0编译到一半直接崩掉排查半天才反应过来是版本不匹配。2.2 编译工具链和依赖源码级别的编译工具链是绕不开的。Windows平台下核心组件是三件套Visual StudioVS2015/2017/2019都可以个人推荐VS2019对CMake的支持最成熟。注意安装的时候要选上使用C的桌面开发工作负载不然编译器都没有。CMake建议3.16以上版本。下载Windows安装版安装时勾选Add CMake to system PATH省去手动配环境变量的麻烦。Python如果你需要生成Python版本的OpenCV绑定也就是import cv2能用的那个cv2.pyd需要安装Python 3.6以上版本并且安装时要勾选Add Python to PATH。Linux平台下则是另一套组合gcc/g 7、cmake、make、pkg-config。Ubuntu/Debian系统直接sudo apt update sudo apt install build-essential cmake pkg-config如果要GUI显示图片的功能还要装GTK开发包sudo apt install libgtk2.0-dev这里要特别提一个容易忽略的点OpenCV 4.x要求C11标准所以太老的编译器不支持。Linux上如果系统自带的GCC版本偏低比如CentOS 7默认的GCC 4.8编译时会出现各种莫名其妙的语法报错——因为GCC 4.8的C11支持并不完整。解决方案是升级GCC或者用devtoolset总之别在编译器版本上死磕。2.3 一个值得注意的目录结构源码解压后先花一分钟看一下目录结构。核心内容都在opencv-4.4.0/ ├── CMakeLists.txt # 顶层CMake配置整个编译的入口 ├── modules/ # 核心模块源码core、imgproc、highgui等都在这里 ├── platforms/ # 各平台的编译配置脚本 ├── samples/ # 官方示例代码 ├── doc/ # 文档 └── 3rdparty/ # 第三方依赖源码比如libjpeg、libpng通常不建议直接在源码根目录里创建build目录虽然很多人习惯这么干。更干净的做法是单独建一个build目录mkdir build cd build。这样生成的临时文件、CMake缓存、编译中间产物都在build目录里和源码完全隔离想重新编译的时候把build目录一删重新来就是源码还是干净的。3. CMake配置决定库文件长什么样的关键一步3.1 核心选项逐个数CMake配置本质上是生成一套编译规则。不管你是用cmake-gui的图形界面还是命令行下面这些选项的意义必须搞清楚因为最终生成的库文件是什么形态完全由这些选项决定。先看最核心的五个CMAKE_BUILD_TYPERelease还是Debug。Release编译优化充分生成的库体积小、速度快但没法断点调试Debug生成的库体积大、速度慢但带着完整的调试信息能跟着代码走。日常开发建议两个版本都编一遍Release用于交付部署Debug用于调试。CMAKE_INSTALL_PREFIX安装路径。这是最容易忽略但最重要的选项——编译完成后执行install头文件和库文件会被统一放到这个目录下。不设的话Windows默认是C:/opencv-build建议改成一个自己好记的路径比如D:/opencv-4.4.0-install。BUILD_SHARED_LIBS这个选项决定生成动态库还是静态库。动态库就是Windows下的opencv_world440.dll 一个导入库.lib运行时需要dll在PATH里静态库是.lib文件链接时把代码直接嵌入exe里部署时不用带一堆dll但最终exe体积会大不少而且链接时容易遇到依赖传递的问题后面细说。官方预编译包默认是动态库。BUILD_EXAMPLES和BUILD_TESTS这两个默认是OFF建议保持OFF。开着会编译大量示例程序和测试用例白白增加几十分钟编译时间而且OpenCV的示例代码量非常大编译过程中产生大量警告和错误看了心烦。OPENCV_EXTRA_MODULES_PATH如果你下载了opencv_contrib这里填它modules目录的绝对路径。之后CMake会自动扫描这个目录下的所有模块作为扩展模块参与编译。3.2 和Python绑定有关的几个选项如果你需要Python版本的OpenCV下面这些要留意BUILD_opencv_python2Python 2绑定现在基本用不到了关掉。BUILD_opencv_python3Python 3绑定打开。PYTHON3_EXECUTABLE如果系统里有多个Python版本这里要手动指定用哪个。CMake有时候会自作聪明选错版本编出来的cv2装不上大概率就是这里没查。很多人在ANACONDA环境里编译OpenCV装了anaconda之后CMake经常自动定位到conda的Python然后编出来的cv2.pyd放到了conda目录下。如果你用的是系统Python配置的时候注意检查这三个变量到底指向了哪里。3.3 按需裁剪不要让所有模块全量编译Windows下CMake配置时会列出形如BUILD_opencv_core、BUILD_opencv_imgproc、BUILD_opencv_highgui这类开关——这是OpenCV各个子模块的编译开关默认全是ON。全量编译的最大问题是编译时间长更麻烦的是每个模块都会拖入一堆第三方依赖编译时任何一环出问题都要排查半天。我的建议是按照自己的实际需求裁减。比如传统图像处理为主的项目core、imgproc、highgui、imgcodecs、videoio这几个就够了做摄像头人脸识别再加上objdetect、face就够了目标检测、深度学习推理的场景才需要dnn模块。举一个典型的裁减配置cmake -DBUILD_opencv_calib3dOFF \ -DBUILD_opencv_dnnOFF \ -DBUILD_opencv_features2dOFF \ -DBUILD_opencv_flannOFF \ -DBUILD_opencv_javaOFF \ -DBUILD_opencv_jsOFF \ -DBUILD_opencv_python2OFF \ -DBUILD_opencv_python3ON \ -DBUILD_opencv_stitchingOFF \ -DBUILD_opencv_superresOFF \ -DBUILD_opencv_tsOFF \ -DBUILD_opencv_videostabOFF \ ..这样编出来的库从原来的几百MB缩到几十MB编译时间也大幅度缩短特别是对只做边缘检测、轮廓提取、图像预处理这类基础操作的人来说十几个模块完全没必要。3.4 其他值得关注的选项WITH_OPENCL启用OpenCL可以让OpenCV在支持OpenCL的GPU/集显上自动加速部分操作。默认开启问题不大但如果你的目标机器没有OpenCL环境运行时反而会有兼容性问题。嵌入式场景建议关掉。WITH_IPPIntel的IPP加速库OpenCV 4.4.0默认是会自动下载并启用的。官方下载页面被很多用户诟病下载慢的问题有一部分就是IPP拖慢的。编译网络不好的时候可以在CMake里加-DWITH_IPPOFF效果只是部分图像处理函数性能略微下降不影响正常使用。OPENCV_ENABLE_NONFREE这个选项控制SIFT、SURF等算法的编译。如果你在4.4.0上想用xfeatures2d模块里的SIFT必须打开这个选项否则CMake会明确拒绝。官方包默认是关闭的这也是刚才说官方包满足不了需求的一个典型例子。配置完成之后CMake会输出一份配置摘要显示哪些模块被启用、哪些第三方库被检测到、Python绑定是否生成等。建议花一分钟认真读一遍很多问题在配置阶段就能发现。4. 编译执行与库文件产物分析4.1 开始编译注意并行核数CMake配置完成后进入build目录开始编译。Windows的命令行方式cmake --build . --config Release --parallel 8Linux下make -j8这里的-j8是并行编译的核数8表示同时启动8个编译任务。理论上核数越多编译越快但有一个实际问题并行数太高容易把内存吃满。OpenCV的每个编译单元都比较重源文件大、头文件多12核的机器上-j12编译时内存占用能到10GB以上内存不够就直接卡死或者编译进程被杀。8GB内存的台式机建议-j416GB以上再考虑-j8。编译时间的量级给个参考全量编译Release版本8核CPU大概30到45分钟只编core、imgproc、highgui这几个核心模块的话10多分钟就能跑完Debug版本编译时间大概是Release的两倍。编译过程中屏幕上会刷大量编译日志不用全看但如果出现error:字样的行就要停下来处理。一个很实用的经验是保存一份完整的编译日志命令是cmake --build . --config Release 21 | tee build.logLinux或者重定向到文件Windows PowerShell。出问题排查的时候翻日志比重新编译一次省事太多。4.2 编译完成后一路到库文件编译成功后库文件已经出现在build目录里了但这还不是最终交付的形态。还需要执行安装步骤Windows:cmake --install . --config ReleaseLinux:sudo make install执行完这一步之前设置的CMAKE_INSTALL_PREFIX目录下会出现完整的交付结构。这是我推荐手动配置安装路径的根本原因——不需要去一堆build临时目录里翻找头文件和库官方安装目录的结构清晰多了。Windows下安装目录结构D:/opencv-4.4.0-install/ ├── include/opencv2/ # 所有头文件 └── x64/ └── vc15/ ├── lib/ │ ├── opencv_world440.lib # 动态库的导入库 │ └── opencv_world440d.lib # Debug版本名字多一个d ├── bin/ │ ├── opencv_world440.dll # 运行时动态库 │ └── opencv_world440d.dll └── staticlib/ # 如果你开了静态库选项 ├── opencv_core.lib ├── opencv_imgproc.lib └── ...注意一个细节Windows下动态库模式所有模块合并成了一个opencv_world440.dll也就是所谓的world模式。Release版叫opencv_world440Debug版叫opencv_world440d——这个d后缀很重要很多人在Debug模式下链接了Release的lib结果一堆运行时错误。Linux下安装目录结构则是另一种风格/usr/local/ ├── include/opencv4/opencv2/ # 头文件 └── lib/ ├── libopencv_core.so.4.4.0 ├── libopencv_core.so.4.4 ├── libopencv_core.so # 软链接 ├── libopencv_imgproc.so.4.4.0 ├── libopencv_imgproc.so.4.4 ├── libopencv_imgproc.so └── ...Linux下每个模块对应一个独立的so文件没有Windows那种world合并模式。另外CMake的配置文件OpenCVConfig.cmake会同时被安装到lib/cmake/opencv4目录下这就是后续find_package(OpenCV)能工作的基础。4.3 把库文件集成进你的项目拿到库之后怎么把它用起来是最后一步。Windows Visual Studio项目项目属性 - VC目录 - 包含目录加上D:/opencv-4.4.0-install/includeVC目录 - 库目录加上D:/opencv-4.4.0-install/x64/vc15/lib链接器 - 输入 - 附加依赖项Release加opencv_world440.libDebug加opencv_world440d.lib运行时把opencv_world440.dll复制到exe同目录或者把bin目录加入PATHLinux CMake项目则简单得多。在CMakeLists.txt里cmake_minimum_required(VERSION 3.10) project(test_opencv) find_package(OpenCV 4.4 REQUIRED) add_executable(test main.cpp) target_link_libraries(test ${OpenCV_LIBS})然后编译mkdir build cd build cmake .. makefind_package会自动配置头文件路径和库文件链接前提是之前编译时生成的OpenCVConfig.cmake还在安装目录里。如果是自己手动指定的安装前缀比如安装到了/opt/opencv可以用-DOpenCV_DIR/opt/opencv/lib/cmake/opencv4来指定配置文件位置。5. 编译中的常见问题与排查记录5.1 编译阶段的经典报错错误1编译到一半报错提示缺少boostdesc_bgm.i、vgg_generated_120.i这类文件。这个问题出现在编译contrib模块的xfeatures2d时本质是OpenCV为了规避某些算法的专利问题没有把训练数据直接放进源码仓库而是放在一个单独的受控仓库里。解决方案有两种一是打开OPENCV_ENABLE_NONFREE选项并确保网络通畅让CMake自动下载二是手动下载这些.i文件放到对应的opencv_contrib/modules/xfeatures2d/src目录下。这个问题在网络受限的环境下最常见很多内网开发的用户都栽在这里。错误2编译过程中直接报C compiler cannot create executables编译器无法创建可执行文件。这类问题优先级最高因为它是编译器自身的环境问题。最常见的原因是Visual Studio没有安装完全缺少使用C的桌面开发组件只有C#组件。另一个更隐蔽的原因是杀毒软件拦截了编译器进程尤其是某些国产杀毒和360全家桶把cl.exe当作可疑进程直接杀掉。建议编译前把源码目录和build目录加入白名单或者临时关掉实时防护。错误3configure阶段报Could NOT find PythonInterp。装了Python但CMake没检测到。排查思路确认Python确实装到了系统PATH里然后检查CMake版本是否足够新3.16对Python 3.8/3.9的检测比较准最后实在不行就在CMake命令行里手动指定-DPYTHON3_EXECUTABLEC:/Users/xxx/AppData/Local/Programs/Python/Python39/python.exe -DPYTHON3_INCLUDE_DIRC:/Users/xxx/AppData/Local/Programs/Python/Python39/include -DPYTHON3_LIBRARYC:/Users/xxx/AppData/Local/Programs/Python/Python39/libs/python39.lib5.2 链接运行阶段的常见问题链接错误无法打开opencv_world440.lib或LNK1181。这是Windows新手最容易遇到的报错。大部分情况下是VS项目的库目录没配好或者设置完属性没有点应用。注意VC目录里配了库目录、链接器输入里没加lib文件名也会报这个错。还有一个坑VS配置页面里平台选错了——你配的是x64但当前编译配置是Win32库目录自然找不到x64的lib文件解决方法是把解决方案平台从Win32切到x64。运行时错误找不到opencv_world440.dll。这个报错通常是exe编译链接成功后运行时弹出来的。dll在库目录里但不被系统找到因为Windows搜索dll的默认路径不包含库目录。把dll复制到exe同目录是最省事的方式也可以把bin目录加入系统PATH环境变量。注意Debug模式下编译的exe要带opencv_world440d.dll两边的dll混用会直接崩溃。Linux下链接时一堆unresolved external symbol。静态库模式下这个问题频繁发生。原因是OpenCV静态库依赖一些系统库比如pthread、dl、zlib而静态库本身不会主动传递这些依赖需要使用者自己手动链接。解决方案target_link_libraries(test ${OpenCV_LIBS} pthread dl z)如果还不满足可以在CMake里开启OPENCV_EXTRA_LIBS自动传递第三方依赖但需要保证OpenCV编译时检测到了这些库。Python环境里import cv2报ModuleNotFoundError。编译生成了cv2.pyd但Python导入不到。先确认cv2.pyd被安装到了哪里一般是Lib/site-packages下再确认当前使用的Python解释器和编译时配置的Python是同一个。Anaconda环境里这是重灾区conda的base环境、虚拟环境、系统Python三个Python版本同时存在很容易搞混。5.3 几个省时间的实用技巧最后分享几个编译OpenCV时的实用技巧这些是翻官方文档查不到的内容技巧一善用cmake-gui。第一次配置OpenCV时用图形界面把选项看一遍搞清楚每个选项什么意思再动手。命令行配置虽然也能完成但不够直观有些选项不知道叫什么名字图形界面天然有搜索功能输入关键词就能定位。第一遍配置好之后后续的命令行配置就简单了。技巧二编译前先确认磁盘空间。OpenCV编译过程的临时文件很大Release全量编译需要10GB以上空间Debug版本翻倍。磁盘不够会导致编译到一半报no space left on device这种错误最容易让人崩溃。技巧三不要用公司内网或虚拟机的共享文件夹做编译目录。编译过程中有大量小文件读写网络存储和虚拟磁盘IO性能太差编译速度会被拖到难以忍受的程度。本地固态硬盘上编译8核机器全量编译二十分钟内能跑完放到网络存储上同一套配置可能编译两个多小时还完不了。从4.4.0往后我每年都会重新编译两三次OpenCV但流程踩熟之后这套方案几乎可以照搬。核心心得就三点一是版本对齐主仓库、contrib、第三方依赖的版本不能乱二是选项裁剪只编译自己需要的东西三是保留build日志和CMake配置记录下次出问题有据可查。本文还有配套的精品资源点击获取