(1):详解QT多媒体框架:给予视频播放器

原文链接:http://mobile.51cto.com/symbian-271123.htm

对于使用主框架的QT程序,实现Qimage的转换可借鉴下面程序段:

void MainWindow::on_openButton_clicked()
{//第3个参数表示查找文件时从哪个目录开始,如果为"."的话,表示从该工程目录开始查找,最后那个参数的过滤器的名字之间//要用空格,否则识别不出来QString img_name = QFileDialog::getOpenFileName( this, tr("Open Image"), ".",tr("Image Files(*.png *.jpg *.jpeg *.bmp)"));//toAscii()返回8位描述的string,为QByteArray,data()表示返回QByteArray的指针,QByteArray为字节指针Mat src = imread( img_name.toAscii().data() );cvtColor( src, src, CV_BGR2RGB );QImage img = QImage( (const unsigned char*)(src.data), src.cols, src.rows, QImage::Format_RGB888 );
//    namedWindow( "Image_Show", WINDOW_AUTOSIZE );
//    imshow( "Image_Show", src );ui->label->setPixmap( QPixmap::fromImage(img) );//   ui->label->resize( ui->label->pixmap()->size() );}

(2):详解QT 快速应用OPENCV ,图片示例:基于widget!!!

原文链接:http://mobile.51cto.com/symbian-271260.htm

QT 框架中快速应用OpenCV 是本文要结束的内容,和MFC比较起来,QT的信号槽机制比MFC的信号机制慢,但是因为能很好的实现跨平台,所以我在这里总结一下可能对一些人有点用。OpenCV.China论坛上有一个帖子叫做《在MFC框架中快速应用OpenCV》看了后就想结合QT写一下。

0搭建环境:OpenCV + QT 4.6

我的实验是基于VS2008来做的,QT官方虽然提供了VS2008-add-in的插件,我没有用。直接下载器编译好的库文件进行配置,OpenCV的在VS2008下面的配置方法Google一下到处都是,这里不再补充。首先需要做的是在VS2008里面你需要使QT下和OpenCV的程序能分别跑起来。对于QT在VS的配置其实挺简单,有头文件和相应的链接库,保证调用的时候路径正确,一般就没有问题了。常用命令行make程序的人应该会很清楚那些IDE只不过是层画皮。

.pro配置:

[cpp] view plaincopy
INCLUDEPATH += d:\opencv\build\include\
INCLUDEPATH += d:\opencv\build\include\opencv\
INCLUDEPATH += d:\opencv\build\include\opencv2\  CONFIG(debug,debug|release) {
LIBS += -Ld:\opencv\build\x86\vc10\lib \  -lopencv_core243d \  -lopencv_highgui243d \  -lopencv_imgproc243d \  -lopencv_features2d243d \  -lopencv_calib3d243d
} else {
LIBS += -Ld:\opencv\build\x86\vc10\lib \  -lopencv_core243 \  -lopencv_highgui243 \  -lopencv_imgproc243 \  -lopencv_features2d243 \  -lopencv_calib3d243
}  

1.显示图像

QWidget是QObject下的第一个子类,使用它显示图像会减少不必要的开销。首先定制一个自己需要的QWidget:

  1. class myWidget : public QWidget
  2. {
  3. Q_OBJECT
  4. public:
  5. myWidget(const IplImage *img,QWidget *parent = 0);
  6. ~myWidget();
  7. protected:
  8. void paintEvent(QPaintEvent *e);
  9. private:
  10. IplImage* iplImg;
  11. QImage *qImg;
  12. };

需要绘制一个图像,我重载paintEvent(QpaintEvent *e),我在这里面使用QPainter进行绘制。

  1. void myWidget::paintEvent(QPaintEvent *e)
  2. {
  3. QPainter painter(this);
  4. painter.drawImage(QPoint(5,5),*qImg);
  5. }

rawImage(QPoint(5,5),qImg);的作用是将qImg绘制在左上顶点位于QPoint(5,5)处。

这里面有可能两个问题,第一个问题是要显示的图片太小,创建的Widget太大,最后显示比较丑陋。这时可以在此函数里面获得qImg的宽高,然后resize一下就好了。另外一个问题是:绘制的时候使用的是QImage,不是IplImage类型。关于这个问题论坛上有人专门写了IplImage <-> QImage的转换代码,我在这里不重复那个做法,一是有人已经做了,另外处于效率考虑,这里提供另一种方法。

通常同学们都是用cvLoadImage来读图片,保存在IplImage里面,在这里这个图片我们保存在img里面,然后通过img传进QWidget,然后我new一个QImage

  1. qImg = new QImage(QSize(img->width,img->height),QImage::Format_RGB888);

我这里假设iplImg是RGB格式,且每个通道大小为8。然后创建一个IplImage 的文件头

  1. iplImg = cvCreateImageHeader(cvSize(img.width(),img.height()),8,3);

此iplImage和QImage的不同之处在于QImage没有直接提供创建文件头的方法,可以通过如下方式创建只有文件头数据的QImage

  1. qImg = new QImage(QSize(0,0),QImage::Format_RGB888);

另外两者的图像矩阵像素排列有点不同,比如IplImage中的BGR到了QImage中应该是RGB,当然单通道的灰度图是一样的,值得庆幸的是两者的像素矩阵都是形状相同的多维数组。这样我们可以通过指针共享这部分数据,一种方法如下:

  1. iplImg->imageData = (char*)qImg.bits();

将iplImg的图像矩阵指到qImg那里,以后我们只需要对IplImage运用opencv里面的函数进行处理,其实就直接在处理qImg里面的数据了。但是现在的图像数据还在img里面,首先得把数据搞到手,然后放到iplImg和qImg的共享区中去,另外将颜色排列以QImage中的RGB顺序为标准。

  1. if (img->origin == IPL_ORIGIN_TL)
  2. {
  3. cvCopy(img,iplImg,0);
  4. }
  5. else
  6. {
  7. cvFlip(img,iplImg,0);
  8. }
  9. cvCvtColor(iplImg,iplImg,CV_BGR2RGB);

实际上只要做到这里图片就能显示了。如下图所示

给出myWidget.cpp完整代码

  1. #include "myWidget.h"
  2. #include <QtGui\QPainter>
  3. #include <QtCore\QPoint>
  4. myWidget::myWidget(const IplImage *img,QWidget *parent /* = 0 */) : QWidget(parent)
  5. {
  6. qImg = new QImage(QSize(img->width,img->height),
  7. QImage::Format_RGB888);
  8. iplImg = cvCreateImageHeader(cvSize(img->width,img->height),
  9. 8,3);
  10. iplImg->imageData = (char*)qImg->bits();
  11. if (img->origin == IPL_ORIGIN_TL)
  12. {
  13. cvCopy(img,iplImg,0);
  14. }
  15. else
  16. {
  17. cvFlip(img,iplImg,0);
  18. }
  19. cvCvtColor(iplImg,iplImg,CV_BGR2RGB);
  20. this->resize(img->width,img->height);
  21. }
  22. myWidget::~myWidget()
  23. {
  24. cvReleaseImage(&iplImg);
  25. delete qImg;
  26. }
  27. void myWidget::paintEvent(QPaintEvent *e)
  28. {
  29. QPainter painter(this);
  30. painter.drawImage(QPoint(0,0),*qImg);
  31. }

调用的代码很简单:

  1. int main(int argc,char* argv[])
  2. {
  3. QApplication app(argc,argv);
  4. IplImage *img = cvLoadImage("460.jpg",1);
  5. if (img)
  6. {
  7. myWidget *mw = new myWidget(img);
  8. mw->show();
  9. }
  10. int re = app.exec();
  11. cvReleaseImage(&img);
  12. return re;
  13. }

小结:关于详解 QT 框架中快速应用OpenCV 上篇内容介绍完了

(3):利用Qt与OpenCV简单实现摄像头图像捕捉

原文链接:http://blog.const.net.cn/a/8763.htm

为了pro工程文件看起来简单点,创建一个pri文件,包含opencv相关信息。分别为VS2008、Mingw和Linux设置OpenCV头文件和库的路径。OPENCVPATH_MSVC=D:/Qt/OpenCV-2.1....

为了pro工程文件看起来简单点,创建一个 pri 文件,包含 opencv相关信息。

分别为 VS2008、Mingw和Linux设置OpenCV头文件和库的路径。

OPENCVPATH_MSVC = D:/Qt/OpenCV-2.1.0-vs2008win32-msvc*{INCLUDEPATH += $${OPENCVPATH_MSVC}/includeCONFIG(debug, debug|release) {LIBS+=-L$${OPENCVPATH_MSVC}/lib/debug -lcxcore210d -lhighgui210d} else {LIBS += -L$${OPENCVPATH_MSVC}/lib/release -lcxcore210 -lhighgui210}
}OPENCVPATH_MINGW = D:/Qt/OpenCV-2.1.0-mingw
win32-g++{INCLUDEPATH += $${OPENCVPATH_MINGW}/includeLIBS += -L$${OPENCVPATH_MINGW}/lib -lcxcore210 -lhighgui210
}unix:LIBS += -lcv -lhighgui

读取类

创建一个视频捕捉类,提供start和stop槽来控制摄像头打开和关闭,通过定时器定时捕捉图像,并通过信号将图片传出。

//cameradevice.h
#ifndef CAMERADEVICE_H
#define CAMERADEVICE_H#include <QtCore/QObject>QT_BEGIN_NAMESPACE
class QTimer;
class QImage;
QT_END_NAMESPACEnamespace cv{    class VideoCapture;
    class Mat;
}class CameraDevice : public QObject
{    Q_OBJECT
public:
    explicit CameraDevice(QObject *parent = 0);
    ~CameraDevice();signals:
    void imageReady(const QImage& image);public slots:
    bool start();
    bool stop();private slots:
    void onTimeout();private:
    QImage imageFromMat(const cv::Mat& frame);
    cv::VideoCapture * m_capture;
    QTimer * m_timer;
};#endif // CAMERADEVICE_H
//cameradevice.cpp
#include <QtCore/QTimer>
#include <QtGui/QImage>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "cameradevice.h"CameraDevice::CameraDevice(QObject *parent) :
    QObject(parent)
{    m_capture = new cv::VideoCapture;
    m_timer = new QTimer(this);    connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
}CameraDevice::~CameraDevice()
{    delete m_capture;
    m_capture = NULL;
}bool CameraDevice::start()
{    if (m_capture->isOpened()) {        return true;
    }
    m_capture->open(CV_CAP_ANY);
    if (m_capture->isOpened()) {        m_timer->start(40);
    }
    return m_capture->isOpened();
}bool CameraDevice::stop()
{    if (m_capture->isOpened()) {        m_capture->release();
    }
    return true;
}void CameraDevice::onTimeout()
{    if (!m_capture->isOpened()) {        return;
    }
    static cv::Mat frame;
    *m_capture >> frame;
    if (frame.cols) {        emit imageReady(imageFromMat(frame));
    }
}QImage CameraDevice::imageFromMat(const cv::Mat &frame)
{    const unsigned char* src = frame.ptr();
    QImage image(frame.cols, frame.rows, QImage::Format_RGB32);
    unsigned char * des = image.bits();
    unsigned long count = frame.cols * frame.rows;
    for (unsigned long i = 0; i < count; ++i)
    {        *des++ = *src++;
        *des++ = *src++;
        *des++ = *src++;
        *des++ = 0xff;
    }
    return image;
}

界面类

对话框类就简单了,只需要一个 label 来显示图像,两个按钮来控制开启与关闭即可

//dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QtGui/QDialog>namespace Ui {    class Dialog;
}class CameraDevice;class Dialog : public QDialog
{    Q_OBJECTpublic:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();private slots:
    void onImageArrival(const QImage & image);private:
    Ui::Dialog *ui;
    CameraDevice * m_camera;
};#endif // DIALOG_H[喝小酒的网摘]http://blog.const.net.cn/a/8763.htm
//dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include "cameradevice.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog),
    m_camera(new CameraDevice(this))
{    ui->setupUi(this);    connect(m_camera, SIGNAL(imageReady(QImage)), this, SLOT(onImageArrival(QImage)));
    connect(ui->startButton, SIGNAL(clicked()), m_camera, SLOT(start()));
    connect(ui->stopButton, SIGNAL(clicked()), m_camera, SLOT(stop()));
}Dialog::~Dialog()
{    delete ui;
}void Dialog::onImageArrival(const QImage &image)
{    ui->view->setPixmap(QPixmap::fromImage(image));
}

