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' 退出,延迟 30msif (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 颜色格式,转换为 RGBcv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);// 将 Mat 转换为 QImageQImage 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_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void updateFrame();  // 更新视频帧void togglePlayback();  // 切换播放/暂停状态private:Ui::Widget *ui;QLabel *label;  // 用于显示视频的QLabelQPushButton *btnPlayPause;  // 播放/暂停按钮cv::VideoCapture cap;  // OpenCV视频捕获对象QTimer *timer;  // 用于定时刷新视频帧bool isPlaying;  // 播放状态标记
};#endif // WIDGET_H

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洛谷P3383 【模板】线性筛素数

题目链接&#xff1a;P3383 【模板】线性筛素数 - 洛谷 | 计算机科学教育新生态 题目难度&#xff1a;普及一 题目分析&#xff1a;本题是模板题&#xff0c;用到了线性筛法&#xff0c;其中原理是保证范围内的每个合数都被删掉&#xff08;在 bool 数组里面标记为非素数…

STM32标准库移植RT-Thread nano

STM32标准库移植RT-Thread Nano 哔哩哔哩教程链接&#xff1a;STM32F1标准库移植RT_Thread Nano 移植前的准备 stm32标准库的裸机代码&#xff08;最好带有点灯和串口&#xff09;RT-Thread Nano Pack自己的开发板 移植前的说明 本人是在读学生&#xff0c;正在学习阶段&a…

JVM--类加载器

概念 类加载器&#xff1a;只参与加载过程中的字节码获取并加载到内存中的部分&#xff1b;java虚拟机提供给应用程序去实现获取类和接口字节码数据的一种技术&#xff0c;也就是说java虚拟机是允许程序员写代码去获取字节码信息 类加载是加载的第一步&#xff0c;主要有以下三…

ECMAScript 6语法

1.ES6简介 ECMAScript 6&#xff08;简称ES6&#xff09;是于2015年6月正式发布的JavaScript语言的标准&#xff0c;正式名为ECMAScript 2015&#xff08;ES2015&#xff09;。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序&#xff0c;成为企业级开发语言 。 …

联想Y7000+RTX4060+i7+Ubuntu22.04运行DeepSeek开源多模态大模型Janus-Pro-1B+本地部署

直接上手搓了&#xff1a; conda create -n myenv python3.10 -ygit clone https://github.com/deepseek-ai/Janus.gitcd Januspip install -e .pip install webencodings beautifulsoup4 tinycss2pip install -e .[gradio]pip install pexpect>4.3python demo/app_januspr…

FastAPI + GraphQL + SQLAlchemy 实现博客系统

本文将详细介绍如何使用 FastAPI、GraphQL&#xff08;Strawberry&#xff09;和 SQLAlchemy 实现一个带有认证功能的博客系统。 技术栈 FastAPI&#xff1a;高性能的 Python Web 框架Strawberry&#xff1a;Python GraphQL 库SQLAlchemy&#xff1a;Python ORM 框架JWT&…

微服务入门(go)

微服务入门&#xff08;go&#xff09; 和单体服务对比&#xff1a;里面的服务仅仅用于某个特定的业务 一、领域驱动设计&#xff08;DDD&#xff09; 基本概念 领域和子域 领域&#xff1a;有范围的界限&#xff08;边界&#xff09; 子域&#xff1a;划分的小范围 核心域…

【B站保姆级视频教程:Jetson配置YOLOv11环境(二)SSH连接的三种方式】

B站同步视频教程&#xff1a;https://www.bilibili.com/video/BV1m5wUeyEQD/ 在Jetson设备上配置YOLOv11环境时&#xff0c;SSH连接是实现远程高效开发与管理的关键一环。不同的网络环境和硬件配置可能会影响SSH连接的方式&#xff0c;本文将结合相关视频内容&#xff0c;详细…

计算机毕业设计Python+知识图谱大模型AI医疗问答系统 健康膳食推荐系统 食谱推荐系统 医疗大数据 机器学习 深度学习 人工智能 爬虫 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Elasticsearch的索引生命周期管理

