实战OpenCV之视频处理

基础入门

        视频是由一系列连续的图像帧组成的,这些帧按照一定的速率连续播放,从而形成动态画面。与视频相关的主要参数有:分辨率、帧率、码率、编解码器、帧类型、文件格式等,下面分别进行介绍。

        1、帧率。表示每秒显示的图像帧数,该参数决定视频流畅度,更高的帧率意味着更平滑的动作。常见的帧率有:24fps(电影)、30fps(电视标准)、60fps(流畅的游戏体验)等。

        2、分辨率。表示视频每一帧图像的宽度和高度,通常以像素为单位,该参数决定视频的清晰度和细节程度。常见的分辨率有:720p(1280 x 720)、1080p(1920 x 1080)、4K(3840 x 2160)等。

        3、码率。也叫比特率,指每秒传送的数据量,通常以kbps (千比特/秒) 或 Mbps (兆比特/秒) 表示。该参数影响视频的质量和文件大小,高比特率意味着更好的视频质量,但文件也更大。码率可以是恒定的(CBR, Constant Bitrate),也可以是可变的(VBR, Variable Bitrate)。

        4、编解码器。即Codec,是编码器和解码器的组合词,用于压缩和解压视频数据。该参数影响视频质量和文件大小,常见的编解码算法有:H.264/AVC、H.265/HEVC、MJPEG、VP9等。

        5、帧类型。在H.264、H.265编码算法中,使用了不同的帧类型来提高压缩效率,主要包括I帧、P帧和B帧。

        (1)I帧:也称为帧内编码帧,是一个完整的图像帧,它包含了该帧所有的图像信息,类似于一张静态图片。I帧不需要参考其他任何帧来解码,因此可以在视频的任何点开始播放。但是,由于包含完整信息,所以占用的空间较大。通常用于视频的开头或场景变化较大的地方,因为这些位置不适合使用预测编码。

        (2)P帧:也称为前向预测帧,只包含相对于前一帧变化的部分信息。P帧会参考前一个I帧或P帧来进行解码,通过对前一帧的预测,P帧只需要记录变化的内容,这样就能大大减少所需的存储空间。P帧在视频中占大多数,用于高效地表示场景中变化不大的部分。

        (3)B帧:也称为双向预测帧,会同时向前和向后参考相邻的I帧或P帧。B帧进一步提高了压缩效率,但增加了解码复杂度。

        6、文件格式。用于存储视频数据的标准或容器,不同的视频文件格式有着不同的特性和用途。常见的视频文件格式有:MP4、AVI、MOV、FLV、MPEG、WMV等。

API接口

        cv::VideoCapture是OpenCV中用于处理视频输入的核心类之一,它可以用来从摄像头设备或视频文件中捕获视频帧。cv::VideoCapture类构造函数的原型如下。

VideoCapture();
VideoCapture(int device_index);
VideoCapture(const String& filename);

        各个参数的含义如下。

        device_index:整数,表示设备索引,通常0表示第一个摄像头。

        filename:视频文件的路径。

        cv::VideoCapture类提供了很多实用性的方法来控制视频流,其导出的主要方法如下。

        open用于打开摄像头或者视频文件,成功打开设备或文件返回true,失败返回false。其参数的含义与上面完全相同,故这里不再赘述。

bool open(int device_index);
bool open(const String& filename);

        read用于读取一帧视频数据,成功读取帧返回true,失败返回false。参数image为一个OutputArray,通常是一个cv::Mat对象,用于接收读取到的帧。

bool read(OutputArray image);

        grab会提前获取下一帧的数据,但并不立即填充到image中。如果成功获取下一帧,grab方法返回true。如果没有更多的帧可获取,或者发生错误,grab方法返回false。

bool grab();

        retrieve将先前通过grab方法获取的帧数据填充到image中。如果成功填充了一帧,retrieve方法返回true,并且image将包含这一帧的数据。如果没有通过grab方法获取帧,或者发生错误,retrieve方法返回false。grab和retrieve方法通常一起使用,先通过grab获取下一帧,再通过retrieve获取该帧的数据。这种分离的设计使得处理视频流时更为灵活,可以在获取下一帧之前处理当前帧,或者处理多路视频流。

bool retrieve(OutputArray image, int stream = 0);

        各个参数的含义如下。

        image:一个OutputArray,通常是一个cv::Mat对象,用于接收读取的帧。

        stream:整数,指定要从中检索帧的流。对于单流设备,默认为0。

        isOpened用于判断视频设备或文件是否打开,如果已成功打开,则返回true,否则返回false。

bool isOpened() const;

        release用于释放VideoCapture对象所使用的资源。

void release();