主程序

//main.cpp
#include <QtGui/QApplication>
#include "dialog.h"int main(int argc, char *argv[])
{    QApplication a(argc, argv);
    Dialog w;
    w.show();    return a.exec();
}

问题

用一个定时器来做似乎存在些问题,反复打开关闭,在windows下可发现资源泄漏。不清楚是什么原因。

简单调整几行代码,改为多线程程序后,该问题似乎消失了。

  • 改动主要在对话框类中:
#include <QtCore/QThread>
#include "dialog.h"
#include "ui_dialog.h"
#include "cameradevice.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog),
    m_camera(new CameraDevice)
{    ui->setupUi(this);    QThread * thread = new QThread(this);
    m_camera->moveToThread(thread);
    thread->start();    connect(m_camera, SIGNAL(imageReady(QImage)), this, SLOT(onImageArrival(QImage)));
    connect(ui->startButton, SIGNAL(clicked()), m_camera, SLOT(start()));
    connect(ui->stopButton, SIGNAL(clicked()), m_camera, SLOT(stop()));
}Dialog::~Dialog()
{    m_camera->deleteLater();
    delete ui;
}void Dialog::onImageArrival(const QImage &image)
{    ui->view->setPixmap(QPixmap::fromImage(image));
}

改为多线程后,可将捕捉类中的定时器的时间设为 0

