02_Windows10+OpenCV4.5.5+Qt Creator 实现读入本地视频并播放在QLabel控件上

该文详细介绍了如何在Windows环境下利用Qt框架结合OpenCV库进行视频的读取、播放、暂停及显示操作。通过修改Qt项目的pro文件添加OpenCV库依赖,使用QTimer控制视频帧的更新,并通过QProgressBar展示视频播放进度。文章还提到了视频时长与实际不一致的问题,解决方案是确保读取和存储帧率一致。
摘要由CSDN通过智能技术生成

目录

前期工作

ui界面

 mainwindow.h

 mainwindow.cpp


前面写的两篇相关博客

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/include
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../../user/apps/software/OpenCV4.5/opencv/build/x64/vc14/lib/ -lopencv_world455
else: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);
}

发现问题:录制的视频与实际视频时长不一致
解决方法:设置读取视频帧和存储视频帧帧率一致,定时器时间戳一致

运行效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值