视觉里程计06 Qt界面显示摄像头

界面主体

显示图像通过定时器定时调用信号槽里的更新函数实现

编写信号槽函数前需要先编译,这样才能更新界面的.h文件

具体实现

qtcameratest01.h修改如下:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_qtcameratest01.h"

#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp> // for camera
using namespace cv;

class qtcameratest01 : public QMainWindow
{
	Q_OBJECT

public:
	qtcameratest01(QWidget *parent = Q_NULLPTR);
private:
	Ui::qtcameratest01Class ui;
	QTimer *timer;
	Mat frame;
	QImage image;
	VideoCapture cap1;
	private slots:
	void opencam();
	void nextFrame();
	void closeCamara();
	void camshot();
};
static QImage Mat2QImage(Mat& image);

qtcameratest01.cpp文件修改如下:

#include "qtcameratest01.h"
#include <QMessageBox>
#include <QTimer>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp> // for camera
#include <opencv.hpp>
using namespace cv;


qtcameratest01::qtcameratest01(QWidget *parent)
	: QMainWindow(parent)
{
	// 初始化
	timer = new QTimer(this);
	timer->stop();
	ui.setupUi(this);
	connect(ui.OpenCamBtn, SIGNAL(clicked()), this, SLOT(opencam()));
	connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));
	connect(ui.CloseCamBtn, SIGNAL(clicked()), this, SLOT(closeCamara()));
	connect(ui.CamshotBtn, SIGNAL(clicked()), this, SLOT(camshot()));
}
void qtcameratest01::opencam()
{
	if (cap1.isOpened())
		cap1.release();
	double rate = cap1.get(CV_CAP_PROP_FPS);
	try
	{
		cap1.open(0);
		
		cap1 >> frame;
		if (!frame.empty())
		{
			timer->setInterval(rate);
			timer->start();
		}
		
	}
	catch (const std::exception&)
	{
		QMessageBox::critical(NULL, "ERROR", "打开失败",QMessageBox::Close);
	}
}
static QImage Mat2QImage(Mat& image)
{
	QImage img;

	if (image.channels() == 3) {
		cvtColor(image, image, CV_BGR2RGB);
		img = QImage((const unsigned char *)(image.data), image.cols, image.rows,
			image.cols*image.channels(), QImage::Format_RGB888);
	}
	else if (image.channels() == 1) {
		img = QImage((const unsigned char *)(image.data), image.cols, image.rows,
			image.cols*image.channels(), QImage::Format_ARGB32);
	}
	else {
		img = QImage((const unsigned char *)(image.data), image.cols, image.rows,
			image.cols*image.channels(), QImage::Format_RGB888);
	}

	return img;
}

void qtcameratest01::nextFrame()
{
	cap1 >> frame;
	if (!frame.empty())
	{
		image = Mat2QImage(frame);
		QImage* imgScaled = new QImage;
		QImage* imgc = &image;
		*imgScaled = imgc->scaled(ui.campicreal->width(), ui.campicreal->height(), Qt::KeepAspectRatio);

		ui.campicreal->setPixmap(QPixmap::fromImage(*imgScaled));
	}

}
void qtcameratest01::closeCamara()
{
	timer->stop();//停止读取数据。
	cap1.release();//释放内存;  
}
void qtcameratest01::camshot()
{
	QImage* imgScaled = new QImage;
	QImage* imgc = &image;
	*imgScaled = imgc->scaled(ui.campicreal->width(), ui.campicreal->height(), Qt::KeepAspectRatio);

	ui.campicshot->setPixmap(QPixmap::fromImage(*imgScaled));
}

注意事项

  • 界面中用到的资源需要在ui setup时同时初始化,否则会出现内存错误
  • 界面更新方式通过定时器访问,摄像头资源需要释放
  • debug的话需要CDB,否则无法调试
posted @ 2017-10-22 23:46  回归的世界线  阅读(796)  评论(0编辑  收藏  举报