QT opencv读取视频数据,QLabel实时显示图像(定时器)

简述

使用 Qt 做一个实时显示视频的Demo,这里结合Opencv来做的。该视频可以是从摄像头实时获取的数据,也可以是本地保存的视频数据。

简述下思路:

  • 使用 QT 做一个文件选择器,选择本地视频;
  • 使用opencv读取该视频数据,将视频分解成一帧一帧的图像;
  • 利用定时器,定时的调用显示图像接口。(这里使用QLabel显示每一帧图像;定时器的时间与视频的帧率有关;);

注:这里注重说明一点,这里必须用定时器,而不可用 waitKey(),因QLabel是组件,使用waitKey()方法会使得QLabel数据堵塞,不能显示。

代码

界面展示:

1、初始化

QTimer m_timer = new QTimer(this);
VideoCapture m_cap = new VideoCapture();
//定时器信号关联 
connect(m_timer, SIGNAL(timeout()), this, SLOT(slots_catchCap()));

2、选择本地视频路径

//"选择视频"按钮点击事件
void LeakDetectionSimulator::slots_chooseVideo_Btn_Clicked()
{
	//定义文件对话框类
	QFileDialog *fileDialog = new QFileDialog(this);
	//定义文件对话框标题
	fileDialog->setWindowTitle(QStringLiteral("选择视频"));
	//设置默认文件路径
	fileDialog->setDirectory(".");
	//设置文件过滤器
	fileDialog->setNameFilter(tr("Video(*.mp4 *.avi *.mkv *.flv *.rmvb)"));
	//设置视图模式
	fileDialog->setViewMode(QFileDialog::Detail);
	//打印所选择的文件的路径
	QString fileName;
	if (fileDialog->exec())
	{
		fileName = fileDialog->selectedFiles()[0];
        //显示选择的视频路径
		ui.videoPath_LineEdit->setText(fileName);
	}
}

3、开始检测

//“开始检测”按钮点击事件
void slots_start_Btn_Clicked()
{
	if (ui.start_Btn->text().compare(QStringLiteral("停止检测")) == 0)
	{		
		//关闭定时器
		m_timer->stop();
		ui.imgShow_label->clear();
		PrintInfo("已停止检测!");
		ui.start_Btn->setText(QStringLiteral("开始检测"));
		return;
	}

	//获取全局参数
	if (ui.videoPath_LineEdit->text().compare("") == 0)
	{
		QMessageBox::about(NULL, QStringLiteral("提示"), QStringLiteral("未选择视频,请选择视频后重新操作!"));
		return;
	}

	if (ui.interval_LineEdit->text().compare("") == 0)
	{
		QMessageBox::about(NULL, QStringLiteral("提示"), QStringLiteral("未输入间隔时间,请检查!"));
		return;
	}

    //打开视频
    m_cap->open(QStr2Str(ui.videoPath_LineEdit->text()));
	if (m_cap->isOpened() == false)
    {
        PrintInfo("视频未能打开!");
		return;
    }

	//获取当前视频帧率
	double rate = m_cap->get(CV_CAP_PROP_FPS);
	//每一帧之间的延时与视频的帧率相对应
	m_delay = 1000 / rate;


	//开启定时器
	m_timer->start(m_delay);

	PrintInfo("开始检测!");

	ui.start_Btn->setText(QStringLiteral("停止检测"));
}
//QString 转 string (无中文论码)
string QStr2Str(const QString qStr)
{
	QByteArray cdata = qStr.toLocal8Bit();
	return string(cdata);
}
//获取图像(定时器关联的槽方法)
void slots_catchCap()
{
    m_cap->read(m_frame);

	if (m_frame.empty())
    {
        PrintInfo("视频读取完!");
		//关闭定时器
		m_timer->stop();
        return;
    }
	//显示图像
	ui.imgShow_label->setPixmap(QPixmap::fromImage(MatToQImage(m_frame)));
}

// Mat 转换成 QImage
QImage MatToQImage(const cv::Mat &inMat)
{
	switch (inMat.type())
	{
		case CV_8UC4:		// 8-bit, 4 channel
		{
			QImage image(inMat.data,
				inMat.cols, inMat.rows,
				static_cast<int>(inMat.step),
				QImage::Format_ARGB32);

			return image;
		}

		case CV_8UC3:		// 8-bit, 3 channel
		{
			QImage image(inMat.data,
				inMat.cols, inMat.rows,
				static_cast<int>(inMat.step),
				QImage::Format_RGB888);

			return image.rgbSwapped();
		}

	
		case CV_8UC1:// 8-bit, 1 channel
		{
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
			QImage image(inMat.data,
				inMat.cols, inMat.rows,
				static_cast<int>(inMat.step),
				QImage::Format_Grayscale8); //Format_Alpha8 and Format_Grayscale8 were added in Qt 5.5
#else
			static QVector<QRgb>  sColorTable;

			// only create our color table the first time
			if (sColorTable.isEmpty())
			{
				sColorTable.resize(256);

				for (int i = 0; i < 256; ++i)
				{
					sColorTable[i] = qRgb(i, i, i);
				}
			}

			QImage image(inMat.data,
				inMat.cols, inMat.rows,
				static_cast<int>(inMat.step),
				QImage::Format_Indexed8);

			image.setColorTable(sColorTable);
#endif
			return image;
		}

		default:
//			qWarning() << "CVS::cvMatToQImage() - cv::Mat image type not handled in switch:" << inMat.type();
			break;
	}

	return QImage();
}

因是公司项目,所以很多地方做了删减,但是大致思路都在。

  • 13
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
您好!对于在Qt中使用OpenCV控件并在视频图像显示之前的问题,可以按照以下步骤进行操作: 1. 首先,确保已经正确地集成了QtOpenCV库到您的项目中。 2. 创建一个Qt窗口应用程序,并在UI设计中添加一个控件用于显示视频图像,例如一个QLabel。 3. 在您的代码中,使用OpenCV读取视频文件或者从摄像头捕获视频帧。 4. 将捕获到的视频帧转换为Qt图像格式,例如QImage。 5. 将转换后的图像设置给QLabel控件进行显示。 下面是一些示例代码,帮助您理解如何在Qt中实现这个功能: ```cpp #include <QApplication> #include <QLabel> #include <QTimer> #include <opencv2/opencv.hpp> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建Qt窗口和控件 QLabel label; label.show(); cv::VideoCapture capture("path_to_video_file"); // 替换为您的视频文件路径或者摄像头索引 QTimer timer; QObject::connect(&timer, &QTimer::timeout, [&]() { cv::Mat frame; capture >> frame; if (!frame.empty()) { // 将OpenCV的Mat转换为Qt的QImage QImage image(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888); image = image.rgbSwapped(); // 如果图像是BGR格式,需要进行颜色通道交换 // 将图像设置给QLabel控件进行显示 label.setPixmap(QPixmap::fromImage(image).scaled(label.size(), Qt::KeepAspectRatio)); } }); // 设置定时器的时间间隔,控制视频帧的刷新率 timer.setInterval(33); // 30帧/秒 // 启动定时器 timer.start(); return app.exec(); } ``` 请注意,以上代码仅为示例,您需要根据您的实际需求进行调整和扩展。希望对您有帮助!如有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值