目录 说明零、参考一、ILM的基本概念二、ILM的实践步骤Elasticsearch ILM策略中的“最小年龄”是如何计算的&#xff1f;如何监控和调整Elasticsearch ILM策略的性能&#xff1f; 1. **监控性能**使用/_cat/thread_pool API基本请求格式请求特定线程池的信息响应内容 2. **调整…

Vscode的AI插件 —— Cline

简介 vscode的一款AI辅助吃插件&#xff0c;主要用来辅助创建和编辑文件&#xff0c;探索大型项目&#xff0c;使用浏览器并执行终端命令&#xff08;需要多个tokens&#xff09;&#xff0c;可以使用模型上下文协议&#xff08;MCP&#xff09;来创建新工具并扩展自己(比较慢…

小白一命速通JS中的windowglobal对象

笔者注意到JS中的window对象与global对象经常被混淆&#xff0c;尽管它们在相当一部分使用情况下可以等同&#xff0c;但是本质上仍然存在很多不同&#xff0c;下面是对于两者的详细拆解 1. window 对象 定义&#xff1a;window 对象表示 浏览器环境中的全局上下文。作用域&am…

机器学习2 (笔记)(朴素贝叶斯,集成学习,KNN和matlab运用)

朴素贝叶斯模型 贝叶斯定理&#xff1a; 常见类型 算法流程 优缺点 集成学习算法 基本原理 常见方法 KNN&#xff08;聚类模型&#xff09; 算法性质&#xff1a; 核心原理&#xff1a; 算法流程 优缺点 matlab中的运用 朴素贝叶斯模型 朴素贝叶斯模型是基于贝叶斯…

HTB:Active[RE-WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用nmap对靶机…

Git图形化工具【lazygit】

简要介绍一下偶然发现的Git图形化工具——「lazygit」 概述 Lazygit 是一个用 Go 语言编写的 Git 命令行界面&#xff08;TUI&#xff09;工具&#xff0c;它让 Git 操作变得更加直观和高效。 Github地址&#xff1a;https://github.com/jesseduffield/lazygit 主要特点 主要…

58.界面参数传递给Command C#例子 WPF例子

界面参数的传递&#xff0c;界面参数是如何从前台传送到后台的。 param 参数是从界面传递到命令的。这个过程通常涉及以下几个步骤&#xff1a; 数据绑定&#xff1a;界面元素&#xff08;如按钮&#xff09;的 Command 属性绑定到视图模型中的 RelayCommand 实例。同时&#x…

51单片机(STC89C52)开发:点亮一个小灯

软件安装&#xff1a; 安装开发板CH340驱动。 安装KEILC51开发软件&#xff1a;C51V901.exe。 下载软件&#xff1a;PZ-ISP.exe 创建项目&#xff1a; 新建main.c 将main.c加入至项目中&#xff1a; main.c:点亮一个小灯 #include "reg52.h"sbit LED1P2^0; //P2的…

RoboMaster- RDK X5能量机关实现案例(一)识别

作者&#xff1a;SkyXZ CSDN&#xff1a;https://blog.csdn.net/xiongqi123123 博客园&#xff1a;https://www.cnblogs.com/SkyXZ 在RoboMaster的25赛季&#xff0c;我主要负责了能量机关的视觉方案开发&#xff0c;目前整体算法已经搭建完成&#xff0c;实际方案上我使用的上…

MySQL误删数据怎么办?

文章目录 1. 从备份恢复数据2. 通过二进制日志恢复数据3. 使用数据恢复工具4. 利用事务回滚恢复数据5. 预防误删数据的策略总结 在使用MySQL进行数据管理时&#xff0c;误删数据是一个常见且具有高风险的操作。无论是因为操作失误、系统故障&#xff0c;还是不小心执行了删除命…

RDK X5运行DeepSeek-R1-Distill-Qwen-1.5B,体验长思维链的语言大模型!

简介 本文介绍了在RDK X5上&#xff0c;如何从HuggingFace的原始模型权重&#xff08;safetensors&#xff09;经过量化和编译&#xff0c;的到llama.cpp推理框架所需要的GGUF格式的模型&#xff0c;然后演示了如何使用llama.cpp运行量化后的DeepSeek-R1-Distill-Qwen-1.5B模型…