当前位置: 首页 > article >正文

RK3568 opencv播放视频

文章目录

  • 一、opencv相关视频播放类
    • 1. `cv::VideoCapture` 类
      • 主要构造方法:
      • 主要方法:
    • 2. 视频播放基本流程
      • 代码示例:
    • 3. 获取和设置视频属性
    • 4. 结合 FFmpeg 使用
    • 5. OpenCV 视频播放的局限性
    • 6. 结合 Qt 实现更高级的视频播放
    • 总结
  • 二、QT中的代码实现


一、opencv相关视频播放类

在 OpenCV 中,视频播放主要依赖 cv::VideoCapture 类来进行视频读取和播放,同时使用 cv::imshow 进行帧显示。下面是 cv::VideoCapture 相关的基本概念和用法解析。


1. cv::VideoCapture

cv::VideoCapture 用于从视频文件、摄像头或网络流中读取视频数据。它可以处理多种格式的视频文件,如 MP4、AVI、MKV 以及摄像头流数据。

主要构造方法:

cv::VideoCapture();                     // 空构造函数,需要后续调用 open()
cv::VideoCapture(const std::string& filename); // 通过文件路径打开视频
cv::VideoCapture(int deviceID);         // 通过设备 ID 打开摄像头

主要方法:

方法作用
bool open(const std::string& filename)打开视频文件
bool open(int deviceID)打开摄像头
bool isOpened() const检查是否成功打开
void release()释放资源
bool read(cv::Mat& frame)读取下一帧
bool grab()只抓取一帧数据
bool retrieve(cv::Mat& frame, int flag = 0)获取当前抓取的帧
double get(int propId)获取视频参数
bool set(int propId, double value)设置视频参数

2. 视频播放基本流程

一个基本的视频播放程序通常包含以下步骤:

  1. 打开视频文件或摄像头
  2. 逐帧读取并显示
  3. 监听键盘输入进行暂停、退出等操作
  4. 释放资源

代码示例:

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::VideoCapture cap("video.mp4"); // 打开视频文件
    if (!cap.isOpened()) {
        std::cerr << "无法打开视频文件!" << std::endl;
        return -1;
    }

    cv::Mat frame;
    while (true) {
        cap >> frame;  // 读取一帧
        if (frame.empty()) break; // 读取完毕则退出

        cv::imshow("Video Playback", frame);

        // 按 'q' 退出,延迟 30ms
        if (cv::waitKey(30) == 'q') break;
    }

    cap.release();
    cv::destroyAllWindows();
    return 0;
}

3. 获取和设置视频属性

可以使用 get()set() 获取或修改视频参数:

double fps = cap.get(cv::CAP_PROP_FPS); // 获取帧率
int width = cap.get(cv::CAP_PROP_FRAME_WIDTH); // 获取宽度
int height = cap.get(cv::CAP_PROP_FRAME_HEIGHT); // 获取高度

修改属性(仅部分参数可修改):

cap.set(cv::CAP_PROP_FRAME_WIDTH, 640);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 480);

4. 结合 FFmpeg 使用

OpenCV 默认使用系统自带的编解码器播放视频,可能不支持所有格式。可以让 OpenCV 依赖 FFmpeg 来解码:

  • Windows 用户可以下载 FFmpeg 并设置环境变量。
  • Linux/macOS 用户可以使用 apt install ffmpegbrew install ffmpeg 进行安装。

检查 OpenCV 是否支持 FFmpeg:

std::cout << "FFmpeg support: " << cv::getBuildInformation() << std::endl;

5. OpenCV 视频播放的局限性

  1. 性能问题cv::VideoCapture 读取和解码较慢,不如 FFmpeg 专用库快。
  2. 格式支持有限:依赖编译选项和系统解码器,部分格式可能不受支持。
  3. 音频播放问题:OpenCV 仅处理视频帧,不支持音频,需要额外结合 FFmpeg 处理。

6. 结合 Qt 实现更高级的视频播放

如果你在 C++/Qt 项目中使用 OpenCV,可以使用 QLabel 结合 QImage 进行视频播放:

#include <opencv2/opencv.hpp>
#include <QImage>
#include <QPixmap>
#include <QLabel>

