您的位置:首页 > 编程语言 > Qt开发

Qt Opencv 在Linux下摄像头简单示例v1.0

2013-10-09 20:35 239 查看
下面写的文章也许网上也有类似的,但是大多数都没有给出思路及背景,让初学者每次都只能学到一点皮毛,不少知识需要大量搜索零碎地拼凑起来。题外话,虽然现在是碎片化信息时代,但正是这样信息整合能力也显得非常重要,为读者提供高质量的文章是我以后的目标。我以后会注意分析应用背景及些过程的解析。

不想看下面笔者对编译环境的理解的,可以直接在本页Ctrl+F查找“编译过程”看,因为下面有很大段笔者心酸的回忆,嘻嘻。

资源介绍

opencv是一个非常优秀的图形图像处理类库,里面的类或者结构体,封装了很多实用的图像处理算法,调用其提供的API,等于使用一些复杂的图像处理算法,真是解放生产力啊。这里笔者用的是linux版本的opencv2.2源码,几十M,稳定版本够用即可,没必要时刻追着新版本。不过在linux上的opencv各种版本都是如笔者那样编译即可用。

思考一下,为什么我们要下源码来编译?不是像windows上的直接发布一个压缩包即可用么?我们这次编译为是得到什么?其实很简单,opencv里有专门处理摄像头的API,我们要用它,就得有它的头文件及动态库(或静态库)。而我们拿到源码往往不是为了去研究其代码(如果是做这算法方面的研究便是例外了),而是拿到“本地”编译。至于为何,笔者认为是大家内核版本版本的不统一,编译器版本也不统一导致这样做的的。如果使用Ubuntu之类的,很简单,一个apt-get什么都不用管,因为Ubuntu提供了适应你的内核版本编译器编译的库。知道的同学希望指教一下。

下载请移步:http://www.opencv.org.cn/index.php/Download

虚拟机上的摄像头,一般都是用USB连接,如果是笔记本自带的,也是把虚拟机里的connect上即可。连接外设的方法:在虚拟机顶栏菜单,VM->Removable Devices->XX WebCam->connect && show in status Bar(前者把设备从win环境解除,连接到虚拟机环境,后者是显示在虚拟机右下角的状态栏)。

具体看下图:

QT,版本其实与opencv版本没有什么关系,因为代码编译出来,最终都是翻译成机器码,QT源码是C++写的,OPENCV源码也是C/C++写的,编译器认识他们即可。笔者一起也是担心版本问题,网上的文章往往都是写着qt4.7.2+opencv2.0XXX,或者qtcreator2.0+opencv2.3.1在Ubuntu11上编译成功之类的文章,我那时就很担心,又要确定QT版本,又要确定opencv版本,还得确定linux版本吗?linux怎么那么复杂啊?就是他们的标题及其内容都没有明确指出他们方法的通用性。笔者在这里就说明一下:这文章在linux上的适用,QT版本(4.6,4.7,5.0等无论什么版本都可以,whatever),opencv版本(1.0,2.0,2.2,2.3,2.4,whatever都可以),linux(各种发行版本(内核是2.6以上的),只要别用2.4的内核就好。)

编译过程:

摄像头在虚拟机上(当然,从物理上说你还是得有摄像头才行)安装上面的图看一下即可。下面主要是opencv的编译:主要参考opencv中文论坛的文章

./configure //头文件和库文件一般都是默认安装到/usr/local/include /usr/local/lib内

make

make install

具体代码:

先讲最终要实现什么,很简单,一个窗口,里面有一个label显示摄像头的图像。

然后讲讲原理:每隔一段时间我们就去摄像头抓取一帧图像,然后放到ui->label上面,如果取的时间快,就造成“视频”的感觉了。(可以想到,其实摄像头拍照也是很简单,我们就把其中一帧取出来即可。)

新建一个工程,继承QDialog(用什么窗体都可以),在UI上拖出一个label放在中间,

拉到适当大小。

在工程xxx.pro里面添加必要的库及头文件的路径:

INCLUDEPATH += /usr/local/include/opencv

LIBS += /usr/local/lib/libcv.so \

/usr/local/lib/libhighgui.so \

/usr/local/lib/libcxcore.so \

dialog.h

#ifndef DIALOG_H

#define DIALOG_H

#include <QDialog>

#include <cv.h>

#include <highgui.h>

#include <QTimer>

#include <QPixmap>

namespace Ui {

class Dialog;

}

class Dialog : public QDialog

{

Q_OBJECT

public:

explicit Dialog(QWidget *parent = 0);

~Dialog();

private:

Ui::Dialog *ui;

CvCapture *capture; //highgui
里提供的一个专门处理摄像头图像的结构体

IplImage *frame; //摄像头每次抓取的图像为一帧,使用该指针指向一帧图像的内存空间

QTimer *timer; //定时器用于定时取帧,上面说的隔一段时间就去取就是用这个实现。

private slots:

void getFrame(); //实现定时从摄像头取图并显示在label上的功能。

};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"

#include "ui_dialog.h"

#include <QDebug>

Dialog::Dialog(QWidget *parent) :

QDialog(parent),

ui(new Ui::Dialog)

{

ui->setupUi(this);

timer = new QTimer(this);

capture = cvCaptureFromCAM(0); //cvCaptureFromCAM其实是一个宏,就是cvCreateCameraCapture的别名,0代表第一个摄像头。-1代表默认摄像头。

if(capture==NULL){

qDebug()<<"error!";

}

timer->start(50); //1000为1秒,50毫秒去取一帧

connect(timer,SIGNAL(timeout()),this,SLOT(getFrame())); //超时就去取

}

void Dialog::getFrame()

{

frame = cvQueryFrame(capture); //从摄像头取帧

QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped(); //简单地转换一下为Image对象,rgbSwapped是为了显示效果色彩好一些。

ui->label->setPixmap(QPixmap::fromImage(image));

}

Dialog::~Dialog()

{

timer->stop(); //停止取帧

cvReleaseCapture(&capture); //释放资源是个好习惯

delete ui;

}

本文参考资料:

源码编译:

http://www.opencv.org.cn/index.php/%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91

QT中使用OPENCV库

http://www.opencv.org.cn/index.php/%E5%9C%A8Qt%E4%B8%AD%E4%BD%BF%E7%94%A8OpenCV%E5%BA%93

Debian/Ubuntu

http://www.opencv.org.cn/index.php/Debian%E4%B8%8B%E5%AE%89%E8%A3%85

欢迎技术交流,邮箱noiplee@gmail.com

这是noiplee的技术博客,我写博客的目的是想通过快速分享来达到掌握知识的目的,同时希望和各位网友交流共同进步。我经常关注linux,嵌入式,读书,思维导图,冥想等领域。如果您看了我的文章有任何的建议或者观点,非常欢迎留言和评论,有任何问题我们都可以一起探讨,我会及时回复的。

文章网址:http://blog.chinaunix.net/uid-24641004-id-3459705.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: