目录
前面写的两篇相关博客
https://blog.csdn.net/qq_52218412/article/details/130730387Windows系统下 在qt中 对OpenCV下载配置并简单使用
https://blog.csdn.net/qq_52218412/article/details/130751428Windows10+OpenCV4.5.5打开本地图片进行图片处理 实时摄影并抓拍图片存入本机
前期工作
pro文件添加外部库 INCLUDEPATH += $$PWD/../../../user/apps/software/OpenCV4.5/opencv/build/includewin32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../../user/apps/software/OpenCV4.5/opencv/build/x64/vc14/lib/ -lopencv_world455else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../user/apps/software/OpenCV4.5/opencv/build/x64/vc14/lib/ -lopencv_world455d
头文件
#include <QMainWindow> #include <opencv2/opencv.hpp> #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/video.hpp> #include <QFileDialog> #include <QProgressBar> #include <QTimer> #include <QLabel> #include <QTime> using namespace cv;
ui界面
mainwindow.h
private slots:
// 打开 关闭 视频
void on_action_open_triggered();
void on_action_close_triggered();
// 显示视频帧
void setVideoFrame();
// 播放暂停功能
void on_action_stop_triggered();
void on_action_play_triggered();
private:
Ui::MainWindow *ui;
Mat m_frame_;
// 定时器
QTimer *m_timer_;
// 视频读入、视频写入
VideoCapture m_capture_;
VideoWriter m_writer_;
// 工具栏上的进度条
QLabel *m_label_;
QProgressBar *m_progressBar_;
QString m_videoTime_;
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 1 读入视频
// 2 解析视频并播放
// 3 播放暂停功能
// 显示视频时长 视频进度
m_progressBar_ = new QProgressBar(this);
m_progressBar_->hide();
m_label_ = new QLabel(this);
ui->statusbar->addPermanentWidget(m_label_);
//可以使图片完全按QWidget缩放,而不保持原视频比例
ui->label->setScaledContents(true);
m_timer_ = new QTimer(this);
connect(m_timer_, SIGNAL(timeout()), this, SLOT(setVideoFrame()));
}
MainWindow::~MainWindow()
{
delete ui;
}
// 打开本地视频 并播放视频
void MainWindow::on_action_open_triggered()
{
// 从本地文件夹获取视频
const QString dyn = "*.mp4;;*.gif;;*.avi";
QString path = QFileDialog::getOpenFileName(this, "", "../../mp34/video/", dyn);
// 读入视频
m_capture_.open(path.toStdString());
if(!m_capture_.isOpened()) {
ui->label->setText("Open failed");
}
// 50毫秒为一帧
m_timer_->start(50);
// 获取视频时长 duration
// 获取帧率 fps 视频帧数 frameCount
double fps = m_capture_.get(cv::CAP_PROP_FPS);
int frameCount = m_capture_.get(cv::CAP_PROP_FRAME_COUNT);
int duration = static_cast<int>(frameCount / fps * 1000);
m_videoTime_ = QTime(0, 0, 0).addMSecs(duration).toString("hh:mm:ss");
// 设置进度条的范围 并放入状态栏
m_progressBar_->setRange(0, duration);
m_progressBar_->show();
ui->statusbar->addWidget(m_progressBar_);
}
// 关闭视频 并清空屏幕
void MainWindow::on_action_close_triggered()
{
// 关闭视频
m_capture_.release();
m_timer_->stop();
// 清空 界面 进度值 进度条
ui->label->clear();
m_label_->clear();
m_progressBar_->hide();
}
// 设置视频帧展示
void MainWindow::setVideoFrame()
{
// 将视频帧取出
m_capture_.read(m_frame_);
// 帧为空代表无内容,退出循环
if(m_frame_.empty()) {
m_timer_->stop();
return;
}
// 将BGR颜色空间转换为RGB空间
cvtColor(m_frame_, m_frame_, COLOR_BGR2RGB);
// 数据源为data指针,图像的宽度、高度、字节数、像素格式
QImage disImage(m_frame_.data, m_frame_.cols, m_frame_.rows, m_frame_.step,
QImage::Format_RGB888);
// 对QImage对象进行缩放
disImage = disImage.scaled(ui->label->width(), ui->label->height());
ui->label->setPixmap(QPixmap::fromImage(disImage));
// 设置状态栏相关数值
// 获取当前视频帧的时间戳(ms)
double timeStamp = m_capture_.get(cv::CAP_PROP_POS_MSEC);
QString currentTime = QTime(0, 0, 0).addMSecs(timeStamp).toString("hh:mm:ss");
m_label_->setText(QString("%1/%2").arg(currentTime).arg(m_videoTime_));
// 设置进度条的实时值
m_progressBar_->setValue(timeStamp);
}
// 通过控制定时器达到视频暂停的效果
void MainWindow::on_action_stop_triggered()
{
m_timer_->stop();
}
// 通过控制定时器达到视频播放的效果
void MainWindow::on_action_play_triggered()
{
// 50毫秒为一帧
m_timer_->start(50);
}
发现问题:录制的视频与实际视频时长不一致
解决方法:设置读取视频帧和存储视频帧帧率一致,定时器时间戳一致
运行效果图: