前言
此为计算机视觉学习系列的第二篇文章,记录的是笔者以源码方式编译包含qt的opencv库的心得。
opencv是一个强大的图像处理库,而图像处理的结果还需要展示给用户看,但UI界面这块并不是opencv的强项,因此可以考虑将opencv与其他专门做UI的框架结合起来,各取所长。这篇文章选用的UI框架是Qt6。
操作的理论概要
要想让涉及opencv的代码也能用上Qt库,需要完成以下步骤:
- 开启opencv中的
WITH_QT
选项
以Windows平台为例,已经编译好的版本默认是不开启该选项的,所以如果想开启选项的话只能手动修改源码的CMakeLists
文件后重新编译(或者通过cmake-gui工具点击一下改相应选项属性,后续将描述这种方法)。
- 在项目中引入opencv相关库
详细步骤
手动编译源码
工具准备
- Qt6库
我的版本是6.6,MSVC编译版。
注意事项
- 用于编译Qt6的编译器最好与后续用于编译opencv的编译器对应,不要MinGW-w64与MSCV混用,否则可能出现意想不到的bug。
- 笔者个人体悟,最好选择对应平台的原生工具,比如在Windows上就用MSVC,在Linux上就用GCC/g++,可以尽可能规避一些意想不到的bug。
- opencv的sources源码
我的版本是opencv4.8
- cmake
我的版本是3.27.6
- CMake是一个开源的跨平台自动化构建工具,主要用于开发程序时,生成各种不同平台的Makefile或者项目文件。它支持多种编程语言,包括但不限于C、C++、Java和Fortran等,并能利用各种不同的编译工具生成可执行程序或链接库。 值得一提的是,CMake并不直接参与程序的编译过程,而是通过使用名为CMakeLists.txt的构建脚本来向相应的编译工具发出指令,由这些工具来完成最终的程序编译过程。
- cmake的更新较为频繁,新版本会有很多老版本不具备的特性,如果待编译的项目较新,旧版的cmake可能无法处理。所以如果是遇到生成的编译指令文件有错误的问题,可以视情况而定对cmake版本进行升级或者降级,也许问题就解决了。
- visual studio 2022
Visual Studio是一个IDE,这里主要是为了用它内置的MSVC2019编译器进行编译,并且为后续的编码工作提供方便。
使用cmake-gui
在Windows中,提供了cmake的GUI界面,方便我们更直观地了解正在操作的内容:
如上图所示:
- 1表示待编译的源码路径
- 2表示编译生成的目标路径,这里是我自己在源码之外新建了一个build目录
- 3展示的Name和Value值,其实是首次点击
Configure
按钮后 ,对源码路径下的CMakeLists
文件进行解析的结果。此处的红色表示的是还有修改的空间 ,如果要修改对应选项,就改;不改的话就再次点击configure,直到所有选项都不再是红色为止。记得在这里改上述说的WITH_QT
选项
方式:在搜索框中搜索关键字qt(不区分大小写),在
WITH_QT
选项中打勾
- 4表示的configure按钮其实是生成对应的编译指令文件。首次点击时会弹出一个窗口让人选择对应的编译器,我选的是我安装的visual studio 17 2022,它默认对应于MSVC2019。
注意事项:
- 在配置过程中如果发现自己操作有误/配置发生严重错误,可以在文件资源管理器中清空build目录或者删除build目录后重建,这样就又回到了初始状态,不让上一次的错误结果影响到下一次。
- 配置过程中会下载一些文件,建议备好梯子。也可以选择手动下载文件去替换,但是需要注意版本要对应以及修改哈希值。
- 5 在配置完全没有问题后,可以点击这个生成按钮,它会生成对应的配置文件。比如像我选择了vs,就生成了.sIn及相关文件用于打开对应文件夹项目进行后续配置。
- 6 点击这个
open project
按钮后,就会跳转到visual studio
打开源码目录这个项目;也可以自己打开visual studio
后点击打开项目按钮,选中源码下生成的.sIn文件,从而打开项目。
注:如果2中的build目录下没有生成install文件夹,可以自己创建一个。
使用Visual Studio进行编译
接下来就到了生成解决方案
的环节。其实是类似于使用MakeFile工具时的make
阶段。
如下图所示,在源码目录项目右侧中的解决方案资源管理器
中,依次找到CMakeTargets->INSTALL
,右键点击,选中生成
如果刚打开项目时没有看到
解决方案资源管理器
,可以从IDE上方的视图
一栏中找到该子选项
接下来就是build的阶段。
根据笔者的经验:如果前面生成的编译指令没有问题,这一步也不会有太大问题;但如果这一步有几十个报错,大概率是前面的步骤出现了问题,建议先退回去检查,剩下的要视情况决定该如何处理。笔者遇到过如下几类情况,对应的问题概要及方案思路如下(因为遇到问题的时候光顾着解决问题,没有来得及记录下所有完整的报错信息,现在只是回忆个大概):
- 由于找不到Qtxxx.dll......
- 先检查下对应路径是否真的不存在该dll文件,如果真找不到,说明Qt安装有问题,需要重装Qt;如果明明是有的,但安装了多个版本的Qt,先检查下在环境变量PATH中的Qt版本是否与这版对应,且编译Qt和opencv所用的编译器是否一致,不一致建议更换。(比如你有MinGW和MSVC这两个版本的Qt,opencv你选择了用MSVC来编译,Qt却选择了MinGW那版,那么建议你把Qt换回MSVC的版本,因为这两个不太兼容)
- 指向了一个只含宏的c语言文件,报错却是QString未定义
- 编译链接问题,建议检查之前生成编译指令的步骤是否有误
- Qt6必须要C++17,添加
/Zc:__cplusplus
选项- Qt6确实要对标C++17,修改项目属性中的C++编译器标准至C++17; 添加附加选项步骤如下:
- 一个指向某个文件中的的
constexpr
的问题->如果只有这一个文件有问题,把constexpr
改成const
(根据微软官方文档的说法,由于版本差异,有的源文件可能没改,需要手动微调下);但如果很多个文件都有问题,建议回退到生成编译指令步骤 - 如果在cmake的configure步骤中勾选了
BUILD_opencv_world
选项,到这一步可能会提示找不到那个和world相关的lib文件。我看了一下文件目录下,确实也没有这个文件。BUILD_opencv_world
默认是不开启的,它存在的作用也只是更好地将所有lib打包成一个lib,在初学阶段如果是因为这个报错影响编译的话,个人建议多一事不如少一事,退回到cmake阶段取消勾选并且重新生成算了。
成功生成后,在前述设置的build目录下的install文件夹中就能看到编译好的成品了。
如果只用这一个opencv版本的话,可以将输出目录下的install\x64\vc17\bin
的绝对路径写入环境变量的PATH中。
通过visual studio为某个项目配置opencv
配置思路
opencv本质上是一个库,包含了一些头文件、.lib文件(静态库)、.dll文件(动态链接库)。所以在项目中使用它的本质就是在编译项目的时候把相应内容也编译、链接进去或者直接使用。
具体步骤
- 设置include目录(opencv头文件所在目录):
- 设置lib目录:
- 设置附加依赖(将lib目录下的.lib文件名称写入)
其他方式:
- Qt项目采用qmake编译,编辑.pro文件: 添加
INCLUDEPATH +=
和LIBS +=
这两个属性并分别填写opencv库include目录和lib目录对应路径- Qt项目采用cmake编译,编辑CMakeLists.txt文件:
scss#如果有多个opencv版本,用set设置想要的版本路径 set(OpenCV_DIR 此处填路径) FIND_PACKAGE(OpenCV REQUIRED) INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OpenCV_LIBS})
至此,项目就配置成功了。可以跑一个入门demo试试效果:
其中的按钮是Qt生成的,图像处理结果则由opencv生成。