利用Qt与OpenCV简单实现摄像头图像捕捉

安装Qt 中 OpenCV的设置

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

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

OPENCVPATH_MSVC = D:/Qt/OpenCV-2.1.0-vs2008

win32-msvc*{
INCLUDEPATH += $${OPENCVPATH_MSVC}/include
CONFIG(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}/include
LIBS += -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_NAMESPACE

namespace 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_OBJECT

public:
explicit Dialog(QWidget *parent = 0);
~Dialog();

private slots:
void onImageArrival(const QImage & image);

private:
Ui::Dialog *ui;
CameraDevice * m_camera;
};

#endif // DIALOG_H
//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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值