简介:这是一份OpenCV 4.8.0配合MinGW编译器在Windows环境下进行编译的完整资源包,面向需要自行构建OpenCV或以计算机视觉为方向的开发者,也适合在学习中需要参考源码与实际编译细节的读者。资源涵盖OpenCV源码树、头文件、构建脚本与示例程序,压缩包约282.62MB,共2000个文件;其中750个cpp文件为算法实现,317个hpp接口定义,222个py、157个java用于多语言调用演示,135个h为C语言头文件,其余txt、md、html等提供文档与构建说明。已有330人学习下载。通过该资源可深入理解OpenCV从CMake配置、依赖处理到生成静态库和动态库的完整流程,掌握FFmpeg、TBB等关键组件的集成方式;大量示例代码与模块文档也为后续在图像处理、模式识别方向做二次开发和算法研究提供了直接参考。
1. 为什么 Windows 上编译 OpenCV 4.8.0 + MinGW 是道绕不过去的坎
OpenCV 4.8.0 + MinGW 编译,说穿了就是让 OpenCV 在 Windows 上脱离 MSVC 生态,用 GCC 工具链重新生成一套能用的库。很多人在这一步翻车,因为顺手从官网下载的 Windows 预编译包是给 MSVC 用的,拿到 MinGW 工程里链接,立刻给你一屏幕 undefined reference——这不是你代码的问题,是 ABI 对不上。我自己第一次折腾,光解决“编译了三个小时,最后 install 出来的库在 Qt Creator 里还是崩”就花了两天。
如果你在用 Qt 的 MinGW 套件、用 CMake 管理工程、或者要定制 OpenCV 的模块和第三方依赖,那就别去碰预编译包了。自己编译能让调试版和发布版彻底分开,还能按需裁剪模块,免得 cv::dnn 之类的重头戏拖慢你的开发机。这篇文章按我实际跑通过的流程写,包括 CMake 参数、mingw32-make 的线程选择、install 后的路径组织,以及那几条让人血压升高的坑。
2. 开工前的三个决定:工具链、CMake 生成器与源码包怎么选
2.1 配置 MinGW-w64:别用旧版,编译器路径决定成败
MinGW 这个名字本身容易给你误导,OpenCV 4.8.0 的模块特性需要较新的 C++ 标准支持,老掉牙的 MinGW 5.x 就别指望了。我建议直接用 w64 版,线程模型选 posix,异常处理选 seh,架构按你系统选 x86_64。之前的 MinGW 版本里 debug 和 release 的库命名会混在一起,只拿到旧版的话,你在链接时会发现 libstdc++ 版本跟 GCC 对不上,然后崩在运行时。
把编译器解压到不含空格的路径是第一原则。我一般放到C:\mingw64,比放到D:\Program Files\MinGW省心得多,因为 CMake 的检测脚本碰上空格和括号就会闹脾气。配置好之后,先在命令行里跑gcc --version,确认输出的是 gcc 7.3 以上的版本,否则后面编译 OpenCV 的并行库会直接报错。
提示:把
C:\mingw64\bin加到系统 PATH 里,注意是系统变量,不是用户变量。后面 CMake 找编译器、Qt 找运行时都要用到它。
2.2 选对 CMake 生成器与 OpenCV 4.8.0 源码包
OpenCV 4.8.0 的源码包可以从 GitHub 的 release 页面拿opencv-4.8.0.zip,再配对opencv_contrib-4.8.0.zip。如果你只做基础图像处理,不带 contrib 也行,但若想用 SIFT、Aruco 这些在 main 包里被挪走的模块,就必须把 contrib 一起编。我通常把两个包解压成F:\opencv\opencv-4.8.0和F:\opencv\contrib-4.8.0,这样 CMake 的路径看起来一清二楚。
CMake 生成器这一关上,不要选 Visual Studio 系列的生成器,那会召唤出 MSVC 编译链。我们要的是MinGW Makefiles。你可以在图形界面 cmake-gui 里指定这个生成器,也可以直接命令行传参。注意与老版本 OpenCV 不一样,4.8.0 要求 CMake 版本至少 3.16 以上,我一般手上永远留一个 3.30 左右的 x64 安装包。
2.3 准备依赖库:没有它们你会被反复折磨
OpenCV 4.8.0 的默认配置并不会强制要很多第三方库,但有几个是可选的,直接影响你后面跑起来的东西。如果你想用cv::imdecode读 PNG 和 JPEG,默认带的就是系统库,但如果你想要 libtiff、libwebp,就得额外装依赖。常见做法是先用默认配置,跑通基本路径,后续再按需添加。
还有 Eigen、TBB、OpenCL 这些加速库。对 MinGW 来说,TBB 的官方预编译包是 MSVC 的,非常容易造成 ABI 冲突,我一般直接BUILD_TBB=OFF。OpenCL 在 Windows 上会尝试找显卡驱动,找不到也不致命,只是运行时有个警告。FFMPEG 这块要看你的使用场景,编译 FFMPEG 是非常耗费时间的,我们直接用内嵌的 opencv_videoio 库,等到真的需要视频编码时再回头补,这叫“后悔药”版本。
3. 用 CMake 配置 OpenCV 4.8.0:一条命令背后的 12 个关键开关
3.1 最小配置命令是怎么跑通的
写一个构建目录build-mingw,然后从该目录执行 CMake 配置。不要直接在源码目录下编译,否则你的源码树里全是中间文件,之后想改配置就得删光重来。最小命令如下:
cd F:\opencv\build-mingw cmake -G "MinGW Makefiles" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=G:\opencv-mingw-release \ -DOPENCV_EXTRA_MODULES_PATH=F:\opencv\contrib-4.8.0\modules \ -DBUILD_EXAMPLES=OFF \ -DBUILD_TESTS=OFF \ -DBUILD_PERF_TESTS=OFF \ F:\opencv\opencv-4.8.0这条命令里的-DCMAKE_INSTALL_PREFIX要记得改成你自己的安装目录,它决定了第五周之后链接时找头文件和库的位置。OPENCV_EXTRA_MODULES_PATH只有当你解压了 contrib 才需要。BUILD_EXAMPLES、BUILD_TESTS、BUILD_PERF_TESTS 这三个开关我默认都关掉,理由很现实:编 examples 和 tests 会让编译时间增加三分之一以上,而且 OpenCV 自带的测试框架在 Windows 上还经常因为路径分隔符报错,关掉不是偷懒是止损。
3.2 从静态到 DLL:BUILD_SHARED_LIBS 与安装路径的抉择
在 CMake 里有一个容易被新手忽略的-DBUILD_SHARED_LIBS,它默认是 ON。如果你是商业项目,共享库(DLL)会让你发布时带上opencv_core480.dll这些文件,省得把整个静态库链进 exe,但部署麻烦一点。如果你只是给自己写工具,静态库更舒服,一个 exe 就能拷到别的电脑跑。
我通常先做 Release 共享库,因为后续用 Qt Creator 调试时不用面对静态库的调试符号问题。命令加一句:
-DBUILD_SHARED_LIBS=ON配合-DBUILD_opencv_world=ON,它会生成一个opencv_world480.dll,你再也不用在链接器里列一串二三十个 lib 文件。当然,使用 world 之后要注意模块内部的链接顺序,有时候你明明加了 world lib,却报 LNK1104 找不到 libopencv_core——那是 CMake 配置时代没有生成 world 模块,重新配一次就行。
3.3 让生成速度不翻车:关闭不需要的模块与测试
OpenCV 4.8.0 的模块树里有很多你根本用不上的东西,比如opencv_stitching、opencv_photo、opencv_videostab。这些模块一旦参与编译,就会拉进来一堆依赖,里面很多还是 CMake 自动检测时误打误撞加的。你看一眼 CMake 输出的 module list,如果某些模块你是真的不会调用,就在配置命令里通过-DBUILD_opencv_<模块名>=OFF关掉。
我自己固定关掉的有BUILD_opencv_java、BUILD_opencv_python,这两个还牵扯到 JNI 和 Python 开发头文件的检测,影响还不如直接关。再有就是WITH_OPENCL,在 MinGW 下很多 OpenCL 头文件带了 MSVC 的 pragma 注释,我干脆关掉,省去一堆 defined 警告。配置之后强烈建议翻一翻 CMake 输出的Install to:段落,它会把最终安装到哪、哪几个库会被编译写得清清楚楚。
4. MinGW 编译 OpenCV 4.8.0 的完整过程:从 make 到 install
4.1 用 mingw32-make 编译时怎样线程数才稳
配置完成后,直接运行mingw32-make。前提是你已经把C:\mingw64\bin加入 PATH,不然命令行只能傻眼。mingw32-make默认单线程编译,OpenCV 这种体量少则四十分钟,多则两三个小时。加-j参数可以并发编译,比如 8 核机器用-j8。
mingw32-make -j8刚编译时你会看到一大片[ 1%] Built target opencv_core,这很正常。但如果你在编译到某个模块时突然蹦出internal compiler error,多数不是代码问题,而是 CPU 过热或者线程开太满,我建议退到-j4再试。要是退线程后还是崩,就去查是不是磁盘空间不够,OpenCV 构建目录需要接近 15GB 空闲空间,这在 Windows 上经常被忽略。
4.2 install 之后,你的 include 和 lib 在哪
编译完成之后才是最关键的一步:安装。如果你跳过 install,直接在 build 目录里去找头文件和库,会遇到一堆乱七八糟的中间状态。执行:
mingw32-make install它会把所有产物拷贝到CMAKE_INSTALL_PREFIX指定的目录。以我常用的G:\opencv-mingw-release为例,你会得到G:\opencv-mingw-release\include\opencv2和G:\opencv-mingw-release\x64\mingw\lib。注意这个x64\mingw子目录,很多新手对着 MSVC 的x64\vc16\lib死活找不到 MinGW 的库,其实是目录命名不同。
安装完成后,把G:\opencv-mingw-release\x64\mingw\bin加进 PATH,否则运行时会提示找不到opencv_core480.dll。
4.3 把 Qt Creator 接上编译结果:pro 文件的写法
如果你在用 Qt Creator 的 MinGW 套件,那么在.pro文件里加路径时不要用反斜杠结尾,也不要有空格。我一般这样写:
INCLUDEPATH += G:/opencv-mingw-release/include LIBS += -LG:/opencv-mingw-release/x64/mingw/lib -lopencv_world-lopencv_world会按 MinGW 的命名规则自动去找libopencv_world.dll.a。写完之后 qmake 再构建一次,能编过就说明库路径对了。如果提示找不到-lopencv_world,先去看lib目录下有没有libopencv_world480.dll.a这类文件,没有就回 CMake 确认BUILD_opencv_world是否开起来,再重新生成一次。
5. OpenCV + MinGW 编译避坑:5 条踩过的血泪教训
5.1 编译器路径里有空格,CMake 直接黑匣子报错
现象:CMake 配置时报错The C compiler identification is unknown,几十行,看不到具体原因。
原因:我把 MinGW 装在了C:\Program Files\mingw-w64\...,CMake 的编译器检测脚本在解析路径空格时把命令截断了,导致gcc.exe无法识别。
解决:把整个 MinGW 目录解压到C:\mingw64,保证路径全是 ASCII 且无空格,重新执行 CMake。这是 Windows 上最老生常谈的坑,但易踩。
5.2 链接时报 undefined reference to "cv::Mat::zeros..."
现象:你的代码明明包含了opencv2/opencv.hpp,编译过了,链接到-lopencv_world就报一堆undefined reference to cv::Mat之类。
原因:一个是你链接了 MSVC 的静态库opencv_world480.lib,这是最常见的;另一种是 MinGW 工具链调试版本与 CMake 生成的库不一致。
解决:先确认你链接的库文件名是libopencv_world.dll.a,而不是opencv_world.lib。然后在.pro或 CMakeLists 里明确使用G:/opencv-mingw-release/x64/mingw/lib路径,不要随便用系统里已经安装的其他 OpenCV。
5.3 生成 opencv_world 库失败?先查 libstdc++-6.dll
现象:编译过了,install 之后运行时提示找不到libstdc++-6.dll,程序直接崩溃。
原因:MinGW 的 GCC 版本太老或 PATH 里混入了别的 MinGW 比如 Qt 自带的 MinGW,它们的 libstdc++ 版本不同。我用的 GCC 8.1.0 编译的库,运行时却让 Qt 自带的 12 版去加载,自然找不到符号。
解决:把C:\mingw64\bin放在 PATH 最前面,让where libstdc++-6.dll指向同一个编译器目录。你也可以把libstdc++-6.dll直接复制到 exe 输出目录,作为最后手段。
5.4 调试版和发布版混用触发断言崩溃
现象:Release 编译的 OpenCV 库,连接上调试版的 Qt MinGW 应用,运行时在cv::imread里直接Assertion failed。
原因:OpenCV 的 debug 版本和 release 版本分别用了不同的宏定义,你在 CMake 里只编了 Release,但 Qt Creator 的构建套件选了 Debug,链接了同一个库。
解决:编译时开启CMAKE_BUILD_TYPE=Debug和CMAKE_BUILD_TYPE=Release分别编两套,安装到不同目录;或者在工程文件里统一用 Release 套件。我见过有人直接把 OpenCV 的 debug 库和 release 库拷在同一个目录里,结果 CMake 按名称找不到,又浪费半天。
5.5 环境变量 PATH 设了却不起作用的玄学真相
现象:系统 PATH 里明明加了C:\mingw64\bin,新开一个命令行窗口g++却还是命令找不到。
原因:Windows 的系统 PATH 里用了%UserProfile%这种变量,或者你的 PATH 里被其他安装包加了一个指向旧 MinGW 的C:\MinGW,新的设置优先级被压住了。
解决:在命令行里echo %PATH%,检查实际看到的路径顺序。然后where g++看看它定位到哪。如果环境变量修改后没生效,请确保你没有使用以管理员权限打开的窗口(有时用户 PATH 与系统 PATH 刷新时机不同)。把这几个检查做完,基本能定位。
6. 编译完之后先别急着写代码:验证工具链的三种方式
6.1 用 C++ 最小程序验证链接与运行
编译完了先写一个最简程序,不涉及 GUI,只要cv::Mat能创建就行。这样能最快排除“库根本没装好”的干扰。我习惯先创建test.cpp:
#include <opencv2/opencv.hpp> #include <iostream> int main() { cv::Mat m(100, 100, CV_8UC3, cv::Scalar(0, 255, 0)); std::cout << "rows=" << m.rows << " cols=" << m.cols << std::endl; return 0; }然后在命令行编译:
g++ -std=c++17 test.cpp -I G:/opencv-mingw-release/include -L G:/opencv-mingw-release/x64/mingw/lib -lopencv_world -o test.exe运行输出rows=100 cols=100,基础链接就通了。如果这一步就报错,优先查 PATH 和库路径,不用碰你后面的业务代码。
6.2 检查 DLL 依赖:objdump 与 windeployqt 双保险
链接成功不代表运行时没问题。我用objdump -p test.exe | grep "DLL Name"看看它依赖了哪些 DLL,确认opencv_world480.dll指向的路径不是你机器上另一个旧版本。Qt 用户还可以用windeployqt把依赖的 Qt DLL 复制到 exe 目录,它常常能连带检查出 OpenCV 的 DLL 路径问题。
6.3 把版本号写进 CMake 和代码,避免日后再次踩坑
验证完工具链,我马上把当前 OpenCV 版本写死在 CMakeLists 里,这样以后机器上装了别的 OpenCV 也不会串。例如:
set(OpenCV_DIR "G:/opencv-mingw-release") find_package(OpenCV 4.8.0 REQUIRED) target_link_libraries(myapp PRIVATE ${OpenCV_LIBS})同时在代码里用cv::getBuildInformation()打印一次构建信息,并把它写进日志文件。这样一个多月后你重新捡起项目,看一眼日志就知道当时用了哪个编译器、哪些模块开了。我自己的习惯是把编译参数也保存在 install 目录下的build_info.txt,方便复查。这一点看着小,却帮我在换电脑时省掉了重新猜配置的折腾,希望帮到你。
本文还有配套的精品资源,点击获取