
简介本资源为OpenCV 4.8.0在Windows平台下使用MinGW编译的完整源码包面向需要在Windows环境中构建计算机视觉与机器学习应用的开发者尤其适合希望摆脱Visual Studio依赖、使用MinGW工具链进行编译的中高级C程序员。压缩包共约2000个文件涵盖750个cpp源文件、317个hpp头文件、222个Python脚本、157个Java文件及135个C头文件另含HTML文档、XML配置、Markdown说明与JSON数据等整体约282.62MB结构完整便于按模块查阅与二次开发。资源包含DNN模块改进、性能优化等4.8.0版本新特性并涉及FFmpeg、TBB等依赖库的集成配置。已有330人学习下载读者可获取从源码到静态库、动态库的完整编译产物结合示例程序与教程深入理解图像处理、视频分析及模式识别功能的实现原理同时需注意OpenCV的BSD许可与FFmpeg的LGPL许可要求。1. 为什么有人非要用 MinGW 编译 OpenCV 4.8.0如果你在 Windows 上做 C 图像处理大概率第一反应是装 Visual Studio 然后用官方预编译包。但真实工程里有一类场景绕不开 MinGW项目本身用 Qt MinGW 工具链、CI 跑在 MSYS2 环境、或者你就是要一个不依赖 MSVC 运行库的绿色可执行文件。这时候官方那个opencv-4.8.0-windows.exe直接翻车——它是用 MSVC 编的MinGW 链接时会报一堆undefined referenceABI 对不上。所以「OpenCV 4.8.0 MinGW 编译」这件事的本质是自己从源码产出一套和 MinGW 工具链 ABI 一致的库文件。它解决的是工具链统一问题不是性能问题。适合谁用 MinGW-w64 做主力编译器、需要静态或半静态链接 OpenCV、或者要在没有 MSVC 的机器上复现构建的开发者。这篇笔记按我实际走通的顺序讲从环境准备到 CMake 参数、从编译报错到产物验证参数都给具体值。2. 编译前的环境准备工具链版本对不上后面全是白干2.1 MinGW-w64 选型为什么我坚持用 POSIX 线程 SEH 异常MinGW 在 Windows 上有两条主流分支老旧的 MinGW.org32 位、sjlj 异常和 MinGW-w6464 位、支持 SEH。OpenCV 4.8.0 的代码里大量用了 C11 之后的特性加上它内部依赖线程所以必须选 MinGW-w64。具体到发行版我一般用 MSYS2 里的mingw-w64-x86_64-gcc或者独立分发的 w64devkit两者都能跑通。关键在三个编译选项选错了会在链接期或运行期炸选项可选值推荐原因架构i686 / x86_64x86_644.8.0 的 64 位优化路径更完整线程模型win32 / posixposixOpenCV 的std::thread、std::mutex依赖 posix 模型异常模型sjlj / seh / dwarfseh64 位下 seh 性能好且和系统兼容用gcc -v能看到当前工具链的配置输出里会有Thread model: posix和Exception model: seh这样的字样。如果显示win32那std::thread相关代码会直接编译失败别抱侥幸。2.2 依赖清单CMake、Ninja、Python 一个都不能少OpenCV 4.8.0 的构建系统是 CMake官方要求 3.5 以上但 4.8.0 里有些模块用了较新的 CMake 语法我实测 3.20 最稳。生成器我强烈建议用 Ninja 而不是 MinGW Makefiles原因是 Ninja 的并行调度更干净增量编译快而且不会出现mingw32-make那种莫名其妙的 jobserver 报错。Python 是给opencv_python模块和部分代码生成脚本用的。如果你只要 C 库可以在 CMake 里关掉 Python 绑定但构建过程中仍可能调用 Python 脚本生成头文件所以装一个 3.8 的解释器并加进 PATH 是省事的做法。一个最小可用的环境清单MinGW-w64 GCC 11.2 或更高我用的 13.2 也通过CMake 3.20 以上Ninja 1.10 以上Python 3.8 以上可选但推荐源码opencv-4.8.0主仓库外加opencv_contrib-4.8.0需要 extra 模块时提示源码目录路径里不要有中文和空格。MinGW 的某些工具对空格路径处理不干净会在生成阶段报奇怪的路径错误这是血泪经验。2.3 目录规划源码、构建、安装三分离我习惯把三件事分开避免污染源码树也方便删掉重建# 目录结构示例路径按自己习惯改 D:/work/opencv/ ├── src/ │ ├── opencv-4.8.0/ # 主源码 │ └── opencv_contrib-4.8.0/ # 扩展模块 ├── build/ # 构建目录CMake 在这里跑 └── install/ # 安装目录最终产物在这构建目录必须是空的或者至少没有上一次的CMakeCache.txt。我见过有人直接在源码目录里跑 CMake结果源码树被生成文件塞满想清理都无从下手。每次改大参数前把 build 目录整个删掉重来比在缓存上打补丁可靠得多。3. CMake 配置把参数一次配对别反复试3.1 最小可用配置命令下面这条命令是我在 64 位 MinGW-w64 下跑通 OpenCV 4.8.0 的基线配置。它关掉了用不上的模块打开了 Ninja 生成器指定了安装前缀# 在 build 目录下执行 cmake -G Ninja \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIXD:/work/opencv/install \ -DCMAKE_C_COMPILERgcc \ -DCMAKE_CXX_COMPILERg \ -DCMAKE_MAKE_PROGRAMninja \ -DBUILD_SHARED_LIBSOFF \ -DBUILD_opencv_python3OFF \ -DBUILD_TESTSOFF \ -DBUILD_PERF_TESTSOFF \ -DBUILD_EXAMPLESOFF \ -DWITH_OPENCLOFF \ -DWITH_IPPOFF \ -DWITH_MSMFON \ -DWITH_DSHOWON \ -DWITH_FFMPEGOFF \ -DOPENCV_EXTRA_MODULES_PATHD:/work/opencv/src/opencv_contrib-4.8.0/modules \ ../src/opencv-4.8.0逻辑说明-G Ninja指定生成器CMAKE_BUILD_TYPERelease开优化BUILD_SHARED_LIBSOFF产出静态库方便打包BUILD_opencv_python3OFF跳过 Python 绑定省一大截编译时间WITH_OPENCL和WITH_IPP关掉是因为它们会引入额外依赖MinGW 下容易出问题WITH_MSMF和WITH_DSHOW是 Windows 摄像头后端做视频采集就留着。参数说明OPENCV_EXTRA_MODULES_PATH指向 contrib 的modules目录注意是modules不是仓库根目录写错了 CMake 会静默忽略你以为编进去了其实没有。CMAKE_INSTALL_PREFIX用正斜杠MinGW 对反斜杠的转义处理不一致。3.2 静态库还是动态库一个影响部署方式的决定BUILD_SHARED_LIBS这个开关决定了你拿到的是.a还是.dll.dll.a。两者没有绝对优劣看场景静态库OFF最终可执行文件大但部署时不用带一堆 DLL适合做绿色工具、单文件分发。缺点是如果多个模块都静态链接 OpenCV符号会重复链接期可能报multiple definition。动态库ON可执行文件小多个程序共享一份 OpenCV但部署时必须把bin目录下的 DLL 一起拷过去漏一个就运行期崩。我一般做桌面工具选静态做需要热更新 OpenCV 的场景选动态。注意静态链接时MinGW 还需要额外链接-lstdc -lpthread -lws2_32这些系统库CMake 的OpenCVConfig.cmake里已经处理了大部分但自己写 Makefile 时要留意。3.3 裁剪模块编得越少翻车越少OpenCV 4.8.0 默认会尝试编译所有模块其中一些在 MinGW 下需要额外依赖比如opencv_videoio的 FFmpeg、opencv_highgui的某些 GUI 后端。如果你不需要直接关掉能省大量时间也避开依赖坑。我常用的裁剪参数-DBUILD_opencv_javaOFF \ -DBUILD_opencv_jsOFF \ -DBUILD_opencv_appsOFF \ -DBUILD_opencv_tsOFF \ -DWITH_GTKOFF \ -DWITH_VTKOFF \ -DWITH_EIGENOFF \ -DWITH_TBBOFF \ -DWITH_OPENMPOFFBUILD_opencv_ts是测试支持模块关掉不影响核心功能。WITH_GTK在 Windows 下本来就没意义。WITH_TBB和WITH_OPENMP是并行后端MinGW 下 TBB 的预编译包不好找OpenMP 虽然 GCC 自带但和 OpenCV 的某些循环有冲突我倾向关掉用std::thread自己的并行就够了。注意关掉WITH_FFMPEG后VideoCapture打不开 mp4 文件只能走摄像头。如果你要读视频文件要么打开 FFmpeg需要自己编或找 MinGW 版要么用WITH_MSMF走系统解码器但 MSMF 对编码格式支持有限。4. 编译与安装Ninja 跑起来后盯什么4.1 启动编译并行度别拉满配置成功后在 build 目录执行# 并行编译-j 后面跟核心数 ninja -j8 # 编译完成后安装到 CMAKE_INSTALL_PREFIX ninja install-j8是并行任务数一般设成 CPU 物理核心数。别设成逻辑核心数超线程在编译这种重 IO 和内存的场景下收益很小反而容易因为内存不足触发 OOM。我 16G 内存的机器上-j8编 OpenCV 4.8.0 大概 20 到 30 分钟具体看模块裁剪程度。编译过程中如果某个模块报错Ninja 会停在出错的文件上不会继续往下跑。这时候看最后 20 行输出通常是缺头文件或者某个类型不匹配。MinGW 和 MSVC 在类型推导上有些差异OpenCV 官方主要保证 MSVC 通过MinGW 下偶尔需要打小补丁。4.2 常见编译错误三个我踩过的坑错误一std::thread has not been declared现象是编译到opencv_core的并行相关文件时报错。原因是 MinGW 的线程模型是win32而不是posix。解决换用 posix 线程模型的 MinGW-w64 发行版或者重新配置工具链。用gcc -v确认Thread model: posix。错误二undefined reference to cv::...在链接阶段现象是编译都过了链接自己的测试程序时找不到符号。原因通常是链接顺序不对或者静态库之间的依赖没展开。MinGW 的链接器对库顺序敏感被依赖的库要放在后面。用pkg-config --libs opencv4拿到的顺序一般是对的如果手动写把opencv_core放最后。错误三fatal error: opencv2/core.hpp: No such file现象是编译自己的代码时找不到头文件。原因是CMAKE_INSTALL_PREFIX/include没加进编译器的搜索路径。检查-I参数是否指向了安装目录的include而不是源码目录的include。源码目录的头文件是模板安装目录的才是配置好的。4.3 验证产物写个最小程序跑一遍编译安装完别急着用先写个最小程序验证。下面这段代码读一张图、转灰度、写出来覆盖了core、imgcodecs、imgproc三个核心模块// verify.cpp #include opencv2/core.hpp #include opencv2/imgcodecs.hpp #include opencv2/imgproc.hpp #include iostream int main() { // 读图路径换成自己的 cv::Mat img cv::imread(test.jpg, cv::IMREAD_COLOR); if (img.empty()) { std::cerr read failed std::endl; return -1; } cv::Mat gray; cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY); cv::imwrite(gray.jpg, gray); std::cout ok, size gray.size() std::endl; return 0; }编译命令静态链接g verify.cpp -o verify.exe \ -ID:/work/opencv/install/include \ -LD:/work/opencv/install/x64/mingw/staticlib \ -lopencv_core -lopencv_imgcodecs -lopencv_imgproc \ -lstdc -lpthread -lws2_32 -luser32 -lgdi32 -lcomdlg32 -lole32逻辑说明-I指向安装头文件-L指向静态库目录注意 OpenCV 4.8.0 在 MinGW 下的库路径是x64/mingw/staticlib或x64/mingw/lib取决于 CMake 版本-l按依赖顺序列库imgproc依赖core所以core放最后。后面那串系统库是 MinGW 静态链接 OpenCV 时必须的缺了会报undefined reference to WSAStartup之类的错。跑通后输出ok, size[宽 x 高]就说明库没问题。如果读图失败检查test.jpg是否在运行目录以及imgcodecs是否真的编进去了。5. 避坑与排查那些让编译前功尽弃的细节5.1 坑一CMake 缓存残留导致参数不生效现象改了BUILD_SHARED_LIBS从 ON 到 OFF重新跑 CMake 和 ninja产出的还是 DLL。原因是CMakeCache.txt里缓存了旧值CMake 认为你没改。解决删掉整个 build 目录重新配置或者用cmake -U BUILD_SHARED_LIBS清掉特定缓存项。我一般直接删目录干净。5.2 坑二contrib 模块路径写错静默忽略现象配置时没报错编译也过了但cv::xfeatures2d::SIFT找不到。原因是OPENCV_EXTRA_MODULES_PATH指向了 contrib 仓库根目录而不是modules子目录。CMake 对不存在的路径不报错只是不加载。解决确认路径末尾是opencv_contrib-4.8.0/modules配置输出里会打印Extra modules:列表检查有没有你要的模块。5.3 坑三静态链接时系统库漏链现象编译自己的程序时链接阶段报undefined reference to __imp_WSAStartup或__imp_CreateDIBSection。原因是 OpenCV 静态库内部调用了 Windows API但你的链接命令没带上对应的系统库。解决补上-lws2_32 -luser32 -lgdi32 -lcomdlg32 -lole32 -loleaut32 -luuid。这些库在 MinGW 安装目录的x86_64-w64-mingw32/lib下都有。5.4 坑四运行期缺 DLL 或路径不对现象程序编译链接都过双击运行报「找不到 libgcc_s_seh-1.dll」或「找不到 libstdc-6.dll」。原因是 MinGW 的动态运行库没在 PATH 里。解决要么把 MinGW 的bin目录加进系统 PATH要么编译时加-static-libgcc -static-libstdc把运行库静态链进去。后者更适合分发。5.5 坑五Debug 和 Release 混用现象Release 编的 OpenCV 库自己的程序用 Debug 模式编译链接时报undefined reference或者运行期崩溃。原因是 Debug 和 Release 的 ABI 不完全兼容尤其是 STL 容器的内存布局。解决保持构建类型一致OpenCV 用 Release自己的程序也用 Release需要调试就单独编一套 Debug 版 OpenCV别混。6. 进阶把编译产物接进 CMake 项目与体积优化6.1 用 OpenCVConfig.cmake 自动找库手动写-I和-L只适合验证真实项目应该用 CMake 的find_package。安装完成后install目录下会有OpenCVConfig.cmake在自己的CMakeLists.txt里这样写# CMakeLists.txt cmake_minimum_required(VERSION 3.20) project(mycv) # 指向 OpenCV 安装目录 set(OpenCV_DIR D:/work/opencv/install) find_package(OpenCV 4.8 REQUIRED) add_executable(mycv main.cpp) target_include_directories(mycv PRIVATE ${OpenCV_INCLUDE_DIRS}) target_link_libraries(mycv PRIVATE ${OpenCV_LIBS})逻辑说明OpenCV_DIR告诉 CMake 去哪找配置文件find_package会自动填充OpenCV_INCLUDE_DIRS和OpenCV_LIBS包括系统库依赖。这样换机器时只改OpenCV_DIR一个变量不用动链接命令。如果find_package报找不到检查OpenCV_DIR是否指向包含OpenCVConfig.cmake的那一层不是lib也不是bin。6.2 体积优化静态库怎么瘦身静态链接 OpenCV 后可执行文件动辄几十 MB。几个有效的瘦身手段编译时加-DCMAKE_CXX_FLAGS-ffunction-sections -fdata-sections链接时加-Wl,--gc-sections让链接器丢掉没用的函数段。关掉不用的模块前面裁剪参数已经做了。用strip去掉符号表strip mycv.exe能减掉几 MB。如果不需要异常和 RTTI加-fno-exceptions -fno-rtti但 OpenCV 内部用了异常这个要谨慎可能编不过。我实测一个只用了coreimgprocimgcodecs的程序Release 静态链接后约 12MBstrip后 8MB 左右。如果动态链接exe 只有几百 KB但需要带 5 到 6 个 DLL。6.3 一个具体技巧用 pkg-config 管理编译参数MinGW 环境下OpenCV 安装时会生成opencv4.pc文件在install/x64/mingw/lib/pkgconfig下。把它所在目录加进PKG_CONFIG_PATH就能用pkg-config拿参数export PKG_CONFIG_PATHD:/work/opencv/install/x64/mingw/lib/pkgconfig pkg-config --cflags --libs opencv4输出会包含所有-I、-L和-l直接贴进 Makefile 或编译命令就行。这个方式比手写参数可靠尤其是库依赖顺序pkg-config 已经排好了。注意 Windows 下路径分隔符和 shell 的差异在 MSYS2 里跑最顺。我自己的习惯是每次升级 OpenCV 版本先删 build 目录用同一套 CMake 参数重新配置编完立刻跑一遍验证程序确认imread、cvtColor、imwrite三个调用都正常再往项目里接。这套流程走了好几遍翻车次数明显少了。希望帮到你。本文还有配套的精品资源点击获取