(4):QThread的使用方法

昨天不小心看到Qt开发人员( Bradley T. Hughes)Blog中的一片文章 you are-doing-it-wrong 。 结果看得头昏脑胀:好歹也自学了近1年的Qt,也一直很小心、很认真地阅读Qt和manual和例子等资料,却被突然告知,QThread的正确使用方法 是一种自己从没见过,而且Qt manual、example、书籍中都没有提到过的一种方法。到底怎么了... [喝小酒的网摘]http://blog.const.net.cn/a/8760.htm

莫非manual、exmaple以及资料中的介绍都是错的??

认真看看其他的人的评论,总算理清了一点头绪。所有事情源于 QThread 的事件循环!

QThread 的两种使用方法

1. 不使用事件循环。这是官方的 Manual 、example 以及相关书籍中都介绍的一种的方法。
a. 子类化 QThread
b. 重载 run 函数,run函数内有一个 while 或 for 的死循环
c. 设置一个标记为来控制死循环的退出。

2. 使用事件循环。(博客 you are-doing-it-wrong 批驳的就是这种情况下的 一种用法。)

a. 子类化 QThread,
b. 重载 run 使其调用 QThread::exec() 
c. 并为该类定义信号和槽,这样一来,由于槽函数并不会在新开的 thread 运行,很多人为了解决这个问题在构造函数中调用 moveToThread(this);

