实战OpenCV之视频处理

news2024/11/27 6:07:36

基础入门

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

        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           0

int 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;
    }
#endif

    namedWindow("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.coloradmin.cn/o/2201521.html

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

相关文章

(01)python-opencv基础知识入门(图片的读取与视频打开)

前言 一、图像入门 1.1 读取图像cv.imread() 1.2 数组数据转换cv.cvtColor() 1.3数据窗口展示 1.4图像保存 1.5图像的截取 1.6 图像的比例缩放 二、视频入门 参考文献 前言 OpenCV 于 1999 年由 Gary Bradsky 在英特尔创立&#xff0c;第一个版本于 2000 年问世。Vad…

Golang | Leetcode Golang题解之第468题验证IP地址

题目&#xff1a; 题解&#xff1a; func validIPAddress(queryIP string) string {if sp : strings.Split(queryIP, "."); len(sp) 4 {for _, s : range sp {if len(s) > 1 && s[0] 0 {return "Neither"}if v, err : strconv.Atoi(s); err …

毕业设计项目-古典舞在线交流平台的设计与实现(源码/论文)

项目简介 基于springboot实现的&#xff0c;主要功能如下&#xff1a; 技术栈 后端框框&#xff1a;springboot/mybatis 前端框架&#xff1a;html/JavaScript/Css/vue/elementui 运行环境&#xff1a;JDK1.8/MySQL5.7/idea&#xff08;可选&#xff09;/Maven3&#xff08…

一台电脑轻松接入CANFD总线-来可CAN板卡介绍

在工业控制领域&#xff0c;常常使用的总线技术有CAN(FD)、RS-232、RS-485、Modbus、Profibus、Profinet、EtherCAT等。RS-485以其长距离通信能力著称&#xff0c;Modbus广泛应用于PLC等设备&#xff0c;EtherCAT则以其低延迟和高实时性在自动化系统中备受青睐。 其中&#xf…

实时开放词汇目标检测(论文复现)

实时开放词汇目标检测&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 实时开放词汇目标检测&#xff08;论文复现&#xff09;概述模型框架使用方式配置环境训练和评估训练评估 演示效果Gradio Demo 概述 YOLO-World是由腾讯人工智能实验…

Comfyui 学习笔记5

1.图像处理小工具&#xff0c;沿某个轴反转Image Flip 2. reactor换脸 3. 通过某人的多张照片进行训练 训练的模型会保存在 models/reactor/face/下面&#xff0c;使用时直接load就好 4. 为一个mask 更加模糊 羽化 5. 指定位置替换&#xff0c;个人感觉这种方式进行换脸的融…

评职称需要讲究方法

评职称需要讲究方法 评职称不要太老实 你评三年没下来 你同事走“野路子” 一年就下来了 所以别吃亏了 不走的弯路别走 不该吃的苦别吃 大家如果对于职称评审业绩材料整理还有什么不懂的&#xff0c;可以在评论区留言&#xff0c;甘建二告诉你们怎么报职称&#xff0c;少…

4.C语言概念之旅:解锁关键字,字符,字符串的秘密,揭秘语句和注释,程序员的宝藏

C语言概念之旅&#xff1a;解锁关键字&#xff0c;字符&#xff0c;字符串的秘密&#xff0c;揭秘语句和注释&#xff0c;程序员的宝藏 C语言往期系列文章目录 往期回顾&#xff1a; C语言是什么&#xff1f;编程界的‘常青树’&#xff0c;它的辉煌你不可不知VS 2022 社区版…

Java | Leetcode Java题解之第468题验证IP地址

题目&#xff1a; 题解&#xff1a; class Solution {public String validIPAddress(String queryIP) {if (queryIP.indexOf(.) > 0) {// IPv4int last -1;for (int i 0; i < 4; i) {int cur (i 3 ? queryIP.length() : queryIP.indexOf(., last 1));if (cur <…

优雅的实现服务调用 -- OpenFeign

文章目录 1. RestTemplate存在问题2. OpenFeign介绍3. 快速上手引入依赖添加注解编写OpenFeign的客户端远程调用 4. OpenFeign参数传递从URL中获取参数传递单个参数传递多个参数传递对象传递JSON 5. 最佳实践Feign继承方式创建一个新的模块引入依赖编写接口打jar包服务实现方实…

锐龙7 7800X3D与i7-14700K到底怎么选!其实很简单

从2022年的锐龙7 5800X3D到后来的锐龙7 7800X3D&#xff0c;笔者使用X3D处理器已有2年多的时间。站在自己的立场&#xff0c;我是非常希望游戏老鸟购买这类处理器的&#xff0c;并且也推荐了不少。 这里说的是老鸟&#xff0c;也就是比较懂电脑的玩家。 但是对于新手玩家而言&a…

Canal 扩展篇(阿里开源用于数据同步备份,监控表和表字段(日志))

1.Canal介绍 Canal把自己伪装成从数据库&#xff0c;获取mysql主数据库的日志&#xff08;binlog&#xff09;信息&#xff0c;所以要想使用canal就得先开启数据库日志 https://github.com/alibaba/canal Canal 主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量…

刷题 链表

面试经典150题 - 链表 141. 环形链表 class Solution { public:bool hasCycle(ListNode *head) {ListNode* slow head, *fast head;while (fast ! nullptr && fast->next ! nullptr) {slow slow->next;fast fast->next->next;if (slow fast) {return…

maven加载依赖成功但是引入import不了包,注解报错

突然就复现不出来了&#xff0c;奇了怪了&#xff0c;简单说一下吧&#xff0c;就是模块里引入了SpringBoot Test那个依赖然后&#xff0c; 这个地方是显示引入成功的&#xff0c;但是 这个包下没有&#xff0c;导致我SpringBootTest一直出不来&#xff0c;就找不到这个包下的注…

【一步步开发AI运动小程序】二十、AI运动小程序如何适配相机全屏模式?

引言 受小程序camera组件预览和抽帧图像不一致的特性影响&#xff0c;一直未全功能支持全屏模式&#xff0c;详见本系列文件第四节[小程序如何抽帧]https://blog.csdn.net/alphaair/article/details/133981787 “小程序如何抽帧”)&#xff1b;随着插件在云上赛事、健身锻炼、A…

一个神奇的 Python 库:flanker-next

文章目录 一个神奇的 Python 库&#xff1a;flanker-next背景介绍库简介安装指南函数使用示例解析邮箱地址验证邮箱地址解析 MIME 消息 应用场景自动化邮件处理邮件内容分析客户支持自动化 常见问题及解决方案问题1&#xff1a;解析无效的电子邮件地址问题2&#xff1a;无法找到…

1992-2022年各省夜间灯光数据(excel+shp格式)

1992-2022年各省夜间灯光数据&#xff08;excelshp格式&#xff09; 1、时间&#xff1a;1992-2022年 2、来源&#xff1a; DMSP-OLS、NPP-VIIRS 3、指标&#xff1a;均值、总和、最小值、最大值、标准差 4、范围&#xff1a;34省市&#xff08;含港澳台&#xff09; 5、说…

(25)QPSK信号在AWGN和Rayleigh衰落信道下的性能仿真

文章目录 前言一、MATLAB仿真代码二、仿真结果 前言 QPSK信号在AWGN和Rayleigh衰落信道下的性能仿真MATLAB代码。 一、MATLAB仿真代码 代码如下&#xff1a; nSamp 8; % 矩形脉冲的采样点数 nSymbol 1000000; % 传输的符号…

GPT-SOVIT模型部署指南

一、模型介绍 强大的小样本语音转换和文本转语音 WebUI。 具有以下特征&#xff1a; 零样本 TTS&#xff1a; 输入 5 秒的声音样本并体验即时文本到语音的转换。少量样本 TTS&#xff1a; 仅使用 1 分钟的训练数据对模型进行微调&#xff0c;以提高语音相似度和真实感。跨语…

QD1-P11 HTML常用标签:图片标签

本节学习 HTML 常用标签&#xff1a;图片标签 img ‍ 本节视频 www.bilibili.com/video/BV1n64y1U7oj?p11 ‍ 知识点 1&#xff1a;img 是行内标签 img 是一个行内标签&#xff0c;不会自动换行。 知识点 2&#xff1a;img 标签使用格式 <img src"图片URL" a…