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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/962015.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AWTK 骨骼动画控件发布

Spine 是一款广泛使用的 2D 骨骼动画工具&#xff0c;专为游戏开发和动态图形设计设计。它通过基于骨骼的动画系统&#xff0c;帮助开发者创建流畅、高效的角色动画。本项目是基于 Spine 实现的 AWTK 骨骼动画控件。 代码&#xff1a;https://gitee.com/zlgopen/awtk-widget-s…

新年手搓--本地化部署DeepSeek-R1,全程实测

1.环境准备安装ollma ollma官网链接: Download Ollama on Linux ubuntu命令行安装: curl -fsSL https://ollama.com/install.sh | sh 选择运行模型,用7b模型试一下(模型也差不多5G): ollama run deepseek-r1:7b 运行qwen: ollama run qwen2.5:7b 2.为方便运行…

STM32使用VScode开发

文章目录 Makefile形式创建项目新建stm项目下载stm32cubemx新建项目IED makefile保存到本地arm gcc是编译的工具链G++配置编译Cmake +vscode +MSYS2方式bilibiliMSYS2 统一环境配置mingw32-make -> makewindows环境变量Cmake CmakeListnijia 编译输出elfCMAKE_GENERATOR查询…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.21 索引宗师:布尔索引的七重境界

1.21 索引宗师&#xff1a;布尔索引的七重境界 目录 #mermaid-svg-Iojpgw5hl0Ptb9Ti {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Iojpgw5hl0Ptb9Ti .error-icon{fill:#552222;}#mermaid-svg-Iojpgw5hl0Ptb9Ti .…

毕业设计--具有车流量检测功能的智能交通灯设计

摘要&#xff1a; 随着21世纪机动车保有量的持续增加&#xff0c;城市交通拥堵已成为一个日益严重的问题。传统的固定绿灯时长方案导致了大量的时间浪费和交通拥堵。为解决这一问题&#xff0c;本文设计了一款智能交通灯系统&#xff0c;利用车流量检测功能和先进的算法实现了…

课题推荐:基于matlab,适用于自适应粒子滤波的应用

自适应粒子滤波&#xff08;Adaptive Particle Filter, APF&#xff09;是一种用于状态估计的有效方法&#xff0c;特别适用于非线性和非高斯系统。 文章目录 应用场景MATLAB 代码示例代码说明结果扩展说明 以下是一个基于自适应粒子滤波的简单应用示例&#xff0c;模拟一个一维…

Redis(5,jedis和spring)

在前面的学习中&#xff0c;只是学习了各种redis的操作&#xff0c;都是在redis命令行客户端操作的&#xff0c;手动执行的&#xff0c;更多的时候就是使用redis的api&#xff08;&#xff09;&#xff0c;进一步操作redis程序。 在java中实现的redis客户端有很多&#xff0c;…

基于聚类与相关性分析对马来西亚房价数据进行分析

碎碎念&#xff1a;由于最近太忙了&#xff0c;更新的比较慢&#xff0c;提前祝大家新春快乐&#xff0c;万事如意&#xff01;本数据集的下载地址&#xff0c;读者可以自行下载。 1.项目背景 本项目旨在对马来西亚房地产市场进行初步的数据分析&#xff0c;探索各州的房产市…

(2025 年最新)MacOS Redis Desktop Manager中文版下载,附详细图文

MacOS Redis Desktop Manager中文版下载 大家好&#xff0c;今天给大家带来一款非常实用的 Redis 可视化工具——Redis Desktop Manager&#xff08;简称 RDM&#xff09;。相信很多开发者都用过 Redis 数据库&#xff0c;但如果你想要更高效、更方便地管理 Redis 数据&#x…

智慧园区管理系统为企业提供高效运作与风险控制的智能化解决方案