而争论和不解正是这样的一条语句造成的。

Bradley T. Hughes 给出说明是: QThread 应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个QObject的子类中,然后将该子类的对象moveToThread到新线程中。

另外:
在Qt4.3(包括)之前,run 是虚函数,必须子类化QThread来实现run函数。
而从Qt4.4开始,qthreads-no-longer-abstract    ,run 默认调用 QThread::exec() 。这样一来不需要子类化 QThread 了,只需要子类化一个 QObject 就够了,这正是被 Bradley T. Hughes推荐的方法。

终于看懂了,但
不管怎么说,都应该是 QThread 当初的设计导致的这种问题,而所有文档和例子中都没有提到该如何使用Qthread 进一步加剧了对QThread的这种误用。

相关链接:

http://labs.qt.nokia.com/blogs/2010/06/17/youre-doing-it-wrong/
http://labs.qt.nokia.com/blogs/2006/12/04/threading-without-the-headache/
http://labs.qt.nokia.com/blogs/2007/07/05/qthreads-no-longer-abstract/
http://gitorious.org/qthreadhowto/qthreadhowto/trees/master
http://blog.exys.org/entries/2010/QThread_affinity.html
http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/[喝小酒的网摘]http://blog.const.net.cn/a/8760.htm

(5):使用opencv和QT实现摄像头采集

在网上收罗了很多资料,QT没有专门操作摄像头的类,这个得自己写。网上也有很多关务openCV和V4l的一些介绍,由于我项目要在window下开发,所以就选择了openCV。由于以前没有用过openCV,所以就只看了关于openCVS摄像头操作的这部分,其他的还没时间去看。

openCV : http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.1/