实战解析

        在下面的实战代码中,我们首先定义了一个预处理宏VIDEO_PROCESSING_MODE,用于控制程序是打开一个视频文件还是打开默认摄像头。在主函数中,根据该宏的取值,程序尝试打开视频文件,或启动默认摄像头。如果无法打开视频文件或摄像头,程序会输出错误信息并终止。

        接下里,我们创建了一个名为"Video Processing"的窗口,并设置了窗口的大小。程序随后进入一个无限循环,在每次循环中读取一帧视频,并显示该帧。如果无法读取更多帧,则跳出循环。另外,程序还监听键盘输入,如果用户按下了'q'键,则退出循环。最后,我们释放了VideoCapture对象使用的资源,并销毁所有窗口。

#include <opencv2/opencv.hpp>
using namespace cv;#include <iostream>
using namespace std;#define VIDEO_PROCESSING_MODE           0int main()
{
#if VIDEO_PROCESSING_MODE == 0// 打开视频文件VideoCapture cap("DigitalHuman.mp4");if (!cap.isOpened()){cout << "Can not open or find the video file" << endl;return -1;}
#else// 打开摄像头VideoCapture cap(0);if (!cap.isOpened()){cout << "Can not open or find the camera" << endl;return -1;}
#endifnamedWindow("Video Processing", WINDOW_NORMAL);resizeWindow("Video Processing", 640, 360);Mat frame;// 获取视频的帧率int nFPS = (int)cap.get(CAP_PROP_FPS);while (true){// 读取一帧if (!cap.read(frame)){// 如果无法读取更多帧,跳出循环break;}// 显示当前帧imshow("Video Processing", frame);// 按q键可以退出if (waitKey(1000 / nFPS) == 'q'){break;}}// 释放资源cap.release();destroyAllWindows();return 0;
}

        执行上面的代码,运行效果可参考下图。

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

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

相关文章

【devops】x-ui 实现一键安装 x-ray 打造高速国际冲浪 | xray管理平台

一、部署X-UI篇 1、Github 地址&说明 github地址如下&#xff1a; https://github.com/FranzKafkaYu/x-ui?tabreadme-ov-file 2、一键部署 2.1、更新并安装curl #Ubuntu、Deibian系统 apt update && apt upgrade -y apt install curl -y #CentOS7 系统 yum…

强大的JVM监控工具

介绍 在生产环境中&#xff0c;经常会遇到各种各样奇葩的性能问题&#xff0c;所以掌握最基本的JVM命令行监控工具还是很有必要的 名称主要作用jps查看正在运行的Java进程jstack打印线程快照jmap导出堆内存映像文件jstat查看jvm统计信息jinfo实时查看和修改jvm配置参数jhat用…

现代身份和访问管理 IAM 如何降低风险

您的公司是否仍在使用 1998 年时的身份管理系统&#xff1f;仅凭用户名和密码就能登录本地网络并访问几乎所有资源吗&#xff1f; 虽然大多数企业已经转向现代身份和访问管理(IAM) 平台&#xff0c;但成千上万的企业和其他组织仍然依赖过时的用户名/密码系统。 如果你看一下传…

SpringBoot 整合 阿里云 OSS图片上传

一、OOS 简介 ‌阿里云OSS&#xff08;Object Storage Service&#xff09;是一种基于云存储的产品&#xff0c;适用于存储和管理各种类型的文件&#xff0c;包括图片、视频、文档等。‌ 阿里云OSS具有高可靠性、高可用性和低成本等优点&#xff0c;因此被广泛应用于各种场景&…

简单的网络爬虫爬取视频

示例代码爬取一个周杰伦相关视频 import requests# 自己想下载的视频链接 video_url https://vdept3.bdstatic.com/mda-qg8cnf4bw5x6bjs5/cae_h264/1720516251158906693/mda-qg8cnf4bw5x6bjs5.mp4?v_from_shkapp-haokan-hbf&auth_key1728497433-0-0-4a32e13f751e04754e4…

Avalonia.Xaml.Behaviors开源库的使用

文章目录 简介1. 安装 Avalonia.Xaml.Behaviors2. 创建基本的 Avalonia 应用3. 设置 XAML 界面4. 创建 ViewModel 和 ICommand 实现5. 注册 DataContext6. 使用触发器7. 创建自定义行为8. 在 XAML 中使用自定义行为9. 命令参数传递10. 组合和复用行为总结简介 Avalonia.Xaml.Be…

oracle-函数-instr()的妙用以及相似功能like

INSTR(C1,C2[,I[,J]]) 【功能】在一个字符串中搜索指定的字符,返回发现指定的字符的位置; 【说明】多字节符(汉字、全角符等)&#xff0c;按1个字符计算 【参数】 C1 被搜索的字符串 C2 希望搜索的字符串 I 搜索的开始位置,默认为1 J 第J次出现的位置,默认为1 【…

Ubuntu 24.04升级openssh9.8p1

Ubuntu 24.04升级openssh9.8p1 1、更新2、安装依赖3、新建文件夹4、进入新建文件夹5、下载openssh9.8p1安装包6、当前文件夹解压&#xff17;、进入解压文件夹&#xff18;、配置&#xff19;、编译及安装&#xff11;&#xff10;、重启ssh&#xff11;&#xff11;、查看ssh及…

