实战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…

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

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

算法修炼之路之位运算

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

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

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

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…

创建osd加入集群

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

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

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

C++ | Leetcode C++题解之第457题环形数组是否存在循环

题目&#xff1a; 题解&#xff1a; class Solution { public:bool circularArrayLoop(vector<int>& nums) {int n nums.size();auto next [&](int cur) {return ((cur nums[cur]) % n n) % n; // 保证返回值在 [0,n) 中};for (int i 0; i < n; i) {if …

【论文速看】DL最新进展20241009-图像生成、多模态、医学扩散模型、行人重识别

目录 【图像生成】【多模态】【医学扩散模型】【行人重识别】 【图像生成】 [2024] CAR: Controllable Autoregressive Modeling for Visual Generation 论文链接&#xff1a;https://arxiv.org/pdf/2410.04671 代码链接&#xff1a;https://github.com/MiracleDance/CAR 可控…

torchvision.transforms.Resize()的用法

今天我在使用torchvision.transforms.Resize()的时候发现&#xff0c;一般Resize中放的是size或者是(size,size)这样的二元数。 这两个里面&#xff0c;torchvision.transforms.Resize((size,size))&#xff0c;大家都很清楚&#xff0c;会将图像的h和w大小都变成size。 但是…

洞察AI趋势:智享AI直播,打造专属你的数字化直播AIGC系统!

洞察AI趋势&#xff1a;智享AI直播&#xff0c;打造专属你的数字化直播AIGC系统&#xff01; 在当今这个日新月异的数字时代&#xff0c;人工智能&#xff08;AI&#xff09;已不再是遥不可及的未来科技&#xff0c;而是正深刻改变着我们生活、工作的每一个角落。其中&#xf…

[ROS2]解决PyQt5和sip的各种报错问题 stderr: qt_gui_cpp

前言 编译ros环境的时候遇到了qt_gui_cpp各种编译问题&#xff0c;但是鉴于网上解决方法基本没有&#xff0c;故记录下来帮助后来者。整篇文章总结下来就是一句话&#xff1a;PyQt5和sip安装过程或安装版本有问题&#xff0c;需要重新安装。 问题与解决方法 如果PyQt5你是正…

DAMA数据管理知识体系(第12章 元数据管理)

课本内容 12.1 引言 图12-1 语境关系图&#xff1a;元数据概念理解 元数据的信息范围很广&#xff0c;不仅包括技术和业务流程、数据规则和约束&#xff0c;还包括逻辑数据结构与物理数据结构等。它描述了数据本身&#xff08;如数据库、数据元素、数据模型&#xff09;&#x…

女性议题,正在成为喜综困境?

《脱口秀和Ta的朋友们》&#xff08;以下简称《脱友》&#xff09;与《喜剧之王单口季》&#xff08;以下简称《喜单》&#xff09;两档喜综的对垒&#xff0c;竟然意外走向了同一个落点&#xff1a;对女性视角的收割。 #杨笠 这是血肉在疯长的声音# #杨笠 不是敢说是不知道这…