刚开始下载的是2.3.1的,安装后发现没有lib库所以后面选择了2.1的

openCV中文学习 pdf  :

现在,开始详细的介绍如何在QT中实时的采集摄像头数据。

打开QTcreator (我用的是QT 2.3的 中文版)

新建一个widget工程

在界面上放两个label 分别用来显示摄像头采集到的数据和照的照片。

编辑camaraget.h 文件

[cpp] view plaincopy?
    #ifndef CAMARAGET_H   #define CAMARAGET_H   #include <QWidget>   #include <QImage>   #include <QTimer>     // 设置采集数据的间隔时间   #include <highgui.h>  //包含opencv库头文件   #include <cv.h>   namespace Ui {  class camaraGet;  }  class camaraGet : public QWidget  {  Q_OBJECT  public:  explicit camaraGet(QWidget *parent = 0);  ~camaraGet();  private slots:  void openCamara();      // 打开摄像头   void readFarme();       // 读取当前帧信息   void closeCamara();     // 关闭摄像头。   void takingPictures();  // 拍照   private:  Ui::camaraGet *ui;  QTimer    *timer;  QImage    *imag;  CvCapture *cam;// 视频获取结构, 用来作为视频获取函数的一个参数   IplImage  *frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像   };  #endif // CAMARAGET_H  

编辑 camaraget .cpp

[cpp] view plaincopy?
    #include "camaraget.h"   #include "ui_camaraget.h"   camaraGet::camaraGet(QWidget *parent) :  QWidget(parent),  ui(new Ui::camaraGet)  {  ui->setupUi(this);  cam     = NULL;  timer   = new QTimer(this);  imag    = new QImage();         // 初始化   /*信号和槽*/  connect(timer, SIGNAL(timeout()), this, SLOT(readFarme()));  // 时间到,读取当前摄像头信息   connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara()));  connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures()));  connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));  }  /****************************** ********* 打开摄像头 *********** *******************************/  void camaraGet::openCamara()  {  cam = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频   timer->start(33);              // 开始计时,超时则发出timeout()信号   }  /********************************* ********* 读取摄像头信息 *********** **********************************/  void camaraGet::readFarme()  {  frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧   // 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不同的摄像头用不同的格式。   QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);  ui->label->setPixmap(QPixmap::fromImage(image));  // 将图片显示到label上   }  /************************* ********* 拍照 *********** **************************/  void camaraGet::takingPictures()  {  frame = cvQueryFrame(cam);// 从摄像头中抓取并返回每一帧   // 将抓取到的帧,转换为QImage格式。QImage::Format_RGB888不同的摄像头用不同的格式。   QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);  ui->label_2->setPixmap(QPixmap::fromImage(image));  // 将图片显示到label上   }  /******************************* ***关闭摄像头,释放资源,必须释放*** ********************************/  void camaraGet::closeCamara()  {  timer->stop();         // 停止读取数据。   cvReleaseCapture(&cam);//释放内存;   }  camaraGet::~camaraGet()  {  delete ui;  }  

好了,全部代码都OK了(当然,创建工程时,会生成main.cpp,不必去改动它),但现在你点运行,依然会产生错误,为什么呢?因为还没有把openCV的库包含进去。

在*.pro 文件中 加入:

INCLUDEPATH+=C:\OpenCV2.1\include\opencv

   LIBS += C:\OpenCV2.1\lib\highgui210.lib \
    C:\OpenCV2.1\lib\cxcore210.lib \
    C:\OpenCV2.1\lib\cv210.lib

OK,大功告成,运行后,在widget中点击打开摄像头,就可以看到自己了。运行后的效果:

后来我发现这个效果不怎么好,就改了一下:改了以后的运行效果也贴出来:

就改了一句:

[cpp] view plaincopy?
  1. QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888);
[cpp] view plaincopy?
  1. 改为了 QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();

(6):求道勿远,求心勿近 的一个博客:Qt Opencv 在Linux下摄像头简单示例v1.0

原文链接:http://blog.chinaunix.net/uid-24641004-id-3459705.html

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

不想看下面笔者对编译环境的理解的,可以直接在本页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中文论坛的文章

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

具体代码:

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

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

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

拉到适当大小。

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

 INCLUDEPATH +=/usr/local/include/opencvLIBS +=/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_OBJECTpublic: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

