Windows下使用MinGW编译Qt+OpenCV动态库的完整指南

发布时间:2026/8/30 19:03:08
Windows下使用MinGW编译Qt+OpenCV动态库的完整指南 简介本资源是面向Qt与OpenCV跨平台开发者的预编译动态库集合专为解决Windows环境下Qt5.15.2与OpenCV4.5.5基于MinGW64工具链的兼容性集成难题。开发者可直接链接使用避免耗时的源码编译与环境配置显著提升图像处理、计算机视觉项目如实时视频分析、特征匹配、DNN推理的开发效率。压缩包共719个文件含55个DLL动态库、495个头文件hpp/h、54个静态导入库.a、22个XML配置及CMake构建支持文件另有许可证与第三方依赖说明文档总大小42.68MB结构清晰world版与非world版模块分离便于按需选用。目前已有744人学习下载资源完整覆盖core、imgproc、dnn、features2d、stitching、video等核心模块同时提供libopencv_world455.dll.a等关键导入库支持Qt Creator一键配置与MinGW64无缝调用。1. 项目缘起为什么要在Windows上用MinGW编译QtOpenCV动态库如果你在Windows上做Qt开发并且项目里需要用到OpenCV做图像处理那你大概率会遇到一个经典难题官方预编译的OpenCV库通常是用Visual Studio的MSVC编译器构建的。而当你使用Qt Creator并且选择了MinGW作为编译器套件时直接链接这些MSVC编译的库十有八九会失败报出一堆链接错误。这就是所谓的“ABI不兼容”——不同编译器生成的二进制接口不一样不能混用。所以一个很自然的想法就是自己动手用和Qt环境一致的MinGW编译器从头编译一份OpenCV。这听起来是个标准的操作但实际做起来坑可不少。特别是当你需要把编译好的OpenCV库集成到Qt项目中并且希望以动态链接库DLL的形式使用时从环境配置、编译参数选择到最终的部署每一步都可能让你折腾半天。我最近就因为一个跨平台项目的需要在Windows 10上用Qt 5.15.2自带的MinGW 8.1.0 64位编译器成功编译了OpenCV 4.5.5并生成了带world模块和不带world模块的两套动态库。整个过程踩了不少坑也总结出一些能让编译过程更顺畅、结果更可靠的技巧。这篇文章我就把这次完整的“踩坑-填坑”经历分享出来目标就是让你看完之后能一次成功地把这件事搞定。2. 环境准备与工具选型为什么是这套组合拳工欲善其事必先利其器。在开始编译之前明确每个组件的版本和获取方式至关重要版本不匹配是绝大多数编译错误的根源。2.1 核心组件版本锁定Qt 5.15.2: 这是Qt官方长期支持版本LTS中的一个重要节点稳定性有保障。我使用的是Qt官方在线安装器安装的mingw81_64套件。关键点务必确认安装时勾选了MinGW 8.1.0 64-bit这个组件。安装后其路径通常类似于C:\Qt\5.15.2\mingw81_64里面的bin目录就包含了我们需要的g.exe,gcc.exe,mingw32-make.exe等工具。OpenCV 4.5.5: 我选择这个版本是因为它是我项目依赖的特定版本且4.5.x系列已经非常成熟。你可以从OpenCV官网的 GitHub Releases 页面下载opencv-4.5.5.zip源代码和opencv_contrib-4.5.5.zip扩展模块。注意opencv_contrib不是必须的但如果你需要用到SIFT、SURF、文本检测等高级功能就必须下载它。CMake 3.20: 这是编译OpenCV的构建工具。版本不能太低建议使用3.20或更高版本。从 CMake官网 下载安装即可。MinGW 8.1.0 64-bit: 这就是Qt自带的编译器我们不需要单独安装。但需要确保它的bin目录如C:\Qt\5.15.2\mingw81_64\bin已经添加到系统的PATH环境变量中。你可以在命令行输入g --version和mingw32-make --version来验证。2.2 为什么选择动态库DLL编译OpenCV时CMake会提供BUILD_SHARED_LIBS选项决定是构建动态库ON还是静态库OFF。我强烈建议选择动态库即设置为ON原因如下减小最终可执行文件体积你的Qt程序本身不会包含OpenCV的代码只在运行时加载DLL。这对于依赖众多OpenCV模块的大型项目尤其有利。便于更新和维护如果OpenCV库需要升级或打补丁你只需要替换DLL文件而不需要重新编译整个Qt项目。内存共享如果系统中有多个程序使用了同一个OpenCV DLL内存中只会加载一份节省系统资源。当然静态库也有其优点比如部署简单一个exe走天下但考虑到OpenCV的庞大和Qt项目的灵活性动态库在Windows桌面开发中是更主流的选择。2.3 “带world”与“不带world”的本质区别这是本次编译的一个核心决策点。OpenCV的world模块是一个特殊的选项BUILD_opencv_world。当开启这个选项时CMake会把几乎所有OpenCV的核心模块如core,imgproc,highgui,videoio等打包进一个巨大的动态库文件中通常命名为opencv_world455.dll455代表版本4.5.5。带worldBUILD_opencv_worldON:优点部署极其简单。你的Qt项目只需要链接一个opencv_world455.lib导入库并在运行时依赖一个opencv_world455.dll。再也不用担心漏掉某个模块的DLL。缺点生成的DLL文件非常大可能超过100MB。如果你的应用只用了OpenCV的一小部分功能也会被迫加载整个大库增加内存占用和启动加载时间。此外如果你还需要opencv_contrib中的模块它们不会被包含进world库中仍然需要单独编译和链接。不带worldBUILD_opencv_worldOFF:优点按需链接体积优化。每个功能模块如opencv_core455.dll,opencv_imgproc455.dll都是独立的。你的应用只链接和加载它真正用到的模块更精简。缺点部署复杂。你需要清楚地知道你的项目依赖了哪些OpenCV模块并确保所有这些模块的DLL都随你的可执行文件一起发布否则程序会在运行时因找不到DLL而崩溃。我的策略是编译两套。先编译一套不带world的通用库用于日常开发和调试保持灵活性。然后针对最终发布版本如果觉得模块依赖管理太麻烦可以再编译一套带world的库简化部署包。接下来我们就进入具体的编译流程。3. 编译实操从CMake配置到MinGW构建理论说完了我们开始动手。这里我会以不带world模块的编译流程为主线因为这是更常规的做法。在关键节点我会指出编译带world库时的不同设置。3.1 步骤一使用CMake-GUI配置生成Makefile准备源代码目录在某个位置例如D:\Dev创建两个文件夹比如opencv455_build作为构建目录和opencv455_install作为安装目录。将下载的opencv-4.5.5.zip和opencv_contrib-4.5.5.zip解压。打开CMake-GUI“Where is the source code”: 选择解压后的opencv-4.5.5源代码目录。“Where to build the binaries”: 选择刚才创建的opencv455_build目录。第一次Configure点击Configure按钮。在弹出的编译器选择对话框中选择MinGW Makefile并指定编译器路径为Qt MinGW的g.exe和gcc.exe例如C:/Qt/5.15.2/mingw81_64/bin/g.exe。CMake会开始第一次扫描和配置。关键配置项调整第一次Configure完成后列表中会出现很多红色条目。我们需要关注并修改其中几项CMAKE_BUILD_TYPE: 对于MinGW如果你想生成带调试信息的库就填Debug想要发布版填Release。也可以留空后续通过make参数控制。注意Debug和Release的库不能混用最好分别编译。CMAKE_INSTALL_PREFIX: 这是安装路径设置为之前创建的opencv455_install目录的完整路径如D:/Dev/opencv455_install。编译后的头文件和库文件都会安装到这里。OPENCV_EXTRA_MODULES_PATH: 这是添加opencv_contrib模块的关键点击Add Entry添加一个PATH类型的变量值设置为opencv_contrib-4.5.5/modules的完整路径。不添加此项则只编译基础模块。BUILD_opencv_world: 这就是控制是否生成单一world库的开关。本次我们先设置为OFF。WITH_OPENGL/WITH_QT: 如果你希望HighGUI模块使用Qt作为后端来显示图像窗口可以将WITH_QT设为ON。但这需要你的系统有Qt开发环境且CMake能自动找到。对于MinGW编译这个自动查找有时会失败需要手动指定Qt5_DIR等变量过程较复杂。对于初学者我建议先保持OFF使用默认的HighGUI后端。BUILD_EXAMPLES/BUILD_TESTS: 可以设为OFF以加快编译速度。ENABLE_PRECOMPILED_HEADERS: 可以设为OFF有时能避免一些编译错误。第二次Configure与Generate修改完上述选项后再次点击Configure。此时红色条目会减少可能还会出现一些新的依赖项问题如缺少FFmpeg、缺少某些视频编解码器。对于MinGW编译很多视频相关的功能可能无法自动找到如果不需要用到视频文件读写cv::VideoCapture读文件等高级功能可以忽略这些警告。如果Configure最终没有报错红色条目消失或可接受点击Generate按钮。成功后会显示“Generating done”。此时在opencv455_build目录下就生成了Makefile等构建文件。注意如果编译带world的库只需将第4步中的BUILD_opencv_world设为ON其他步骤完全一致。但请记住opencv_contrib模块不会被包含进world库。3.2 步骤二使用MinGW进行编译与安装接下来我们离开CMake-GUI进入命令行操作。打开Qt MinGW命令行环境最可靠的方法是使用Qt安装目录下的Qt 5.15.2 (MinGW 8.1.0 64-bit)快捷方式它会自动设置好所有环境变量。如果没有你需要手动打开CMD或PowerShell并确保C:\Qt\5.15.2\mingw81_64\bin在PATH中。导航到构建目录在打开的命令行中使用cd命令进入opencv455_build目录。执行编译命令mingw32-make -j8-j8参数表示使用8个线程并行编译可以大大加快速度数字根据你的CPU核心数调整。这个过程会持续较长时间半小时到数小时期间会输出大量编译信息。如果遇到错误编译会停止。处理常见编译错误**undefined reference to__imp___glutInitWithExit**这是一个经典的MinGW与OpenGL链接问题。解决方法是在CMake配置中找到HAVE_OPENGL和HAVE_OPENGL相关的选项将它们设为OFF。或者在opencv455_build目录下找到CMakeCache.txt搜索OPENGL将OPENGL_INCLUDE_DIR和OPENGL_gl_LIBRARY的值清空或设为NOTFOUND然后重新Configure和Generate。fatal error: features2d/test/test_detectors_regression.impl.hpp: No such file or directory这通常是文件路径太长或包含空格导致的。确保你的源代码、构建、安装目录都在简单的英文路径下没有空格和中文。cannot find -lilmimf缺少Intel IPP库。在CMake中将WITH_IPP设为OFF。OpenCV 4.5.5可以不依赖IPP。执行安装命令编译成功后执行mingw32-make install这个命令会将编译好的头文件复制到install/include、库文件.dll.a导入库复制到install/x64/mingw/lib.dll动态库复制到install/x64/mingw/bin按照CMAKE_INSTALL_PREFIX指定的目录结构安装好。至此一套由MinGW编译的OpenCV 4.5.5动态库就准备好了。你可以到opencv455_install目录下查看成果。bin目录里是所有的.dll文件lib目录里是对应的.dll.a导入库文件。4. Qt项目集成配置.pro文件与解决运行时依赖库编译好了下一步就是在Qt项目中用它。这里以Qt Creator创建一个控制台项目为例演示如何链接我们刚编译好的OpenCV。4.1 配置项目.pro文件假设你的Qt项目名为TestOpenCV项目目录为D:\Projects\TestOpenCV。你需要将opencv455_install目录下的include和lib子文件夹复制到你的项目目录下或者一个统一的第三方库目录方便管理。这里假设你复制到了项目下的3rdparty/opencv455-mingw文件夹。接下来修改项目的.pro文件# TestOpenCV.pro QT - gui CONFIG c17 console CONFIG - app_bundle # 定义OpenCV的安装路径 win32: { # 请根据你的实际路径修改 OPENCV_PATH $$PWD/3rdparty/opencv455-mingw INCLUDEPATH $$OPENCV_PATH/include LIBS -L$$OPENCV_PATH/lib # 链接你需要的OpenCV模块 # 注意库文件名是 .dll.a但链接时写 -lopencv_core455 这样的格式 LIBS -lopencv_core455 LIBS -lopencv_imgproc455 LIBS -lopencv_highgui455 LIBS -lopencv_imgcodecs455 # 如果你编译了contrib模块并需要例如xfeatures2d # LIBS -lopencv_xfeatures2d455 } SOURCES \ main.cpp关键解释INCLUDEPATH: 告诉编译器在哪里找OpenCV的头文件。LIBS -L...:-L指定了库文件.dll.a所在的目录。LIBS -lopencv_core455:-l指定要链接的库名。注意库文件全名可能是libopencv_core455.dll.a但链接时去掉前缀lib和后缀.dll.a或.a只写opencv_core455。这个455是版本号必须和编译出的库文件名一致。4.2 编写测试代码在main.cpp中写一个简单的测试程序#include QCoreApplication #include iostream #include opencv2/opencv.hpp int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 读取一张图片请确保项目目录下有一张 test.jpg cv::Mat image cv::imread(test.jpg); if(image.empty()) { std::cout Could not open or find the image! std::endl; return -1; } // 转换为灰度图 cv::Mat grayImage; cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY); // 保存结果 cv::imwrite(gray_test.jpg, grayImage); std::cout OpenCV test with MinGW succeeded! Check gray_test.jpg. std::endl; return 0; // 直接退出不进入Qt事件循环 }4.3 解决运行时依赖DLL的部署在Qt Creator中编译Kit选择MinGW 64-bit链接通常会成功。但当你点击运行程序很可能会崩溃提示“无法启动此程序因为计算机中丢失opencv_core455.dll”。这是因为动态链接库DLL需要在运行时被找到。解决方案有以下几种按推荐顺序排列将DLL复制到可执行文件同级目录这是Windows上最简单可靠的方法。从opencv455_install/x64/mingw/bin目录下将你的程序链接的所有OpenCV模块对应的.dll文件例如opencv_core455.dll,opencv_imgproc455.dll等复制到你的Qt项目编译生成的可执行文件.exe所在的目录通常是build-项目名-Desktop_Qt_...-Release或Debug子目录。将DLL路径添加到系统PATH将opencv455_install/x64/mingw/bin目录添加到系统的PATH环境变量中。但这种方法会影响全局且对于最终分发程序给用户不友好。在Qt中使用QCoreApplication::addLibraryPath可以在代码中动态添加库路径但相对复杂。对于带world库的情况这一步就简单多了你只需要复制一个opencv_world455.dll和可能的opencv_world455d.dllfor Debug到可执行文件目录即可。4.4 在Qt Creator中设置运行环境可选但推荐为了避免每次运行都要手动复制DLL可以在Qt Creator中为你的运行配置设置环境变量临时添加DLL路径。在Qt Creator左侧“项目”模式锤子图标下选择当前构建套件如“Desktop Qt 5.15.2 MinGW 64-bit”。在“运行”设置Run Settings部分找到“运行环境”Run Environment。点击“详情”然后点击“添加”添加一个新的环境变量名称PATH值%{buildEnv:PATH};D:/Dev/opencv455_install/x64/mingw/bin请替换为你的实际bin路径操作Prepend前置这样设置后Qt Creator在启动你的程序时会优先从你指定的路径查找DLL。完成以上步骤后再次运行程序应该就能看到成功输出并在目录下生成灰度图了。这证明你的Qt项目已经成功集成了MinGW编译的OpenCV动态库。5. 高级话题与疑难排查即使按照上述步骤操作你可能还是会遇到一些棘手的问题。这里集中解答几个常见的“坑”。5.1 Debug与Release版本混用问题这是最常导致崩溃的问题之一。你必须保证编译一致性你的Qt项目使用的构建模式Debug/Release必须与你链接的OpenCV库的编译模式一致。如何区分MinGW编译的OpenCVDebug版库通常带有一个d后缀例如opencv_core455d.dll和libopencv_core455d.dll.a。Release版则没有这个d。.pro文件配置为了在Qt项目中方便地切换可以使用qmake的CONFIG变量进行条件判断debug { LIBS -lopencv_core455d LIBS -lopencv_imgproc455d # ... 其他Debug库 } else { LIBS -lopencv_core455 LIBS -lopencv_imgproc455 # ... 其他Release库 }同时你需要将Debug和Release版本的DLL分别管理运行时也要放入对应构建模式下的可执行文件目录。5.2 符号未定义undefined reference链接错误如果在Qt编译时遇到大量的“undefined reference tocv::xxx”错误通常意味着库路径或库名写错检查.pro文件中-L指定的路径是否正确-l指定的库名是否完整特别是版本号455。模块依赖缺失OpenCV模块之间有依赖关系。例如highgui依赖imgproc和core。如果你在代码中用了imshow属于highgui但只链接了core就会报错。你需要链接所有直接和间接依赖的模块。一个稳妥的方法是根据你#include的头文件来判断或者先链接所有你可能用到的模块。C运行时库不匹配MinGW编译OpenCV时CMake可能会选择不同的运行时库如-static-libgcc -static-libstdc。确保你的Qt项目构建套件中的MinGW编译器版本与编译OpenCV时使用的完全一致。5.3 程序运行时崩溃或Qt Creator调试器中断如果程序能启动但运行到OpenCV函数时崩溃或者在调试时突然中断可能的原因有DLL版本不匹配运行时加载的DLL不是你自己编译的那个版本。可能是系统PATH里存在其他版本的OpenCV DLL比如之前安装的OpenCV。确保你的程序目录下的DLL是正确的。内存对齐问题某些OpenCV函数如使用SIMD指令的对数据对齐有要求。如果你在栈上或堆上分配了cv::Mat然后传递了错误对齐的数据指针可能导致崩溃。使用cv::Mat::create或cv::Mat的构造函数来分配内存通常可以避免此问题。OpenCV与Qt的GUI冲突如果启用WITH_QT如果你编译OpenCV时开启了WITH_QT那么OpenCV的GUI窗口会使用Qt。这时你需要确保你的Qt程序正确初始化了GUI使用QApplication而非QCoreApplication并且注意OpenCV的GUI事件循环与Qt事件循环的潜在冲突。对于大多数集成场景我建议不要开启OpenCV的WITH_QT让OpenCV使用其自带的原生后端这样更稳定。5.4 关于opencv_contrib模块的特别说明opencv_contrib包含了许多实验性或专利算法模块如SIFT, SURF。编译它们时可能会遇到更多依赖问题例如需要下载额外的模型文件.cache目录或者某些模块因为依赖缺失而自动被禁用。在CMake的Configure输出中仔细查看关于contrib模块的状态如果某个你需要的模块显示为NO可以查看旁边的原因。有时需要手动提供依赖项路径如Eigen、Protobuf等。编译成功后链接这些模块的方式与核心模块相同例如-lopencv_xfeatures2d455。同样它们的DLL也需要被部署。整个从编译到集成的过程本质上是一个确保“环境一致、路径正确、依赖完整”的精细活。自己编译虽然前期麻烦但换来的是对项目依赖的完全掌控以及后续跨平台部署时的一致性。当你成功在Qt MinGW项目里调通第一个OpenCV函数时这种掌控感会让你觉得之前的折腾都是值得的。本文还有配套的精品资源点击获取