简介:OpenCV是跨平台计算机视觉库,Qt是C++图形界面框架,二者整合可以构建出界面友好且具备图像处理、特征检测、对象识别等能力的应用程序。在Windows 10 64位下,使用MinGW工具链编译的这份OpenCV 3.2.0库,已针对Qt5.9.6做好适配,可直接集成到Qt项目中,免去手动CMake配置与漫长编译,该版本专为不使用Visual Studio的MinGW开发者准备,能解决常见的编译兼容问题。资源共245个文件,以145个hpp和57个h头文件提供完整API声明,17个dll支撑运行时调用,16个a静态导入库用于链接,另有5个exe和4个cmake文件辅助环境验证与集成,整体仅10.61MB。其中dll和a文件覆盖core、imgproc、highgui等常用模块,头文件占比最高,方便开发者查阅接口并快速搭建OpenCV图像处理或Qt界面应用,便于实际项目快速落地。目前已有242人学习下载,适合需要摆脱Visual Studio限制、在Qt环境中使用OpenCV的开发者参考使用。
1. 为什么折腾这套组合:opencv3.2.0_mingw_支持Qt5.9.6_win10 不是炫技
opencv3.2.0_mingw_支持Qt5.9.6_win10 这个标题看起来像下载站里的压缩包命名,其实是很多 Windows 桌面开发者在 Qt Creator 里用 MinGW 编译器链接 OpenCV 时绕不过去的一条路。官方预编译包只有 MSVC 版本,拿到 MinGW 工程里一链,undefined reference 刷屏,这是第一次碰到“MSVC 和 MinGW 不能混着用”的典型场景。
要解决的问题很具体:用 Qt 5.9.6 自带的 MinGW 530 编译 OpenCV 3.2.0,打开 WITH_QT,让 highgui 模块使用 Qt 作为窗口后端,之后 imshow 弹出来的窗口自带 Qt 工具栏。适合谁?用 Qt 写带控制界面、需要把摄像头或图片显示和图像处理做在同一个进程里的人,以及不想被 MSVC 工具链绑架、只靠 Qt 和 MinGW 独立完成图形界面应用的人。接下来从工具链匹配开始,一路讲到能跑起来的最小工程。
2. 编译前的门当户对:工具链、ABI 与三条必查项
2.1 MinGW 和 MSVC 的 ABI 差异:为什么官方 OpenCV 包在 Qt Creator 里会翻车
Windows 上的 C++ 编译器生态被切成两半:MSVC 和 MinGW。MSVC 是微软的编译器,目标文件和导入库后缀是.lib;MinGW 是 GCC 的 Windows 移植版,导入库后缀是.dll.a,生成的 exe 依赖libgcc和libstdc++。两者对 C++ 符号修饰、结构体对齐、异常模型的处理差异很大。官方 OpenCV 的 Windows 预编译包只提供 MSVC 库,你用 MinGW 里的 g++ 去链接opencv_world320.lib,链接器不认符号格式,报的就是undefined reference to cv::imread。
很多人问 MSVC 和 MinGW 区别是不是一个来自 Visual Studio、一个来自命令行,这是误解。真正的区别是 ABI,也就是二进制接口。即便你把.lib转换成.dll.a,C++ 重载函数的符号也可能对不上,OpenCV 这种大量使用 STL 和模板的库,转换出来的东西就算链过了,运行时也容易崩。结论很直接:想用 MinGW 做 Qt 程序,OpenCV 必须自己用 MinGW 从源码编一遍。这个成本看起来高,但只要 CMake 配置写对,后面反而省心。
| 组件 | 目录示例 | 说明 |
|---|---|---|
| Qt 5.9.6 MinGW 库 | C:/Qt/Qt5.9.6/5.9.6/mingw53_32 | 32 位,不混用 MSVC 库 |
| MinGW 编译器 | C:/Qt/Qt5.9.6/Tools/mingw530_32 | GCC 5.3.0,自带 mingw32-make |
| CMake | 任意大于 3.10 的版本 | 生成器必须选 MinGW Makefiles |
2.2 版本匹配:Qt 5.9.6 自带的 MinGW 530 与 CMake 的搭配选择
Qt 5.9.6 的安装包里附带Tools/mingw530_32,也就是 MinGW-w64 GCC 5.3.0 的 32 位编译器。为什么不建议去 mingw 官网下载一个最新版?因为 Qt 5.9.6 自己是用这个编译器编的,Qt 库的二进制接口只和这个版本的 GCC 兼容。你把 OpenCV 用新版 MinGW 编出来,再和 Qt 5.9.6 链接,GCC 版本差异引入的 ABI 变化会让链接器报类型错误。
CMake 的版本选择不用太纠结,OpenCV 3.2.0 发布时 CMake 还比较老,但实测 CMake 3.13 到 3.20 都能正常生成。关键点是生成器要选MinGW Makefiles,而不是默认的Visual Studio或NMake Makefiles。如果你在命令行里敲不出cmake和mingw32-make,配置命令里就要显式指定CMAKE_MAKE_PROGRAM,不然 CMake 找不到 make 程序会在最后一步报错退出。
这里还要注意一个架构问题:Qt 5.9.6 的 MinGW 套件默认是 32 位程序,即使 Win10 是 64 位系统也要用 32 位编译链。OpenCV 跟着编 32 位,之后安装目录会落在x86/mingw而不是x64/mingw。这个细节直接决定集成时-L路径写谁,很多人在这一步反复出错。
2.3 动手前的三个前置检查:Qt 路径、Perl、PATH 顺序
第一,Qt 安装路径。我一般就用C:/Qt/Qt5.9.6/5.9.6/mingw53_32,没有空格没有中文。如果装在D:/Program Files (x86)/Qt这类带空格路径,OpenCV 3.2 的 FindQt5 模块在部分 CMake 版本下会因为路径里的右括号配置失败,这是当年被坑过一次的真实经历。
第二,Perl。OpenCV 编译过程不一定百分百需要 Perl,但如果 CMake 检测不到,部分源码生成步骤会被跳过,等编译到一半才发现缺头文件。装一个 Strawberry Perl,让 CMake 能检测到,属于防患于未然。装完记得重开控制台,让 PATH 生效。
第三,PATH 顺序。进入命令行先敲where mingw32-make,确认指向 Qt 目录里的 MinGW。很多机器装了 Git for Windows 或 MSYS2,它们的usr/bin下也有 mingw32-make,版本不一致会链到完全不同的运行时上。再敲where cmake,确定没有 Anaconda 或 Python 环境里的 CMake 挡在前面。这三个检查做完,CMake 配置阶段基本能做到门当户对。
3. 用 CMake 生成构建工程:OpenCV 3.2.0 的关键开关与生成命令
3.1 源码和构建目录规划:路径不带空格的执念
OpenCV 3.2.0 的源码可以从官方 GitHub 仓库切3.2.0的 tag 获取,也可以直接下 SourceForge 上的 3.2.0 源码包。源码目录我建议放在C:/dev/opencv-3.2.0,构建目录单独建一个C:/dev/opencv-3.2.0/build-qt。源码和构建目录分开是必须的,因为 OpenCV 的 CMake 构建会生成很多缓存文件,放在源码目录里会让后续更新麻烦,而且 CMake 自己也在手册里明确反对 in-source build。
路径不带空格和中文是一条近乎玄学的经验。MinGW 的 make 对空格的处理比 MSVC 差不少,路径里有空格时,编译阶段经常出现找不到某个.h文件,甚至链接阶段报cannot open output file。中文路径在部分 Win10 编码环境下还会把源码里的字符串写坏。最省事的就是全部用C:/dev/...这类短路径。
3.2 最小可用 CMake 配置命令(MinGW Makefiles)
进入源码根目录后执行以下命令:
cd C:/dev/opencv-3.2.0 mkdir build-qt cd build-qt cmake -G "MinGW Makefiles" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_MAKE_PROGRAM=C:/Qt/Qt5.9.6/Tools/mingw530_32/bin/mingw32-make.exe \ -DCMAKE_PREFIX_PATH=C:/Qt/Qt5.9.6/5.9.6/mingw53_32 \ -DCMAKE_INSTALL_PREFIX=C:/dev/opencv-install \ -DWITH_QT=ON \ -DWITH_OPENGL=ON \ -DWITH_IPP=OFF \ -DBUILD_opencv_world=ON \ -DBUILD_EXAMPLES=OFF \ -DBUILD_TESTS=OFF \ -DBUILD_PERF_TESTS=OFF \ ..这里每个参数都有明确用途。CMAKE_MAKE_PROGRAM指向 Qt 自带的mingw32-make.exe,避免 CMake 在系统 PATH 里找到另一个 make。CMAKE_PREFIX_PATH是关键,OpenCV 的 FindQt5 模块会在这个路径下查找 Qt5Config.cmake。如果找不到,后面的 WITH_QT 会静默失败,OpenCV 依然能编译,但 highgui 会退回到 Win32 窗口后端。
WITH_IPP=OFF是因为 IPP 闭源库在 OpenCV 3.2 时代经常和 MinGW 编译链冲突,关了可以少一个变量。BUILD_opencv_world=ON会把所有模块打包成一个opencv_world库,后面链接时不用面对十几个小库的依赖顺序问题。关闭 tests 和 examples 是因为它们在集成时完全用不上,开着只会白白拖慢编译时间。
3.3 必须打开的开关:WITH_QT、WITH_OPENGL 和 BUILD_opencv_world
WITH_QT是整个标题里“支持 Qt”的核心。打开这个开关后,OpenCV 的 highgui 模块会编译成基于 Qt 的窗口后端,namedWindow和imshow内部走的是QApplication事件循环。如果你只是想在 Qt 界面里放一个图像控件,不一定要用这个后端,但想验证 OpenCV 自带的显示功能是否和 Qt 包兼容,就必须开。
WITH_OPENGL建议一并打开。Qt5 的 GUI 模块本身依赖 OpenGL 动态库,OpenCV 的 Qt 后端在部分显卡驱动下需要 OpenGL 上下文来创建窗口。不开这个选项,编译能过,但运行到namedWindow时可能崩溃或黑屏。
BUILD_opencv_world的取舍是一个经典问题。OpenCV 3.2 的世界库把所有模块编进同一个 DLL,链接简单,运行时只需要分发一个libopencv_world320.dll。劣势是如果只用到其中两个模块,DLL 体积偏大。但对个人开发和内部工具来说,省下的链接时间远比那几十 MB 体积值。
3.4 配置失败的典型报错:Qt5_DIR 找不到 / 编译器不匹配
CMake 配置阶段最常见的报错是:
Could NOT find Qt5 (missing: Qt5_DIR)原因基本是CMAKE_PREFIX_PATH写错了,或者指向了 Qt 的 MSVC 套件目录,比如C:/Qt/Qt5.9.6/5.9.6/msvc2015。OpenCV 的 FindQt5 模块只认带bin、include、lib的 MinGW 套件目录。解决方法是显式指定:
-DQt5_DIR=C:/Qt/Qt5.9.6/5.9.6/mingw53_32/lib/cmake/Qt5另一个容易翻车的是 CMake 检测到系统里装了多个 Qt。比如你之前装过 Qt 5.15,CMAKE_PREFIX_PATH又同时指了 5.9.6 和 5.15,CMake 会优先找到新版本,随后 OpenCV 编出来的 highgui 链接 Qt 5.15,但你的 Qt Creator 工程用的是 5.9.6,运行时就会报cannot mix incompatible Qt library。所以CMAKE_PREFIX_PATH里只放 5.9.6 的路径,不要贪多。
配置成功之后,CMake 输出末尾会有一段 GUI 相关的信息。睁大眼睛看这一行:
GUI: QT如果没有这行,而是WIN32或GTK,说明 WITH_QT 没生效,回到前面排查路径。
4. 编译与安装:mingw32-make 的常见翻车点
4.1 编译命令与并行数控制:-j4 还是 -j8
配置完成之后,就是漫长的编译阶段。命令很简单:
cd C:/dev/opencv-3.2.0/build-qt mingw32-make -j4-j4表示四个并行编译任务,速度和个人机器核心数有关。如果你的 CPU 是四核八线程,-j8听起来更快,但 OpenCV 3.2 的模块之间存在依赖关系,并行任务太多时链接阶段会抢内存。MinGW 的 GNU 链接器在内存不足时会直接退出,报一个没法看懂的g++.exe: fatal error: Killed。我一般先用-j4跑,编译很顺利再回退到-j2或者不加参数跑。
编译耗时要有一个预期。禁用 examples 和 tests 之后,在 SSD 上大约 20 到 40 分钟,机械硬盘可能要一个半小时。中途不要关窗口,如果报错,先记下是哪个模块的哪个文件,再去查原因。
4.2 编译中断排查:内存、杀毒软件、源码路径
编译中断最常见三个原因。第一个是内存耗尽,OpenCV 中opencv_imgproc模块有大量模板展开,GCC 5.3 的内存占用比新版本更夸张,4GB 内存的老机器跑-j4很容易挂。解决方式是降并行度,或者临时关掉占用内存大的浏览器。
第二个原因是杀毒软件的实时监控。Windows Defender 在编译到生成 DLL 的阶段会扫描新生成的.dll和.exe,占用文件句柄后导致链接失败,报错可能是一句莫名其妙的Permission denied。把C:/dev/opencv-3.2.0加入 Windows Defender 排除列表,能省掉很多突然中断。
第三个原因是源码路径里带了中文或空格。这个在第 3 章已经强调过,但在编译中断时还会再犯。如果看到某个头文件找不到,先看一眼完整路径,十有八九是路径问题。
4.3 安装到自定义目录:OpenCVConfig.cmake 与 DLL 的生成
编译完成后,执行安装:
mingw32-make install安装到C:/dev/opencv-install之后,目录结构大致是include/opencv2、x86/mingw/bin、x86/mingw/lib以及cmake相关的配置目录。因为 Qt 5.9.6 的 MinGW 套件是 32 位,所以这里走到x86/mingw/lib,如果你自己装了 64 位 MinGW,才会看到x64/mingw/lib。
安装目录里会生成 OpenCVConfig.cmake,这是后续在 CMake 工程里用find_package(OpenCV REQUIRED)直接找到的配置文件。有人觉得奇怪,明明编译的是 32 位,为什么配置里会有x86目录?这是因为 OpenCV 的 CMake 脚本按照平台架构来组织安装路径,x86表示 32 位构建结果。后面写工程时,-L路径和 PATH 里的 bin 路径都要指向这个目录。
安装完成后,建议顺手把C:/dev/opencv-install/x86/mingw/bin加进用户环境变量 PATH,虽然 Qt Creator 里可以通过运行环境变量配置,但加好后在 CMD 里跑测试程序更方便。
5. 常见问题与排查:编译和链接期的 5 个具体案例
5.1 案例一:imshow 报错 The library is compiled without QT support
现象:程序编译链接都通过,但一运行到cv::imshow("test", img),OpenCV 直接抛异常,提示The library is compiled without QT support in function 'imshow'。
原因:OpenCV 在配置阶段 WITH_QT 没有真正打开,highgui 回退到了 Win32 后端。这个回退是静默发生的,CMake 配置输出那里没有出现GUI: QT,编译出来的库就没有 Qt 窗口能力。
解决:回到第 3.2 节的 CMake 命令,重点确认CMAKE_PREFIX_PATH正确指向 MinGW 套件目录。配置完成后看终端输出里的 GUI 行,确认是 QT 再编译。如果已经编完了,必须删掉 build 目录重新配置,光改一个 CMakeCache.txt 里的 WITH_QT 值不够,因为模块依赖关系已经生成了。
5.2 案例二:运行报错找不到 libopencv_world320.dll
现象:exe 生成成功,双击运行时 Windows 弹窗提示找不到libopencv_world320.dll。
原因:OpenCV 的 bin 目录没有出现在 PATH 环境变量里。MinGW 编译的动态库不会自动复制到系统目录,exe 启动时按 PATH 顺序找 DLL,找不到就直接退出。
解决:在 CMD 里先设置 PATH 再运行程序:
set PATH=C:\dev\opencv-install\x86\mingw\bin;C:\Qt\Qt5.9.6\5.9.6\mingw53_32\bin;%PATH%在 Qt Creator 里跑,则需要把这条 PATH 写进项目的“运行环境”变量。还有一个更土但好用的办法:直接把libopencv_world320.dll和 Qt 相关 DLL 复制到 exe 同目录。注意复制前确认 exe 是 32 位,别把 64 位的 DLL 复制进去。
5.3 案例三:编译时报错 cannot mix incompatible Qt library
现象:编译或链接时出现类似cannot mix incompatible Qt library (version 0x50601) with this library (version 0x50906)的报错。
原因:OpenCV 编译时链接了一个 Qt 版本,而你的 Qt Creator 工程里用的是另一个 Qt 版本。最常见的是系统里先装了 Qt 5.6 或 Qt 5.15,CMAKE_PREFIX_PATH被 CMake 在当前目录或环境变量里扫描到了多个 Qt 路径。
解决:不要在一个 CMake 配置命令里塞多个CMAKE_PREFIX_PATH到不同 Qt 根目录。只保留 5.9.6 的 MinGW 套件,同时删掉 build 目录重来。另外检查C:/Qt下面是否有多个版本残留,如果有,尽量把它们移出 CMake 默认搜索范围,用第 3.2 节的完整命令重新生成。
5.4 案例四:链接器报 undefined reference to cv::imread
现象:MinGW 链接器刷出一排undefined reference to cv::imread(std::string const&, int),或指向cv::Mat构造函数。
原因:链接的库不对。最常见的是把官方 MSVC 预编译包里的opencv_world320.lib直接喂给了 MinGW 链接器。.lib和 MinGW 的.dll.a是两种格式,链路时所有 C++ 符号都找不到。另一个常见原因是你没有指定-L到自编译安装目录的x86/mingw/lib,导致链接器找到了别的 OpenCV 版本。
解决:确认链接路径是C:/dev/opencv-install/x86/mingw/lib,这个目录里应该有libopencv_world320.dll.a。如果用的是 CMake 工程,不要自己手写${OpenCV_LIBS}的名字,直接让它展开;如果用的是 qmake 工程,确保LIBS += -lopencv_world320前面对应了正确的-L路径。如果之前试过用转换工具把.lib转.dll.a,删掉那个手工产物,MinGW 自编译库才是正路。
5.5 案例五:Qt 平台插件 "windows" 找不到 / 窗口一闪而过
现象:程序启动后弹窗提示could not find or load the Qt platform plugin "windows",或者 imshow 窗口一闪而过,进程直接退出。
原因:OpenCV 的 highgui 链接了 Qt5Gui,但运行时 Qt 的 plugins 路径没有配置。Qt 在 Windows 上需要platforms/qwindows.dll这个插件来创建窗口,插件目录默认在 Qt 安装目录的plugins下。如果你没有调用 Qt 的QApplication,OpenCV 内部虽然会创建 QApplication,但插件路径不会自动写入。
解决:在 exe 旁边放一个qt.conf文件,内容如下:
[Paths] Plugins=C:/Qt/Qt5.9.6/5.9.6/mingw53_32/plugins或者把 Qt 的 bin 目录加进 PATH。更推荐用windeployqt工具把需要的 Qt 库和 plugins 复制到 exe 同目录,之后发布到别的机器也不会看到这个报错。对于内部测试,直接在 Qt Creator 里运行最省心,它会自动带上 Qt 相关环境变量。
6. 在 Qt Creator 里集成并验证 Qt 后端:最小工程写法
6.1 用 CMake 工程链接 OpenCV
前面几步走完,OpenCV 已经是 MinGW + Qt 双支持状态。建立一个最简单的 CMake 工程验证一下:
cmake_minimum_required(VERSION 3.10) project(opencv_qt_demo) set(CMAKE_PREFIX_PATH "C:/dev/opencv-install" "C:/Qt/Qt5.9.6/5.9.6/mingw53_32" ) find_package(OpenCV REQUIRED) find_package(Qt5 REQUIRED COMPONENTS Widgets) add_executable(qt_demo main.cpp) target_link_libraries(qt_demo PRIVATE ${OpenCV_LIBS} Qt5::Widgets)主文件main.cpp里写一个最简单的图片显示程序:
#include <opencv2/opencv.hpp> #include <iostream> int main() { cv::Mat img = cv::imread("C:/dev/test.png"); if (img.empty()) { std::cerr << "imread failed" << std::endl; return 1; } cv::namedWindow("Qt Backend Check", cv::WINDOW_NORMAL); cv::imshow("Qt Backend Check", img); cv::waitKey(0); return 0; }这个工程跑通后,说明find_package成功定位了 OpenCV 的 MinGW 库,imshow创建的是 Qt 窗口。如果没跑通,回头看第 5 章那五条。
6.2 用 qmake 工程链接 OpenCV
不习惯 CMake 的人可以在.pro文件里直接写:
QT += core gui widgets TEMPLATE = app TARGET = qt_demo CONFIG += c++11 INCLUDEPATH += C:/dev/opencv-install/include LIBS += -LC:/dev/opencv-install/x86/mingw/lib -lopencv_world320 SOURCES += main.cpp因为你的工具链是 32 位 Qt,-L路径里的 x86 别改成 x64。如果 OpenCV 安装目录里没有x86/mingw,就打开文件管理器找一下libopencv_world320.dll.a实际放在哪,以那个目录为准。
6.3 验证 Qt 后端生效的三种迹象
窗口显示出来后,看一眼特征:理想状态下的窗口有 Qt 工具栏,包括放大、缩小、保存、复制图片等图标,普通 Win32 后端没有这些。第二种验证是把鼠标悬停在窗口上,Qt 后端会在状态栏显示像素坐标和 RGB 值。第三种最直接,在代码里打印:
std::cout << cv::getBuildInformation() << std::endl;在输出信息里搜索GUI,如果是QT就说明这份 OpenCV 确实带 Qt 支持。
后续做界面设计的时候,很多人会把 imshow 窗口嵌进 Qt Designer 搭好的界面里。那时不要走 OpenCV 的窗口,而是把cv::Mat转成QImage再放到 QLabel 上。这个转换不难,注意 BGR 到 RGB 的通道顺序即可。我自己的习惯是先让 imshow 跑通验证库没问题,再去做 Qt 控件嵌入,这样问题能切得干干净净。希望这套编译、集成和排查的路径帮到你,让你在 Qt 里用 OpenCV 少走弯路。
本文还有配套的精品资源,点击获取