QT与openCV,与PCL结合!相关推荐

  1. 在Qt调用OpenCV库编写GUI程序

    写在前面 OpenCV本身自带的HighGUI库就可以完成一部分GUI设计编写工作,无奈其中控件实在太少,除了按钮就是滚动条,OpenCV中文站上曾经给出了OpenCV和MFC的搭配调用,但是Open ...

  2. Qt与OpenCV编程:在QLabel加载的图像上画矩形并剪切

    前言 1.使用Qt与OpenCV做开发时,时常会用到鼠标与图像交互这块,OpenCV有自己的鼠标事件,但要在Qt搭建的界面上是不能使用OpenCV封装的鼠标事件,Qt有自己的鼠标事件. 2.Qt鼠标事 ...

  3. Qt:OpenCV—Q图像处理基本操作(Code)

    原文链接:http://www.cnblogs.com/emouse/archive/2013/03/31/2991333.html 作者写作一系列:http://www.cnblogs.com/em ...

  4. qt调用opencv汇总(2)

    OpenCV3.4.3+Qt5.9.4(QtCreator)开发环境搭建 之前有过对OpenCV3.4.2+VS2015编译及环境搭建,今天使用OpenCV3.4.3+QtCreator5.9.4编译 ...

  5. Qt调用OpenCV汇总(1)

    //************************************************************************************************** ...

  6. linux上qt配置opengl,Ubuntu下配置Qt+OpenGL+OpenCV

    我的平台:Ubuntu 10.04+Qt+OpenGL+OpenCV OpenGL是Qt自带的,Windows下的版本OpenGL库已经随同Qt的Windows发行版一同安装,Linux版本则没有安装 ...

  7. windows平台下基于QT和OpenCV搭建图像处理平台

        在之前的博客中,已经分别比较详细地阐述了"windows平台下基于VS和OpenCV"以及"Linux平台下基于QT和OpenCV"搭建图像处理框架,并 ...

  8. Qt + Python + OpenCV图标替换工具 之 Qt界面设计(四)

    目录 上一篇博文 程序的下载地址以及源码 Qt界面设计 上一篇博文 Qt + Python + OpenCV图标替换工具 之 Python调用dll(三) https://blog.csdn.net/ ...

  9. Qt + Python + OpenCV图标替换工具 之 Python调用dll(三)

    目录 上一篇博文 程序的下载地址以及源码 Python调用dll 上一篇博文 Qt + Python + OpenCV图标替换工具 之 获取颜色及生成图片(二) https://blog.csdn.n ...

最新文章

  1. 按次计费接口的简单实现思路
  2. Python零碎知识(7):硬性出错
  3. 获取成员函数地址及获取函数地址
  4. 【搜索树】高级打字机(luogu 1383)
  5. c语言死循环中输入字符,如下代码,如果输入字符,为什么会造成死循环?
  6. 二十八条改善ASP性能和外观的技巧(三)
  7. 剑指offer:剪绳子(找规律,贪心算法,动态规划)
  8. nrpe的安装和配置(转)
  9. FreeMarker合并单元格
  10. 5个月自学,零基础至日语2级全攻略
  11. 设计模式-头脑风暴-速记
  12. 如何建立开发环境可以让开发人员快捷开发出模型的原型
  13. perl语言linux培训,一文了解Perl语言
  14. 机器学习(聚类六)——层次聚类
  15. mysql连接失败问题
  16. windows自带截图工具快捷方法
  17. 计算机网络统考outlook操作视频,网络教育计算机统考Outlook
  18. Python实现的图书分析大屏展示系统(附源码)
  19. 《C专家编程》学习笔记
  20. Sallen-Key二阶低通滤波器——设计问题浅析

热门文章

  1. 跨库多维分析后台的实现
  2. [日常] DNS的迭代查询过程
  3. SQL Server 2008 修改安装路径后安装出错的解决方法
  4. 自己实现简单的AOP(三) 实现增强四项基本功能
  5. Eclipse helios 上编写arduino程序并进行烧录
  6. Docker实现运行tomcat并部署项目war包,并实现挂载目录
  7. 第13章 C#中的多线程
  8. Microsoft SQL Server 存储过程
  9. 2019.04.06 电商04 模板嵌套
  10. 第六周---事后分析