Windows环境下的编程工具Visual Studio,调试功能很好用。之前是在VS上写调用OpenCV库的C++代码。现在有设计界面的需求,但是不喜欢VS自带的C++ GUI库MFC。所以选择了安装QT。
写Qt程序,可以在VS中安装Qt插件,这是一种开发方式。但QT不只是个GUI库,它还具备像VS一样的IDE,叫 Qt Creator。这篇博客介绍QT Creator和OpenCV开发环境配置。
在windows环境下,Qt和OpenCV都可以编译安装成两种版本:MinGW和MSVC。网上有很多MinGW版的QT配置OpenCV的资料,使用MinGW版需要用CMAKE编译安装。OpenCV安装库目录自带VC版。为了windows下,使用编译器的统一、以及与VS切换方便,下面介绍VC版的配置。
软件版本
PC上原来安装有VS2013,OpenCV2.4.12, VS配置OpenCV的过程参见这篇博客:在Visual Studio下配置OpenCV的3种方式,总结一下就是把OpenCV的包含目录(包含.h头文件)、库目录(包含.lib文件)、执行目录(包含.dll文件)添加进去。
安装Qt的版本是qt-opensource-windows-x86-msvc2013-5.6.0,可以看到使用的编译器和VS2013一样,是msvc2013(或叫做VC12)。
配置
在Qt creator 中也一样。只不过在VS中需要修改项目属性表,而在Qt Creator中需要修改.pro文件。
.po文件涉及构建C++程序。这个概念对于习惯VS环境开发的人可能会陌生,毕竟强大的IDE可以让“预处理-编译-链接-运行”这一过程变得轻易而被忽略。然而Linux环境开发C++程序需要写Makefile,用来构建程序。学会写MakeFile语法需要花费一定时间,Qt发明.pro文件,语法更简单明了,使用Qt的qmake工具可以生成makefile文件。
打开安装好的OpenCV安装库目录,可以找到包含目录(包含.h头文件)、库目录(包含.lib文件)、执行目录(包含.dll文件)。可以看到需要导入dll,开发程序是以动态库的形式调用OpenCV。
例如下面是包含目录路径。
D:\opencv\build\include
D:\opencv\build\include\opencv
D:\opencv\build\include\opencv2
例如下面是库目录路径。开发方式我选择了x86 32位开发,vc12代表的是编译器版本,VS2013使用的是VC12。没有相应的目录意味着需要自己去编译源码。
D:\opencv\build\x86\vc12\lib
例如执行目录如下所示。
D:\opencv\build\x86\vc12\bin
然后打开Qt Creator,新建一个控制台应用程序,在main.cpp里测试代码如下。可以看出是完成了一个读取图像,然后显示的操作;其中使用waiKey()交互式地控制程序结束。
#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
int main(int argc,char **argv)
{
Mat src=imread("C:/Users/john/Desktop/qt.jpg"); //在qt里面读取图片貌似只支持绝对路径
imshow("test",src);
waitKey(0);
return 0;
}
修改.pro文件,添加如下几行。这里由于程序实现的操作比较基本,只需要添加core、highgui、imgproc3个模块库文件即可。如果对OpenCV尚未熟悉,可将库目录下的所有库文件添加进去。
#包含目录
INCLUDEPATH+= D:/opencv/build/include/opencv \
D:/opencv/build/include/opencv2 \
D:/opencv/build/include
#库文件
LIBS+= -LD:/opencv/build/x86/vc12/lib \
-lopencv_core2412d -lopencv_highgui2412d -lopencv_imgproc2412d
添加执行路径,即bin目录,可通过设置环境变量。把例如下面的路径添加进系统变量的Path变量里。注意添加分号。
D:\opencv\build\x86\vc12\bin;
注意事项
一、每一次修改.pro文件之后,记得qmake一下,以及,清理项目。否则即使重新构建,也没有变化效果。这可以叫做“惰性”吗?
二、添加包含路径,使用INCLUDEPATH+=
,是+=
,而不是=
,意味着“添加”而非“赋值设置”,更为安全。在Windows下路径中/
也可以写成\
或者\\
。但是注意末尾的反斜杠\
,不能写成/
,它代表换行连接。意思是一行太长了,不好看,换一行书写。但不换行也行。
三、添加库目录,使用LIBS+=
。后面可以直接跟库文件路径,也可以使用-L
和-l
。-L
后是目录,-l
是文件名。例如添加opencv_core2412d.lib、highgui2412d.lib、imgproc2412d.lib的两种写法。
LIBS+= -LD:/opencv/build/x86/vc12/lib \
-lopencv_core2412d \
-lopencv_highgui2412d \
-lopencv_imgproc2412d
或
LIBS+=D:/opencv/build/x86/vc12/lib/opencv_core2412d.lib \
D:/opencv/build/x86/vc12/lib/opencv_highgui2412d.lib \
D:/opencv/build/x86/vc12/lib/opencv_imgproc2412d.lib
四、添加包含目录失败,会出现编译错误
error: C1083: 无法打开包括文件: “… .hpp”: No such file or directory
添加库目录失败,会出现链接错误
error: LNK2019: 无法解析的外部符号 …
五、比较坑的是,执行目录没添加进去,程序会没反应,但主程序返回一个奇怪的值。运行的时候出现exited with code -1073741515错误。
exited with code -1073741515
将这个返回值以32位方式转换,-1073741515 ⇒ 0xC0000135,然后会得到一个NT状态码:STATUS_DLL_NOT_FOUND
。这意味着因为DLL文件丢失,Windows不能打开这个程序。
但好像dll文件的目录,即bin目录,已经被添加进系统变量的Path里了。经过仔细检查我发现之前是这么做的:在系统变量中先新建一个opencv
变量,值为D:\opencv\build\x86\vc12\bin;
,然后在Path
中添加%opencv%;
。但这种形式Qt貌似看不懂。我直接将bin目录添加进Path中之后问题解决。
点击“项目”,“构建环境”,“使用系统环境变量”,可以在Qt Creator中检查环境变量。