算法修炼之路之位运算

目录 一:位运算符及一些常用结论总结 1.给一个数n&#xff0c;确定它的二进制表示中的第x位是0还是1(位数从右向左0开始增加) 2.将一个数n的二进制表示形式的第x位修改成1 3.将一个数n的二进制表示的第x位修改为0 4.提取一个数n的二进制表示中最右侧的1 5.干掉一个数n的…

Java、PHP、ASP、JSP、Kotlin、.NET、Go

Java 1995年&#xff0c;Java诞生了&#xff0c;微软的Java是J#&#xff0c;早期是J. 它在C的基础上增强了安全性&#xff0c;不允许多重继承&#xff0c;堆栈不允许类对象&#xff0c;数组和枚举都是类对象。 Java的诞生 早期的Sun公司想要在消费级嵌入式设备编写可移植的代码…

单片机闪存,闪存缓冲取,闪存延迟

一、启用闪存预取缓冲区&#xff08;FLASH_PrefetchBufferCmd (FLASH_PrefetchBuffer_Enable);&#xff09; 闪存预取缓冲区的作用&#xff1a; 在微控制器中&#xff0c;闪存是用于存储程序代码和常量数据的非易失性存储器。当微控制器执行程序时&#xff0c;需要从闪存中读取…

Leetcode热题100-200 岛屿数量

Leetcode热题100-200 岛屿数量 1. 题目描述2. 代码实现1. dfs算法2. bfs算法 1. 题目描述 200 岛屿数量 2. 代码实现 1. dfs算法 class Solution { public:int numIslands(vector<vector<char>>& grid) {int m grid.size(), n grid[0].size();int res 0…

kubernetes-强制删除命名空间

一、故障现象 1、删除命名空间卡住、强制删除也卡住 2、其他终端显示命名空间下无资源 二、处理步骤 1、kubectl get namespace cilium-test -o json > temp.json 获取你需要删除的命名空间json描述文件。 2、修改finalize字段 3、替换 kubectl replace --r…

OmniH2O——通用灵巧且可全身远程操作并学习的人形机器人(其前身H2O是HumanPlus的重要参考)

前言 由于我司一直在针对各个工厂、公司、客户特定的业务场景&#xff0c;做解决方案或定制开发&#xff0c;所以针对每一个场景&#xff0c;我们都会反复考虑用什么样的机器人做定制开发 于此&#xff0c;便不可避免的追踪国内外最前沿的机器人技术进展&#xff0c;本来准备…

信息安全工程师(42)VPN类型和实现技术

前言 VPN&#xff08;Virtual Private Network&#xff0c;虚拟专用网络&#xff09;是一种在公共网络上建立专用网络连接的技术。 一、VPN类型 VPN可以根据不同的分类标准划分为多种类型&#xff0c;主要包括以下几种&#xff1a; 按协议分类&#xff1a; PPTP&#xff08;Poi…

JPA 概述及描述对象和表之间的映射关系注解

参考文档&#xff1a;JPA 概述及常用注解详解、SpringDataJpa 使用指南-阿里云开发者社区 (aliyun.com) 概述 JPA&#xff08;Java Persistence API&#xff09;是 Java 标准中的一套ORM规范&#xff08;提供了一些编程的 API 接口&#xff0c;具体实现由 ORM 厂商实现&#x…

创建osd加入集群

故障原因&#xff1a;ceph节点一个磁盘损坏&#xff0c;其中osd69 down了&#xff0c;需要更换磁盘并重新创建osd加入ceph集群。 信息采集&#xff1a; 更换磁盘前&#xff0c;查询osd69对应的盘符&#xff1a; 将对应的故障磁盘更换后&#xff0c;并重做raid&#xff0c;然后查…

ChatGPT相关参数示例

max_token 用于控制最大输出长度&#xff0c;若ChatGPT的回复大于max_tokens&#xff0c;则对输出结果进行截断。 from openai import OpenAI client OpenAI(base_url"https://api.chatanywhere.tech/v1" ) response client.chat.completions.create(model"…

超轻巧modbus调试助手使用说明

一、使用说明 1.1 数据格式 和其他的modbus采集工具一样&#xff0c;本组件也支持各种数据格式&#xff0c;其实就是高字节低字节的顺序。一般是2字节表示一个数据&#xff0c;后面又有4字节表示一个数据&#xff0c;目前好像还有8字节表示一个数据的设备。不同厂家的设备对应…

vue3+vant4+微信公众号实现图片上传和扫一扫功能

这里我只记录了js的实现过程 首先先安装weixin-js-sdk npm install weixin-js-sdk 处理JS-SDK配置&#xff0c;前提是已经从后端获取到了appId和openId <script setup> import { ref, onMounted } from "vue"; import { imageConfig } from "/api&quo…