内容概要 快鲸智慧园区管理系统&#xff0c;作为一款备受欢迎的智能化管理解决方案&#xff0c;致力于为企业提供高效的运作效率与风险控制优化。具体来说&#xff0c;这套系统非常适用于工业园、产业园、物流园、写字楼及公寓等多种园区和商办场所。它通过数字化与智能化的手…

C++中常用的排序方法之——冒泡排序

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C中常用的排序方法之——冒泡排序的…

基础项目实战——3D赛车(c++)

目录 前言一、渲染引擎二、关闭事件三、梯形绘制四、轨道绘制五、边缘绘制六、草坪绘制七、前后移动八、左右移动​九、曲线轨道​十、课山坡轨道​十一、循环轨道​十二、背景展示​十三、引入速度​十四、物品绘制​十五、课数字路障​十六、分数展示​十七、重新生成​十八、…

深度学习指标可视化案例

TensorBoard 代码案例&#xff1a;from torch.utils.tensorboard import SummaryWriter import torch import torchvision from torchvision import datasets, transforms# 设置TensorBoard日志路径 writer SummaryWriter(runs/mnist)# 加载数据集 transform transforms.Comp…

AI时序预测: iTransformer算法代码深度解析

在之前的文章中&#xff0c;我对iTransformer的Paper进行了详细解析&#xff0c;具体文章如下&#xff1a; 文章链接&#xff1a;深度解析iTransformer&#xff1a;维度倒置与高效注意力机制的结合 今天&#xff0c;我将对iTransformer代码进行解析。回顾Paper&#xff0c;我…

Java内存模型 volatile 线程安全

目录 Java内存模型可见性例子和volatilevolatile如何保证可见性原子性与单例模式i非原子性 线程安全 Java内存模型 参考学习: Java Memory Model外文文档 CPU与内存&#xff0c;可参考&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145303267 Java线程与内…

【FreeRTOS 教程 三】协程状态、优先级、实现及调度

目录 一、协程介绍&#xff1a; &#xff08;1&#xff09;协程的特点&#xff1a; &#xff08;2&#xff09;协程的优势&#xff1a; 二、协程状态&#xff1a; &#xff08;1&#xff09;协程状态说明&#xff1a; &#xff08;2&#xff09;协程状态图示&#xff1a;…

堆的存储(了解)

由于堆是⼀个完全⼆叉树&#xff0c;因此可以⽤⼀个数组来存储。&#xff08;如果不清楚大家可以回顾⼆叉树的存储&#xff08;上&#xff09;c文章里的顺序存储&#xff09; 结点下标为 i &#xff1a; 如果⽗存在&#xff0c;⽗下标为 i/2 &#xff1b; 如果左孩⼦存在&…

谭浩强C语言程序设计(3) 7章

1、递归实现N的阶乘 c复制 #include <cstdio> // 包含标准输入输出库// 计算n的阶乘 int total 0; // 定义全局变量total用于存储阶乘结果// 递归函数计算阶乘 int fac(int a){// 如果输入的数小于0&#xff0c;输出错误信息if (a < 0){printf("%d < 0,err…

WPF基础 | WPF 常用控件实战:Button、TextBox 等的基础应用

WPF基础 | WPF 常用控件实战&#xff1a;Button、TextBox 等的基础应用 一、前言二、Button 控件基础2.1 Button 的基本定义与显示2.2 按钮样式设置2.3 按钮大小与布局 三、Button 的交互功能3.1 点击事件处理3.2 鼠标悬停与离开效果3.3 按钮禁用与启用 四、TextBox 控件基础4.…

MATLAB的数据类型和各类数据类型转化示例

一、MATLAB的数据类型 在MATLAB中 &#xff0c;数据类型是非常重要的概念&#xff0c;因为它们决定了如何存储和操作数据。MATLAB支持数值型、字符型、字符串型、逻辑型、结构体、单元数组、数组和矩阵等多种数据类型。MATLAB 是一种动态类型语言&#xff0c;这意味着变量的数…