Qt实现 结合opencv播放mp4

5 篇文章 1 订阅
1 篇文章 0 订阅

目录

1、opencv介绍

2、效果图

3、下载并编译opencv源码,生成DLL

4、核心代码


1、opencv介绍

opencv的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库,底层代码由C++编写,拥有c++、python、java等接口。

因为其跨平台特性,被广泛运用于:人脸识别,图像处理、人机交互等领域。

2、效果图

本项目实现了通过opencv+qt播放视频的功能。其中用qt制作前端,opencv负责处理视频的解码过程。

3、下载并编译opencv源码,生成DLL

opencv下载地址:https://opencv.org/releases/

我选择的是3.4.12。点击sources下载源码。

打开cmake,编译源码出库。cmake下载地址:https://cmake.org/download/

因为我的vs是2015,然后本次的项目是基于x64编译的,所以勾选的是以上。

cmake结束后,打开OpenCV.sln。生成解决方案。

然后找到CMakeTargets。右键INSTALL,选择仅生成INSTALL

在install\x64\vc14的目录下,会有对应的bin目录和lib目录。分别存放着DLL和lib。

最后再切换到release,编译即可得到release版本的DLL。

4、核心代码

1、绘制视频图像

bool LMoviePlayer::eventFilter(QObject *e, QEvent *event)
{
	if (e == this->_widget && event->type() == QEvent::Paint)
	{
		showImage();
	}
	return QWidget::eventFilter(e, event);
}

void LMoviePlayer::showImage()
{
	QPainter painter;
	painter.begin(this->_widget);
	if(!_image.isNull())
		painter.drawImage(0, 0, _image);
	painter.end();
}

通过Qt的QPainter类提供的drawImage进行绘制。因为视频其实是一幅幅连续的图像组成,所以drawImage能够很好的显示视频的图像。

因为视频是在界面的子控件上显示的,所以需要注册事件过滤器,而不是重写paintEvent中进行。

2、opencv的Mat转QImage

void LMoviePlayer::onSendMat(cv::Mat mat)
{
	Mat matDes;
	uchar *buf = new uchar[_widget->width()*_widget->height() * 3];
	_image = QImage(buf, _widget->width(), _widget->height(), QImage::Format_RGB888);
	cv::resize(mat, matDes, Size(_image.size().width(), _image.size().height()));
	cv::cvtColor(matDes, matDes, COLOR_BGR2RGB);

	int matDesSize = matDes.cols*matDes.rows*matDes.elemSize();
	memcpy(_image.bits(), matDes.data, matDesSize);

	update();
}

mat对象通过信号槽传递而来,通过它可以获取到图像数据。因为opencv是按bgr存储像素,所以把它转换为rgb。QImage才能被绘制出来。

3、子线程读取视频,发出图像数据

void MovieWork::run()
{
	Mat mat;
	while (!_bIswork)
	{
		if(!_capture.isOpened()) continue;

		if (!_capture.read(mat)) {
			if(mat.empty()) continue;
		}
		emit sigSendMat(mat);
		QThread::msleep(40);	//25帧
	}
}

通过继承QThread,重写run方法,实现子线程对视频数据的读取,解码过程被封装在了opencv的VideoCapture类中,

将解码到的数据通过Qt特有的信号槽发送到界面绘制类进行。

4、界面绘制

LMoviePlayer::LMoviePlayer(QWidget *parent)
    : QWidget(parent)
{
	_widget = new QWidget;
	_widget->installEventFilter(this);
	_openMovieBtn = new QPushButton;
	_openMovieBtn->setText(TC("打开视频"));
	_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

	QVBoxLayout *vlayout = new QVBoxLayout;
	vlayout->setMargin(0);
	vlayout->setSpacing(5);
	vlayout->addWidget(_widget);
	vlayout->addWidget(_openMovieBtn);

	this->setMinimumSize(400, 300);
	this->setLayout(vlayout);

	_movieWork = new MovieWork(this);
	qRegisterMetaType<cv::Mat>("cv::Mat");
	connect(_movieWork, SIGNAL(sigSendMat(cv::Mat)), this, SLOT(onSendMat(cv::Mat)));
	connect(_openMovieBtn, SIGNAL(clicked()), this, SLOT(onOpenMovie()));

}

这里需要注意的是qRegisterMetaType<cv::Mat>("cv::Mat");因为这个类型不是qt自带的类型,所以需要注册,qt的信号槽才能够识别并发送出来。

界面上通过QVBoxLayout进行垂直布局,对_widget这个现实视频的子控件设置为宽、高可扩展。

以上就是opencv+qt实现视频的播放,如需要完整源代码和opencv库,可以关注我的公众号 回复 LMoviePlayer 领取。

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值