ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Qt与OpenCV环境配置全攻略:版本匹配、CMake编译及常见坑解析

Qt与OpenCV环境配置全攻略:版本匹配、CMake编译及常见坑解析 1. 配置前的前期准备版本选对了事就成了一半先说结论这个操作我能一次跑通靠的不是运气而是版本匹配。Qt配置OpenCV卡住的人十有八九是卡在“版本搭配”这一步而不是配置本身。如果你还不太熟悉这套组合我先把它们的作用说清楚。Qt是一套跨平台的C图形界面开发框架你可以把它理解成一个“装修队”负责把代码变成带按钮、窗口、图片的界面程序。OpenCV则是一套极度成熟的计算机视觉库里面封装了几千个图像处理相关的算法函数从“让一张图片变灰度”这种基础操作到“实时识别人脸”这种高级功能都有现成接口可以调。而配置这件事通俗点说就是把OpenCV这个“工具仓库”的地址告诉Qt让Qt写代码的时候能随时去仓库里拿工具。我的建议版本组合是这样的Qt版本5.14.2离线安装包带MinGW 7.3.0 64-bit编译器OpenCV版本4.5.5Windows版源码包CMake版本3.22.6注意不是越新越好这个组合是我实际验证过可以稳定走通的。下面我把每一步操作、每个按钮位置、每个可能踩的坑都给你交代清楚。2. Qt安装与环境检查两个最容易忽略的前提2.1 安装路径务必避开中文和空格Qt的安装本身不复杂运行安装包勾选组件下一步下一步就行。但有两点必须提前处理好否则后面编译OpenCV时会莫名其妙报错。第一安装路径不要带中文不要带空格。“D:\Qt”和“D:\Program Files\Qt”这种路径虽然平时用着没什么感觉但在CMake解析路径时空格会导致脚本无法正常拼接路径报出一堆和实际原因毫无关联的错误。我就见过有人在“D:\软件\Qt”这种路径下配了三天没配好换到纯英文路径后一次通过。第二也是很多人没意识到的关键点在Qt安装组件列表里必须确认MinGW编译器已经被勾选。正常安装时工具链Tools这个节点下会有“MinGW 7.3.0”的选项记得勾上。如果你当初安装时偷懒没选后面写OpenCV代码时Qt会提示“没有找到编译器”那就必须重新运行安装程序补充安装非常耽误时间。2.2 用自带MinGW而不是MSVCWindows下Qt的编译器有两种可选MSVC微软的Visual Studio编译器和MinGWGCC的Windows移植版。这个选择直接决定了你后续要用哪个OpenCV包一定不能搞混。如果你用的是MSVC那么可以去OpenCV官网直接下载官方预编译好的“win-pack”版本解压就能用完全不用自己编译。如果你用的是MinGW那很遗憾官方并没有提供对应的预编译包你必须下载OpenCV源码然后用CMake手动编译一遍。我之所以推荐MinGW路线是因为Qt对MinGW的支持非常自然不需要额外安装庞大的Visual Studio整个过程也更简洁适合绝大多数Qt开发者。3. OpenCV源码包获取别下错包这是新手最容易翻车的环节3.1 官网下载还是GitHub下载OpenCV的官方发布页面在GitHub的opencv/opencv仓库里每个Release版本下面都会挂一系列安装包。你在那个列表里会看到很多名字很像的文件Windows用户常见的选择有两个opencv-4.5.5-windows.exe这是官方预编译的Windows安装包自解压程序里面包含的是VC编译的库文件也就是给MSVC用户用的。Source code (zip)这是OpenCV的源码压缩包也就是给MinGW用户编译用的。很多新手在这里会直接点击下载“opencv-4.5.5-windows.exe”解压之后高高兴兴地去Qt里配置结果编译时报出一大堆“未定义的引用”错误。原因很简单预编译包里的库文件是MSVC格式的MinGW的链接器无法识别这种格式。所以请注意如果你使用的是MinGW编译器必须下载**Source code (zip)**这个源码包而不是那个.exe自解压包。下载后解压到“D:\opencv”这种纯英文且无空格的目录下。3.2 解压后的目录结构长什么样解压源码包后你会看到一个名为“opencv-4.5.5”的目录里面至少包含以下关键子目录modulesOpenCV的所有模块源码比如imgproc图像处理、core核心数据结构、objdetect目标检测等。CMakeLists.txt这是给CMake读取的总构建脚本。samples官方示例代码。platforms针对不同平台的编译脚本。这里面没有“build”目录因为build是编译后生成的成果目录需要你自己创建。这也是后续CMake配置时的“兵家必争之地”。4. CMake工具准备版本不是越新越好4.1 CMake是做什么的简单说CMake是一个“构建脚本生成器”。OpenCV的源码文件非常多如果直接用命令去一条条编译会累死人。CMake的作用就是读取OpenCV的CMakeLists.txt描述文件自动检测你系统里的编译器环境然后生成一套适合你当前环境的编译工程文件在WindowsMinGW环境下生成的是Makefile文件最后你用make工具按这份工程文件去批量编译。4.2 选择CMake版本的教训我最初用的是最新版CMake 3.29结果在configure阶段OpenCV就报出语法不兼容的错误查了很久最后发现是CMake版本过新导致的兼容性问题。后来换成了3.22.6一次通过。这个版本附近的CMake和OpenCV 4.5.x配合得比较好没有过时的API问题。CMake安装完成之后建议把它加入系统PATH环境变量。验证方法是打开命令行窗口输入“cmake --version”如果能看到版本号就说明安装成功。有些CMake安装包支持“Add CMake to system PATH for all users”的选项记得勾上。5. CMake编译OpenCV全过程重点操作与参数说明5.1 设置源码目录与构建目录启动CMake图形界面cmake-gui第一个要填的是“Where is the source code”这项要填OpenCV源码目录也就是包含CMakeLists.txt的那个路径即“D:/opencv/opencv-4.5.5”。第二个要填的是“Where to build the binaries”也就是构建目录习惯上在这个源码目录旁边建一个“build”文件夹填入“D:/opencv/opencv-4.5.5/build”。这里不建议把构建目录设置在源码目录里面否则会让后续清理或更新变得很麻烦。5.2 选择MinGW Makefiles生成器点击“Configure”按钮后CMake会弹出一个选择生成器的对话框。这里有几个下拉选项通常默认是“Visual Studio 17 2022”必须手动改选。关键一步来了下拉框中会有一堆带MinGW字样的选项。如果你使用的Qt自带的是MinGW 7.3.0 64位版本那么请选择“MinGW Makefiles”。同时下面有个“Specify native compilers”的复选框建议勾上这样你可以直接指定编译器的路径避免CMake自动搜索出错。点击“Next”后需要分别填写以下内容C编译器D:/Qt/Tools/mingw730_64/bin/gcc.exeC编译器D:/Qt/Tools/mingw730_64/bin/g.exe注意路径前缀要和你的Qt安装位置一致。我的Qt安装在D盘所以路径是“D:/Qt/Tools/mingw730_64/...”如果你装到别的盘要按实际情况调整。5.3 configure阶段需要调整的选项首次点击“Configure”后CMake会开始检测编译器和环境此时界面下方会滚动输出检测日志。这个过程可能会持续几分钟等进度条走完界面上方会密集地冒出很多红色的配置项这都是正常的说明有新的CMake缓存变量被检测出来了还没配置完成并不是报错。在红字配置项里需要修改几个关键的开关参数WITH_OPENMP建议勾选。这个选项启用OpenMP并行计算能让OpenCV在部分图像处理算法中利用多核CPU加速明显提升运行速度。WITH_IPP可以考虑取消勾选。IPP是Intel的加速库Qt自带的MinGW编译器不一定能充分兼容。BUILD_SHARED_LIBS保持勾选。这会生成动态链接库.dll文件。这比静态库方便很多因为编译完成后生成的库体积更小更新时只需要替换dll无需重新链接整个程序。如果你的项目需要静态库取消它也可以但初学者建议保持动态库。BUILD_opencv_world建议勾选。这个选项会把OpenCV的所有模块合并成一个统一的“opencv_world455.dll”文件而不是生成上百个零散的dll。实际引用时只链接这一个库就够了非常省心。设置完成后再次点击“Configure”此时红色配置项会逐渐变少日志中如果出现“Configuring done”字样就说明配置阶段成功通过了。5.4 Generate阶段生成Makefile与库文件点击“Generate”按钮CMake会根据上一步生成的配置在build目录下写入一份完整的Makefile。日志里出现“Generating done”就表示CMake侧的工作全部完成。到这一步CMake的任务已经结束接下来真正动手编译的是mingw32-make。需要注意的是整个配置过程是做OpenCV完整编译的前置工作而不是全部工作。初次配置OpenCV时如果不了解CMake的作用很容易以为点击Generate就大功告成了这是不正确的理解实际编译过程即将开始。6. mingw32-make编译与安装最耗时的一步别盯着屏幕发呆6.1 打开命令行并定位到build目录在Windows的搜索栏输入“cmd”选择“命令提示符”建议右键选择“以管理员身份运行”因为后续的install步骤需要往系统目录写入文件。在命令行窗口中先执行D: cd D:\opencv\opencv-4.5.5\build注意这里用的是反斜杠因为这是Windows命令行不是CMake图形界面。进入build目录后确认目录下能看到一个名为“Makefile”的文件这是CMake生成的编译脚本入口。6.2 执行编译命令在命令行中输入D:\Qt\Tools\mingw730_64\bin\mingw32-make.exe -j4这里有两个细节值得说。第一要用双引号把mingw32-make.exe的完整路径括起来因为路径中带有空格不括起来命令会解析错误。第二后面跟的参数“-j4”表示用4个线程并行编译。如果你是8核或16核处理器改成“-j8”或“-j16”能明显加快速度。不过对于内存少于8GB的机器并行数过高容易卡内存因为每个编译线程都吃内存这是一个实际使用中的权衡。编译开始后命令行会疯狂滚动显示正在编译哪个源码文件。这个过程十分漫长常规配置下大约需要30到60分钟具体取决于CPU性能。有很多人以为这个画面是卡死了其实只要每过几秒能看到新的文件路径在跳动就是正常的。编译过程中最让人崩溃的其实是那些没有明显规律的报错。我遇到过一次“unrecognized command-line option”的错误排查了一圈最后发现是MinGW的版本和OpenCV新代码不兼容。所以再次强调请确保你用的是Qt选的MinGW 7.3.0而OpenCV版本也尽量选4.5.5或者4.5.x系列。如果编译中途报错不要急着重新开始。先看日志里最后几行的具体错误信息绝大多数情况下错误提示会直接告诉你改了哪个文件就会出现问题你针对性解决后重新执行mingw32-make它会从上次失败的位置继续而不是全部重来。6.3 install阶段生成最终可用的库目录编译完成后继续执行D:\Qt\Tools\mingw730_64\bin\mingw32-make.exe install这条命令会把编译好的动态库、头文件、cmake配置文件统一安装到“build/install”目录中。install结束后打开“D:\opencv\opencv-4.5.5\build\install”目录你会看到以下三个子目录include包含OpenCV的全部头文件x64/mingw/bin包含关键的dll文件如opencv_world455.dllx64/mingw/lib包含链接用的导入库文件如libopencv_world455.dll.a到这一步OpenCV的编译安装其实已经完成下面要做的就是让Qt能找到它们。7. Qt工程中的具体配置pro文件与系统环境变量两手都要抓7.1 在pro文件中正确声明OpenCV路径在Qt Creator里打开你的项目工程文件也就是那个后缀为“_qt_version”的.pro文件在文件末尾追加以下内容。注意不同OpenCV版本号不同我这里是4.5.5请按你的实际情况修改路径INCLUDEPATH D:/opencv/opencv-4.5.5/build/install/include LIBS D:/opencv/opencv-4.5.5/build/install/x64/mingw/lib/libopencv_world455.dll.a这里解释一下两个变量的作用。INCLUDEPATH告诉编译器“去哪里找头文件”你写代码时“#include opencv2/opencv.hpp”这行指令能编译通过全靠它。LIBS告诉链接器“去哪里找函数的具体实现”如果这行配置不对编译能通过但是链接阶段会大量报“undefined reference to cv::...”之类的错误。我建议在LIBS行中使用绝对路径来指定库文件。虽然Qt的pro文件里也支持“LIBS -L路径 -lopencv_world”这种更灵活的写法但对于初学者来说绝对路径是最不容易出错的方式一次就能成功。7.2 关于pro文件中“unknown module”报错的特别说明网上很多人会建议在pro文件里加一行“QT opencv”这种做法是错误的。Qt官方的模块列表里根本没有opencv这个模块Qt不能直接“读取”OpenCV。OpenCV不是Qt的插件它们只是一个C库你通过INCLUDEPATH和LIBS告诉编译器“去哪里找这个库的接口和实现”就行。加上“QT opencv”后反而会报“Project ERROR: Unknown module(s) in QT: opencv”的错误。如果你在配置Qt与OpenCV时看到这句话往往就是在pro文件里多余地加了一行“QT ”。请把那些无用行去掉回到正常的库引用方式。7.3 配置系统环境变量避免运行时找不到dll代码编译成功只是第一步。当你点击“运行”按钮时程序启动后会加载OpenCV的dll文件。如果系统找不到这个dll程序会直接闪退而Qt输出栏里不会给出任何具体项目相关的提示只会有“程序异常结束”这类含糊信息。解决方法是把opencv_world455.dll所在的目录加入系统环境变量PATH。右键“此电脑”选择“属性”进入“高级系统设置”点击“环境变量”在“系统变量”里找到“Path”这一行点击“编辑”然后新建一条填入D:\opencv\opencv-4.5.5\build\install\x64\mingw\bin配置完成后需要重启Qt Creator让环境变量生效。除了系统环境变量还有一个替代方案很实用直接把opencv_world455.dll复制到你生成的exe可执行文件所在的目录下。Qt生成的exe一般在“build-项目名-Desktop_Qt_5_14_2_MinGW_64_bit-Debug/debug”目录中。这两种办法可以同时用第一种一劳永逸第二种更直观。如果两种办法都做了程序仍然提示找不到dll大概率是你把DLL的位数或编译器类型搞错了可以反复核对一下。8. 完整测试代码验证配置是否真正成功8.1 读取并显示一张图片新建一个Qt Widgets Application项目在main.cpp中写入以下代码#include QApplication #include QLabel #include opencv2/opencv.hpp int main(int argc, char *argv[]) { QApplication a(argc, argv); cv::Mat image cv::imread(D:/test.jpg); if (image.empty()) { return -1; } cv::Mat rgbImage; cv::cvtColor(image, rgbImage, cv::COLOR_BGR2RGB); QLabel label; QImage qimg(rgbImage.data, rgbImage.cols, rgbImage.rows, rgbImage.step, QImage::Format_RGB888); label.setPixmap(QPixmap::fromImage(qimg)); label.show(); return a.exec(); }这里有一个特别注意点OpenCV默认读入图片的颜色通道顺序是BGR而Qt显示图片时一般使用RGB。如果你直接从cv::Mat转为QImage而不做颜色转换你会发现显示出来的图片色调明显泛蓝。所以我在代码里先调用“cv::cvtColor”把BGR转换为RGB再交给QImage显示。很多初学Qt配OpenCV的人都会踩到这个颜色问题。8.2 摄像头实时画面测试如果图片测试通过那么摄像头测试是更全面的验证。因为摄像头采集涉及视频流解码如果库编译有问题这里的表现会比图片更明显。测试代码如下#include QApplication #include QLabel #include QTimer #include opencv2/opencv.hpp int main(int argc, char *argv[]) { QApplication a(argc, argv); cv::VideoCapture cap(0); if (!cap.isOpened()) { return -1; } QLabel label; QTimer timer; QObject::connect(timer, QTimer::timeout, []() { cv::Mat frame; cap frame; if (frame.empty()) { return; } cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB); QImage qimg(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888); label.setPixmap(QPixmap::fromImage(qimg).scaled(label.size(), Qt::KeepAspectRatio)); }); timer.start(33); label.resize(640, 480); label.show(); return a.exec(); }这段代码的逻辑是每33毫秒从摄像头抓一帧图像转换格式后显示的QLabel上。如果程序能流畅显示摄像头画面说明OpenCV的核心模块、视频模块以及图像显示管线在你的Qt环境中全部正常工作。9. 常见问题与排查技巧这些坑网上搜不到那么全9.1 “unknown module(s) in QT: serialport”是什么情况有不少人在配置Qt项目时会在pro文件里加“QT serialport”但编译时提示“Project ERROR: Unknown module(s) in QT: serialport”。这个错误通常有两种原因。第一你在安装Qt时没有勾选SerialPort模块。Qt的模块很多默认安装不会带全。你需要在Qt安装目录下找到“MaintenanceTool.exe”运行它组件选择里勾选“Qt Serial Port”模块后更新安装。第二可能是你安装的是某些精简版的Qt发行包这些精简版不是官方原版模块被裁剪了所以建议不要在非官方渠道下载Qt安装包而是到官方源或可信的镜像源下载。这类问题的核心在于Qt的能力是按模块组织的一个模块缺失就需要单独补齐与OpenCV无关。9.2 OpenCV头文件找不到如果你写的“#include opencv2/opencv.hpp”在Qt中直接显示红色波浪线且编译时报“No such file or directory”说明INCLUDEPATH路径没有配置正确。检查一下“D:/opencv/opencv-4.5.5/build/install/include”这个目录里是否真的有“opencv2”的文件夹。如果没有说明install步骤未完成或编译中途出错你需要重新检查第5、6步。这里有一个排查细节很多人觉得“build目录下应该有include”但实际OpenCV源码目录也有一个include文件夹两者不是一个概念。源码目录的include是比较简单的基础头文件结构而build/install/include是从源码中整理并复制出来的最终成果。要让Qt引用的是install目录里的include而不是源码目录稍显残缺的include。9.3 编译能过链接时报undefined reference这类报错的最大特点是代码编译阶段毫无异常但链接时冒出一堆“undefined reference to cv::imread”之类的错误。这几乎可以断定是LIBS路径配置不对或者链接的库文件名称与OpenCV版本不一致。比如OpenCV 4.5.5的库文件名是“libopencv_world455.dll.a”版本号不同文件名里的数字就不一样。如果你是4.5.4版本就应该写成“libopencv_world454.dll.a”。版本号和文件名不符时链接器找不到库就会把它当成不存在的符号。建议打开“D:/opencv/opencv-4.5.5/build/install/x64/mingw/lib”目录看看到底是哪个.a文件然后把pro文件里的库路径直接改成实际存在的文件名。9.4 运行时提示找不到opencv_world455.dll如前面所说这是运行时环境变量问题。你编译生成的exe在启动时会按顺序去以下几个地方找依赖的dllexe所在目录、系统PATH环境变量中的目录、系统目录。如果找不到程序就会弹出错误提示框或在Qt输出栏中显示“程序异常结束”。处理方法是把bin目录加入系统PATH并重启Qt Creator。还有一个细节很多人忽略你如果重新编译了OpenCV把新的dll替换到系统目录中那么运行旧程序时可能会出现版本不一致的兼容性问题。所以最稳妥的方式还是让exe目录与dll目录保持一致。9.5 Qt程序与OpenCV的调试信息不兼容在Debug模式下如果链接OpenCV后运行时报“Stray \xxx in program”或调试信息格式错误有两个解决方案。一是切换到Release模式编译运行这种模式不涉及调试信息的复杂性。二是在pro文件中加一行“QMAKE_CXXFLAGS -g0”去掉调试符号可以消掉大部分此类问题。这条经验比较偏门工人平时不会主动提但确实管用。9.6 配置后OpenCV图像处理速度异常缓慢配置成功后如果发现运行图像处理程序非常卡顿首先要看编译时是否勾选了WITH_OPENMP。如果没有OpenCV在单线程下执行像素级操作时会慢很多因为普通图像循环本身就是CPU密集型的没有并行优化确实吃力。另一个可能是你链接的是Debug版本的OpenCV库而OpenCV的Debug与Release在算法代码上差异不小前者带有很多检查逻辑和未优化路径运行速度会明显降低。建议在性能敏感项目中使用Release版编译的库。10. 从配置到部署跨平台项目中的环境管理经验谈10.1 用windeployqt处理依赖项当你的程序开发完成后需要发给别人用。别人电脑上没有安装Qt和OpenCV程序无法运行。这时可以用windeployqt工具自动拷贝Qt相关的dll到exe目录下这是Qt官方自带的一条命令。在命令行中定位到exe所在目录执行D:\Qt\5.14.2\mingw73_64\bin\windeployqt.exe 你的程序名.exe这个命令会把Qt运行所需的全部dll拷到exe旁边。不过它不会处理OpenCV的dll需要手动把opencv_world455.dll复制到exe目录中。如果想直接把两个步骤合并也可以在自己的pro文件里添加自定义步骤但那样配置会复杂一些。对于Qt和OpenCV这种组合建议在项目一开始就规划好文件和目录结构比如把所有第三方库统一下到“D:/ThirdParty/”下Qt装成“D:/Qt”OpenCV解压到“D:/ThirdParty/opencv”。这样写pro文件时路径更清晰迁移到新电脑也更方便只需把目录原样拷走路径结构保持一致即可。10.2 环境不一致是万恶之源很多读者会疑惑为什么按照同样的教程操作结果却不一样根源在于环境不一致。OpenCV的代码写得好不好不重要关键是它依赖的底层库版本、编译器版本、CMake版本、操作系统的位数、架构类型是否匹配。这些变量只要有一两项不匹配就会出现各种离奇问题。因此第一遍配置时最好严格按照已验证过的版本来后面熟悉了再尝试更新版本。11. 我踩过的坑和最终落地的一点心得最后这条留在后面说是希望你看完全文后能带着一份完整的心态去做这件事而不是只盯着某个步骤。我最初配Qt和OpenCV时在编译OpenCV那个环节就栽了两次。第一次是下载了带exe后缀的预编译包在Qt中链接失败第二次是CMake版本太新configure环节就报错。当时非常崩溃一度以为是自己的操作问题后来冷静下来逐个排查才意识到问题出在“包选错了”和“版本过新了”。这两类问题教程里很少有人明确指出因为每个人的失败路径不同。配置成功之后的成就感还是很强的尤其是第一次在Qt窗口里看到摄像头画面流畅刷新时你会觉得前面的折腾都值了。之后我做图像处理项目时都是在Qt界面上直接调用OpenCV的函数写起来很舒服界面的调试也方便太多比如把阈值滑条直接做到界面上实时调节参数不用像纯命令行那样反复改代码重编译这对算法调参的效率提升非常大。如果你想在这个基础上继续深入我建议不要止步于“配置成功”这点上。你可以尝试自己写一个简单的人脸检测小程序或者做一个图片批量处理的工具用Qt把自己需要交互的部分做成界面用OpenCV在后台处理。等这个流程跑通了你就算真正把这两套技术栈焊接在了一起而不是停留在“读图片、显示图片”的演示阶段。我不会跟你说“配置失败就是你不认真”因为这套环境确实有很多坑。只是希望这篇教程能帮你少走我当初走过的弯路一次跑通然后把时间花在更有意思的图像处理本身。如果一个配置项卡住了建议你按照这个顺序自查确认用的OpenCV版本和编译器类型是不是匹配、确认路径有没有中文或空格、确认pro文件里的库文件名版本号对不对、确认dll是否放到了正确位置。绝大部分问题逃不出这四步。
返回列表