OpenCV 轻量级而且高效,由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
QT 框架中快速应用OpenCV 基于视频播放是本篇介绍的内容,接着上篇文章继续介绍,详解 QT 框架中快速应用OpenCV 基于图片上篇,希望上篇文章对你有帮助,那么先来看本篇文章!
有些时候我们需要的是处理视频文件,比如AVI,当然也不过是图像序列。在由于QT运行时的多线程机制导致sleep函数不好使,可以通过其提供的QTimer来控制视频文件的播放。在给出例子之前要罗嗦两句QT的信号/槽机制。MFC里面的消息映射固然很快,但是让一个涉其未深的人阅读起来会觉得很晦涩,QT通过signal/slot机制实现了消息交换。用signal唤起slot,比如点击了button的clicked()事件是一个signal,当这个事件发生之后可以唤起其他的操作,只要你将clicked消息和那个实际操作的槽连接起来了。
OpenCV里面有函数可以方便的读取视频帧,如果使用Widget播放视频,如何控制帧率是一个很巧妙的地方,我使用一个QTimer控制时间(可以理解为帧率),并周期性的唤起读取视频帧的操作,然后在这个操作里面对widget进行重绘,或者模仿前面的方法,用一个QImage当作共享区域,让用来paintEvent用来显示。
有了上面显示图像的基础,我改一下上面的代码,给出一个例子:
- myWidget.h
- #ifndefMYWIDGET_H
- #defineMYWIDGET_H
- #include<QtGui\QWidget>
- #include<QtGui\QPaintEvent>
- #include<QtGui\QImage>
- #include<QtCore\QTimer>
- #include<cv.h>
- #include<highgui.h>
- classmyWidget:publicQWidget
- {
- Q_OBJECT
- public:
- myWidget(constchar*filename,QWidget*parent=0);
- ~myWidget();
- protected:
- voidpaintEvent(QPaintEvent*e);
- privateslots:
- voidnextFrame();
- private:
- CvCapture*capture;
- IplImage*iplImg;
- IplImage*frame;
- QImage*qImg;
- QTimer*timer;
- };
- #endif
- myWidget.cpp
- #include"myWidget.h"
- #include<QtGui\QPainter>
- #include<QtCore\QPoint>
- myWidget::myWidget(constchar*filename,QWidget*parent/*=0*/):QWidget(parent)
- {
- capture=cvCaptureFromFile(filename);
- if(capture)
- {
- frame=cvQueryFrame(capture);
- if(frame)
- this->resize(frame->width,frame->height);
- qImg=newQImage(QSize(frame->width,frame->height),
- QImage::Format_RGB888);
- iplImg=cvCreateImageHeader(cvSize(frame->width,frame->height),
- 8,3);
- iplImg->imageData=(char*)qImg->bits();
- timer=newQTimer(this);
- timer->setInterval(30);
- connect(timer,SIGNAL(timeout()),this,SLOT(nextFrame()));
- timer->start();
- }
- }
- myWidget::~myWidget()
- {
- cvReleaseImage(&iplImg);
- cvReleaseCapture(&capture);
- deleteqImg;
- deletetimer;
- }
- voidmyWidget::paintEvent(QPaintEvent*e)
- {
- QPainterpainter(this);
- painter.drawImage(QPoint(0,0),*qImg);
- }
- voidmyWidget::nextFrame()
- {
- frame=cvQueryFrame(capture);
- if(frame)
- {
- if(frame->origin==IPL_ORIGIN_TL)
- {
- cvCopy(frame,iplImg,0);
- }
- else
- {
- cvFlip(frame,iplImg,0);
- }
- cvCvtColor(iplImg,iplImg,CV_BGR2RGB);
- this->update();
- }
- }
主函数里面调用
- intmain(intargc,char*argv[])
- {
- QApplicationapp(argc,argv);
- char*filename="test.avi";
- myWidget*mw=newmyWidget(filename);
- mw->show();
- intre=app.exec();
- returnre;
- }
由于接不截图都看不出来,所以就不截图。
后一个程序因为涉及到slots,所以添加了一个Q_OBJECT宏,编译之前需要将myWidget.h程序moc一下
比如:
- mocmyWidget.h–omoc_myWidget.cpp
这样会在目录下生成一个.cpp文件,make的时候加到源文件里一起make,或者编译的时候添加到源文件列表中去。
知道如何使用QT来显示图像和播放视频之后,在上述代码里面插入处理图像的代码就很简单了。显示图像的时候在构造函数里面就可以插入处理代码,当然也可以在paintEvent函数里面进行处理,播放视频的时候可以在nextFrame函数里面进行处理,有些预处理可以在构造函数里面完成。
相比于MFC的代码,QT的代码结构看上去,很明显,更加优美。
小结:详解 QT 框架中快速应用OpenCV 基于视频播放 下篇的内容介绍完了,希望本文能帮你解决问题!