搭建Qt界面的OpenCV开发环境
2016-01-21 13:48
369 查看
OpenCV包含了大量的机器视觉处理算法,虽然也提供了highgui的界面功能,但实在有限(也就是一个窗口,加一些使用像素进行绘图的方法),与用户交互相关的功能极少(比如有Trackbar),貌似连个可视化的用户接口的button也没见过,而Qt正好能弥补OpenCV在这些方面的不足:通过OpenCV完成底层算法,用Qt完成上层的应用接口,哇咔,这不是完美组合么!本文原来的初衷是想通过Qt开发来实战练练C++,现在看来是要Qt与OpenCV一起搞了。这篇文章就是安装Qt及在Qt中配置OpenCV的开发环境。
安装Qt存在的一个普遍的问题是:低版本的gcc可能无法编译高版本的Qt。我参照了博客园中的一篇博客 ,搭配使用Qt4.8.6+QtCreator2.6.1+gcc4.9.2,这些软件的下载链接依次是:
qt-everywhere-opensource-src-4.8.6.tar.gz: http://download.qt-project.org/official_releases/qt/4.8/4.8.6/
qt-creator-linux-x86_64-opensource-2.6.1.bin: http://download.qt-project.org/official_releases/qtcreator/2.6/2.6.1/
gcc-4.9.2: http://mirror.bjtu.edu.cn/gnu/gcc/
根据自己的机器环境选择下载,我的环境是:CentOS 6.5 64bit。qt-creator仅仅是Qt开发啊的IDE环境,qt是指包含相关程序的开发库,两者是不同的。在使用Qt开发的过程中完全可以通过vi+命令行的方式搞定,一开始为了能更深入一些,我也是这样做的。但在之后的实际开发中,由于qt-creator提供语法高亮,快速定位源码等很好用的功能,推荐直接使用qt-creator这个集成开发环境。上面gcc链接的镜像是来自北交大,也可以自己选择镜像下载(我用的是学校的ftp)。
进入gcc解压包所在目录,
按上面的--prefix配置,gcc4.9.2会安装到
解压缩之后,进入Qt目录,
我第一次编译中途遇到一个error,提示没有gstream,我使用yum直接就更新了,
再接着
在
最后通过
因为下载的qtcreator是bin格式文件,因此直接在shell中运行,
安装过程同Windows下一样,提示安装目录,我保留默认的
在qt-creator中配置Qt路径
配置用于编译的gcc
这时就可以使用qt-creator新建Qt工程了。然而,我们下面的例子却不打算这么做。除非你是高手,否则我们应该使用命令行而非qt-creator来进行工程规划,qt-creator仅仅是为那些为了赶时间的设计师准备的!
这时我们可以写个小程序小小体验一把了,我们来写个程序实现:通过Qt弹出文件选择对话框,然后用OpenCV中的imread函数读取图片,最后通过Qt界面将图片显示出来。
其中的困难点在于Qt的图片数据类型QImage格式与OpenCV的Mat格式不一致,因此要实现转换,这通过下面的函数实现Mat到QImage的转换,打开文件对话框和显示图片的代码都在main函数中,下面是源代码:
关键是上面的代码直接在Qt中能编译吗?肯定不行,用脚趾头想想就知道,Qt怎么能找到
因此我们要在Qt中使用OpenCV,我们必需要将OpenCV头文件的路径和
opencv嵌入到Qt中
从上图知,我们在
使用Qt中的label显示lyc美图
整理一下上面编译Qt程序依次用到的命令(其实就3个),
这个例子的cpp源码及pro文件下载。
FROM: http://blog.csdn.net/xiahouzuoxin/article/details/41692891
安装Qt存在的一个普遍的问题是:低版本的gcc可能无法编译高版本的Qt。我参照了博客园中的一篇博客 ,搭配使用Qt4.8.6+QtCreator2.6.1+gcc4.9.2,这些软件的下载链接依次是:
qt-everywhere-opensource-src-4.8.6.tar.gz: http://download.qt-project.org/official_releases/qt/4.8/4.8.6/
qt-creator-linux-x86_64-opensource-2.6.1.bin: http://download.qt-project.org/official_releases/qtcreator/2.6/2.6.1/
gcc-4.9.2: http://mirror.bjtu.edu.cn/gnu/gcc/
根据自己的机器环境选择下载,我的环境是:CentOS 6.5 64bit。qt-creator仅仅是Qt开发啊的IDE环境,qt是指包含相关程序的开发库,两者是不同的。在使用Qt开发的过程中完全可以通过vi+命令行的方式搞定,一开始为了能更深入一些,我也是这样做的。但在之后的实际开发中,由于qt-creator提供语法高亮,快速定位源码等很好用的功能,推荐直接使用qt-creator这个集成开发环境。上面gcc链接的镜像是来自北交大,也可以自己选择镜像下载(我用的是学校的ftp)。
1. 更新gcc到4.9.2
进入gcc解压包所在目录,<code style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">mkdir gccout " 新建一个目录用于保存编译gcc生成的文件 cd gccout " 在gccout目录中运行所有命令 ../contrib/download_prerequisites " 安装一些依赖项 ../configure --prefix=/usr/local --mandir=/usr/local/share/man --enable-checking=release --enable-languages=c,c++,java --enalbe-java-awk=gtk --disable-multilib make -j4 " 编译,大约半个多小时吧,看机器性能了 make install " 安装,很快,几十秒</code>
按上面的--prefix配置,gcc4.9.2会安装到
/usr/local目录下,系统原来会有旧版本的gcc(要安装新版gcc必须要求系统中已经含有gcc,这样才能编译gcc源码),因此还要更新gcc到刚安装的4.9.2,则
<code style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">su root " 切换到root cd /usr/bin/ mv gcc gcc477 " 将旧版本的gcc软链接重命名,还可以通过gcc477使用旧版gcc mv g++ g++477 " 将旧版本的g++软链接重命名,还可以通过g++477使用旧版g++ ln -s /usr/local/bin/gcc gcc " 将gcc链接为gcc4.9.2 ln -s /usr/local/bin/g++ g++</code>
2. 编译安装Qt-4.8.6
解压缩之后,进入Qt目录,<code style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">./configure make " 编译时间很长,2个多小时吧 make install</code>
我第一次编译中途遇到一个error,提示没有gstream,我使用yum直接就更新了,
<code style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">yum install gstream*</code>
再接着
make就成功了。接着要使用Qt还要配置Qt所在的路径(即环境变量),
<code style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">cd /etc/profile.d/ " 这个目录中各种环境变量 vi qt4.sh " 新建一个环境变量配置文件</code>
在
qt4.sh中添加如下的信息,当然,Qt默认安装目录是在
/usr/local/Trolltech/Qt-4.8.6,我没有改(改过的修改
QTDIR变量就好了),
[code]export QTDIR=/usr/local/Trolltech/Qt-4.8.6 export PATH=$QTDIR/bin:$PATH export MANPATH=$QTDIR/man:$MANPAT export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
最后通过
source /etc/profile使配置的环境变量生效就OK了。
3. 安装qt-creator-2.6.1
因为下载的qtcreator是bin格式文件,因此直接在shell中运行,<code style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">./qt-creator-linux-x86_64-opensource-2.6.1.bin</code>
安装过程同Windows下一样,提示安装目录,我保留默认的
opt/qtcreator。安装好后在CentOS的启动栏菜单中就能看Qt-creator了。但要让qt-creator配合Qt4.8.6使用,则还要再qt-creator中进行一些配置,执行qt-creator菜单栏
Tools->Option...,配置如下图:
在qt-creator中配置Qt路径
配置用于编译的gcc
这时就可以使用qt-creator新建Qt工程了。然而,我们下面的例子却不打算这么做。除非你是高手,否则我们应该使用命令行而非qt-creator来进行工程规划,qt-creator仅仅是为那些为了赶时间的设计师准备的!
4. Qt与OpenCV强强联合的牛刀小试
这时我们可以写个小程序小小体验一把了,我们来写个程序实现:通过Qt弹出文件选择对话框,然后用OpenCV中的imread函数读取图片,最后通过Qt界面将图片显示出来。其中的困难点在于Qt的图片数据类型QImage格式与OpenCV的Mat格式不一致,因此要实现转换,这通过下面的函数实现Mat到QImage的转换,打开文件对话框和显示图片的代码都在main函数中,下面是源代码:
<code class="sourceCode cpp" style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);"><span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">/*</span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> * FileName : main.cpp</span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> * Author : xiahouzuoxin @163.com</span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> * Version : v1.0</span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> * Date : Sun 23 Nov 2014 04:29:47 PM CST</span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> * Brief : </span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> * </span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> * Copyright (C) MICL,USTB</span> <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;"> */</span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QApplication></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QWidget></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QImage></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QLabel></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QPushButton></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QHBoxLayout></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QVBoxLayout></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <QFileDialog></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <cv.h></span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">#include <highgui.h></span> <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">using</span> <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">namespace</span> cv; <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">static</span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage</span> Mat2QImage(Mat& image) { <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage</span> img; <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">if</span> (image.channels()==<span class="dv" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">3</span>) { cvtColor(image, image, CV_BGR2RGB); img = <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage</span>((<span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">const</span> <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">unsigned</span> <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">char</span> *)(image.data), image.cols, image.rows, image.cols*image.channels(), <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage::</span>Format_RGB888); } <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">else</span> <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">if</span> (image.channels()==<span class="dv" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>) { img = <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage</span>((<span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">const</span> <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">unsigned</span> <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">char</span> *)(image.data), image.cols, image.rows, image.cols*image.channels(), <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage::</span>Format_ARGB32); } <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">else</span> { img = <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage</span>((<span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">const</span> <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">unsigned</span> <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">char</span> *)(image.data), image.cols, image.rows, image.cols*image.channels(), <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage::</span>Format_RGB888); } <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">return</span> img; } <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">int</span> main(<span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">int</span> argc, <span class="dt" style="margin: 0px; padding: 0px; color: rgb(144, 32, 0);">char</span> *argv[]) { <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QApplication</span> app(argc, argv); <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QWidget</span> *wn = <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">new</span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QWidget</span>; wn->setWindowTitle(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"disp image"</span>); <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QString</span> filename = <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QFileDialog::</span>getOpenFileName(<span class="dv" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">0</span>, <span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"Open File"</span>, <span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">""</span>, <span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"*.jpg *.png *.bmp"</span>, <span class="dv" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">0</span>); <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">if</span> (filename.isNull()) { <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">return</span> <span class="dv" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">-1</span>; } Mat image = imread(filename.toAscii().data(), <span class="dv" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>); <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QImage</span> img = Mat2QImage(image); <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QLabel</span> *label = <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">new</span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QLabel</span>(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">""</span>, <span class="dv" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">0</span>); label->setPixmap(<span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QPixmap::</span>fromImage(img)); <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QPushButton</span> *bnt = <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">new</span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QPushButton</span>(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">"Quit"</span>); <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QObject::</span>connect(bnt, <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">SIGNAL</span>(clicked()), &app, <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">SLOT</span>(quit())); <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QVBoxLayout</span> *layout = <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">new</span> <span class="ot" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32);">QVBoxLayout</span>; layout->addWidget(label); layout->addWidget(bnt); wn->setLayout(layout); wn->show(); <span class="kw" style="margin: 0px; padding: 0px; color: rgb(0, 112, 32); font-weight: bold;">return</span> app.exec(); }</code>
关键是上面的代码直接在Qt中能编译吗?肯定不行,用脚趾头想想就知道,Qt怎么能找到
cv.h这些头文件呢,又怎么能找到
imread这些OpenCV中的函数呢!
因此我们要在Qt中使用OpenCV,我们必需要将OpenCV头文件的路径和
imread函数的库和库路径告知Qt,如果你一直像我一样使用的是Makefile来编译OpenCV工程,那将OpenCV集成到Qt中的那真是小菜一碟了。我们先用
qmake -project命令生成
pro文件,
.pro文件在Qt工程中起重要作用。要在Qt中使用OpenCV,我们只要修改
pro文件就好了,
opencv嵌入到Qt中
从上图知,我们在
pro文件的
INCLUDEPATH变量中添加了OpenCV头文件所在路径,在
LIBS变量中添加了库所在路径及所使用的库(-L指定库路径,-llib指定程序中用到的lib库)。修改完
pro文件保存后,这个时候再使用
qmake命令编译,就可以生成Makefile文件,执行
make就得到可执行文件了。我们不妨看看执行显示图片的结果。
使用Qt中的label显示lyc美图
整理一下上面编译Qt程序依次用到的命令(其实就3个),
<code style="margin: 0px; padding: 0.5em; font-stretch: normal; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background: rgb(248, 248, 255);">qmake -project " 生成pro文件,修改后执行下面的命令 qmake " 生成Makefile文件 make " gcc编译生成目标可执行文件,可执行文件名默认为当前目录名</code>
这个例子的cpp源码及pro文件下载。
FROM: http://blog.csdn.net/xiahouzuoxin/article/details/41692891
相关文章推荐
- Halcon C++混合编程学习之Qt 实现检测焊接点
- [OpenCV] -- win7下配置OpenCV的Qt开发环境
- qt 上下页布局与代码规范
- QT中event事件机制与signal关系
- 性能分析工具AQTime
- qt 声音
- 什么是Qt的代理QItemDelegate_Spin Box Delegate Example例子分析
- ubuntu安装Qt5
- Qt之自定义界面(实现无边框、可移动)
- Qt之自定义界面(实现无边框、可移动)
- QTP中action使用,包括多action复用(转)
- QT 的点点滴滴之容器
- Qt学习2
- (Qt学习1)Qt环境搭建
- Qt学习之路(4):初探信号槽
- qt俄罗斯方块 可以使用 (一)
- qt QString用法
- MQTT协议简记
- Qt——树结点的搜索
- QT安装包制作