void displayFrame(cv::Mat frame, QLabel* label) {
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
    QImage img(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
    label->setPixmap(QPixmap::fromImage(img));
}

总结

  1. cv::VideoCapture 是 OpenCV 进行视频播放的核心类,可以从文件、摄像头读取视频。
  2. 基本流程 是打开视频 -> 逐帧读取 -> cv::imshow() 显示 -> 监听 cv::waitKey() 控制播放。
  3. 可以获取/设置视频属性,如帧率、宽高等。
  4. 性能有限,如果对播放速度、格式兼容性有较高要求,建议结合 FFmpegQt 多媒体模块

二、QT中的代码实现

#include "widget.h"
#include "ui_widget.h"
#include <QImage>
#include <QPixmap>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent),
    ui(new Ui::Widget),
    label(new QLabel(this)),
    btnPlayPause(new QPushButton("暂停", this)), // 按钮默认显示“暂停”
    cap("/mnt/app/1.mp4"), // 本地视频路径
    timer(new QTimer(this)),
    isPlaying(true)
{
    ui->setupUi(this);
    setFixedSize(700, 550); // 固定窗口大小

    // 设置 QLabel 位置和大小
    label->setGeometry(10, 10, 640, 480);

    // 设置播放/暂停按钮
    btnPlayPause->setGeometry(300, 500, 100, 40);
    connect(btnPlayPause, &QPushButton::clicked, this, &Widget::togglePlayback);

    // 检查视频文件是否打开成功
    if (!cap.isOpened()) {
        qWarning("无法打开视频文件!");
        return;
    }

    // 启动定时器,每 30ms 更新一帧(大约 33 FPS)
    connect(timer, &QTimer::timeout, this, &Widget::updateFrame);
    timer->start(30);
}

Widget::~Widget()
{
    cap.release(); // 释放 OpenCV 资源
    delete timer;
    delete ui;
}

void Widget::updateFrame()
{
    if (!isPlaying) return; // 如果暂停,则不更新帧

    cv::Mat frame;
    cap >> frame;  // 读取一帧

    if (frame.empty()) {
        qWarning("视频播放结束!");
        timer->stop();  // 停止定时器
        return;
    }

    // OpenCV 默认是 BGR 颜色格式,转换为 RGB
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);

    // 将 Mat 转换为 QImage
    QImage img(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);

    // 显示图像,并适配 QLabel 尺寸
    label->setPixmap(QPixmap::fromImage(img).scaled(label->size(), Qt::KeepAspectRatio));
}

void Widget::togglePlayback()
{
    isPlaying = !isPlaying;
    btnPlayPause->setText(isPlaying ? "暂停" : "播放"); // 更新按钮文本
}

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QTimer>
#include <opencv2/opencv.hpp>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void updateFrame();  // 更新视频帧
    void togglePlayback();  // 切换播放/暂停状态

private:
    Ui::Widget *ui;
    QLabel *label;  // 用于显示视频的QLabel
    QPushButton *btnPlayPause;  // 播放/暂停按钮
    cv::VideoCapture cap;  // OpenCV视频捕获对象
    QTimer *timer;  // 用于定时刷新视频帧
    bool isPlaying;  // 播放状态标记
};

#endif // WIDGET_H


http://www.kler.cn/a/526750.html

相关文章:

  • flowable expression和json字符串中的双引号内容
  • 5.3.2 软件设计原则
  • C++ 堆栈分配的区别
  • 【股票数据API接口41】如何获取股票指最新分时MA数据之Python、Java等多种主流语言实例代码演示通过股票数据接口获取数据
  • 基于阿里云百炼大模型Sensevoice-1的语音识别与文本保存工具开发
  • 简要介绍C语言和c++的共有变量,以及c++特有的变量
  • 第23节课:前端调试技巧—掌握浏览器开发者工具与性能优化
  • 理解PLT表和GOT表
  • 新春登蛇山:告别岁月,启航未来
  • LeetCode 0219.存在重复元素 II:哈希表
  • 【Leetcode刷题记录】166. 分数到小数
  • [EAI-022] FuSe,在VLA模型基础上,融合触觉和语音等异构模态信息
  • 动态规划两个数组dp问题系列一>最长公共子序列
  • 网站快速收录:利用RSS订阅提升效率
  • fpga系列 硬件:FPGA VITIS PS端HELLO WORLD在 ZYNQ EBAZ4203板上实现
  • ADC 精度 第二部分:总的未调整误差解析
  • 33333333333
  • Autogen_core 测试代码:test_cancellation.py
  • Electron工具Electron Fiddle
  • 【TypeScript】TypeScript 运算符
  • AI 的安全性与合规性:实践中的最佳安全策略
  • 【Block总结】PKI 模块,无膨胀多尺度卷积,增强特征提取的能力|即插即用
  • 【华为OD-E卷 - 分积木 100分(python、java、c++、js、c)】
  • Autogen_core: test_code_executor.py
  • 算法---快速排序
  • Python3 【集合】避坑指南:常见错误解析