首页 > 编程语言 >【C++】【OpenCV-4.9.0】视频写入(VideoWriter,借助samples中的代码示例来进行学习)

【C++】【OpenCV-4.9.0】视频写入(VideoWriter,借助samples中的代码示例来进行学习)

时间:2024-03-13 20:13:21浏览次数:17  
标签:视频 示例 get 4.9 char spl ex samples inputVideo

借助官方离线文档中的samples来理解VideoWriter

文档位置:samples/cpp/tutorial_code/videoio/video-write/video-write.cpp

注:需要提前下载 openh264-1.8.0-win64.dll,然后放在Release文件夹下 ,否则无法正确对输出文件进行编码从而运行失败

  1 #include <iostream>
  2 #include <string>
  3 
  4 #include <opencv2/core.hpp>
  5 #include <opencv2/videoio.hpp>
  6 
  7 using namespace std;
  8 using namespace cv;
  9 
 10 void help() {
 11     cout
 12         << "------------------------------------------------------------------------------" << endl
 13         << "This program shows how to write video files." << endl
 14         << "You can extract the R or G or B color channel of the input video." << endl
 15         << "Usage:" << endl
 16         << "./video-write <input_video_name> [ R | G | B] [Y | N]" << endl
 17         << "------------------------------------------------------------------------------" << endl
 18         << endl;
 19 }
 20 
 21 int main(int argc, char* argv[]) {
 22     help();
 23 
 24     // 如果命令行接收的参数长度不等于4则异常退出。
 25     if (argc != 4) {
 26         cout << "Not enough parameters" << endl;
 27         return -1;
 28     }
 29 
 30     // 输入的视频文件,如:CV.exe AVI.avi R G , source = "AVI.avi"
 31     const string source = argv[1];
 32     // 判断用户是否询问输出类型,如果是N,将使用输入视频的编码器类型
 33     const bool askOutputType = argv[3][0] == 'Y';
 34 
 35     VideoCapture inputVideo(source);
 36     if (!inputVideo.isOpened()) {
 37         cout << "Could not open the input video: " << source << endl;
 38         return -1;
 39     }
 40 
 41     // 查找最后一个扩展点,返回下标索引位置,如:CV.exe AVI.avi R G ,pAt = 3
 42     string::size_type pAt = source.find_last_of('.');
 43 
 44     // 定义输出文件名,NAME = "AVIR.avi"
 45     const string NAME = source.substr(0, pAt) + argv[2][0] + ".avi";
 46 
 47     // 获取视频流中的第一帧的编码类型,并转换为int类型(视频流中,每一帧的编码格式可能都不一样)
 48     // 例:
 49     // 转换前 -- 8.75967e+08
 50     // 转换后 -- 875967080
 51     unsigned int ex = static_cast<int>(inputVideo.get(CAP_PROP_FOURCC));
 52 
 53     // 通过按位运算符从int转换为char
 54     // 转换前 -- 875967080 对应的二进制:00110100 00110110 00110010 01101000
 55     // 转换后 -- h264
 56     char EXT[] = {
 57         (char)(ex & 0XFF),
 58         (char)((ex & 0XFF00) >> 8),
 59         (char)((ex & 0XFF0000) >> 16),
 60         (char)((ex & 0XFF000000) >> 24),
 61         0
 62     };
 63 
 64     // 获取输入视频的尺寸
 65     Size S(
 66         (int)inputVideo.get(CAP_PROP_FRAME_WIDTH),
 67         (int)inputVideo.get(CAP_PROP_FRAME_HEIGHT)
 68     );
 69 
 70     // 创建一个写入对象,并指定相关参数(输出视频文件名、编码格式、输入视频帧率、输出视频尺寸、是否为彩色或者灰色)
 71     VideoWriter outputVideo;
 72     if (askOutputType)
 73         outputVideo.open(NAME, ex = -1, inputVideo.get(CAP_PROP_FPS), S, true); // 由CV自动选择帧的编码格式
 74     else
 75         outputVideo.open(NAME, ex, inputVideo.get(CAP_PROP_FPS), S, true); // 和输入视频中的每一帧编码格式保持一致
 76 
 77     // 如果打开失败则输出错误并异常退出
 78     if (!outputVideo.isOpened()) {
 79         cout << "Could not open the output video for write: " << source << endl;
 80         return -1;
 81     }
 82 
 83     // 输出视频尺寸、总帧数和输入视频的编码格式
 84     cout << "Input frame resolution: Width = " << S.width << " Height = " << S.height
 85         << "of nr#: " << inputVideo.get(CAP_PROP_FRAME_COUNT) << endl;
 86     cout << "Input codec type: " << EXT << endl;
 87 
 88     // 选择颜色通道
 89     int channel = 2;
 90     switch (argv[2][0]) {
 91     case 'R':channel = 2; break;
 92     case 'G':channel = 1; break;
 93     case 'B':channel = 0; break;
 94     }
 95 
 96     Mat src, res;
 97     vector<Mat> spl;
 98 
 99     // 循环写入视频
100     for (;;) {
101         inputVideo >> src;
102         if (src.empty()) break;
103 
104         // 分离通道
105         split(src, spl);
106         
107         // 将不符合选择的颜色通道都置零处理
108         for (int i = 0; i < 3; ++i)
109             if (i != channel)
110                 spl[i] = Mat::zeros(S, spl[0].type());
111 
112         // 合并通道
113         merge(spl, res);
114 
115         outputVideo << res;
116     }
117 
118     cout << "Finished writing" << endl;
119     return 0;
120 }

 

运行【CV.exe Video.avi R N】结果:

 

运行【CV.exe Video.avi R Y】结果:对于给出的报错说文件名有误实在没有头绪,就懒得继续深究了。

 

 

 上述的注释基本解释了每行代码的作用,现在总结下运行逻辑:

上述代码功能——通过选择不同的颜色通道,将输入视频另存为选择好的单一颜色通道的视频文件。

1、判断命令行启动参数个数是否正确;

2、获取输入视频文件的首帧编码格式、视频文件尺寸;

3、通过输入参数中的【R | G | B】的选择定义输出视频文件名;

4、创建输出类对象,并通过输入参数中的最后一个来确定编码类型;

5、将输入文件根据选择好的颜色通道进行分离置零再合并,然后循环写入输出文件;

注:split对帧进行分离后,得到的三通道顺序是BGR,这就是为什么 ‘R’ 对应的是 channel[2]。

标签:视频,示例,get,4.9,char,spl,ex,samples,inputVideo
From: https://www.cnblogs.com/vangoghpeng/p/18066845

相关文章

  • 项目示例 - 3.服务网关 - 3.Gateway
    项目示例-3.服务网关-3.Gateway关联知识:分布式微服务-3.服务网关-4.Gateway内容提要:基本使用自定义断言自定义局部、全局过滤器基本使用建Module:微服务起名为gateway-server改pom:引入以下依赖<dependencies><!--gateway--><dependency......
  • 痞子衡嵌入式:使用恩智浦GUI Guider快速创建全新LCD屏示例工程的步骤
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是使用恩智浦GUIGuider快速创建全新LCD屏示例工程的步骤。在痞子衡旧文《在i.MXRT1170上快速点亮一款全新LCD屏的方法与步骤》里,痞子衡介绍了在官方SDK裸机驱动elcdif示例工程基础上做修改以支持一款......
  • 淘宝京东1688...按关键词搜索商品数据,商品详情数据(属性详情图,价格,sku等)批量采集,请求示
    在淘宝、京东、1688等电商平台上,按关键词搜索商品数据以及批量采集商品详情数据(如属性详情图、价格、SKU等)通常涉及到使用平台的API接口。以下是一个简化的请求示例说明,以帮助您理解这个过程。请求示例,API接口接入Anzexi581.了解API接口API接口是一种允许不同软件应用程序......
  • springboot的代理模式示例----面向切面编程
    1.定义切面类 2.编写切面类importcom.alibaba.fastjson.JSON;importcom.fasterxml.jackson.databind.ObjectMapper;importcom.xlkh.bigscreen.common.utils.RedisDeviceUtil;importcom.xlkh.bigscreen.service.bigscreen.BigscreenRedisService;importcom.xlkh.bigs......
  • 20个Python random模块的代码示例
    本文分享自华为云社区《Python随机数探秘:深入解析random模块的神奇之处》,作者:柠檬味拥抱。标准库random函数大全:探索Python中的随机数生成随机数在计算机科学和数据科学领域中扮演着重要角色,Python的标准库中提供了random模块,用于生成各种随机数。本篇博客将深入探讨random模块......
  • onnx导出BERT示例
    onnx导出BERT示例目录onnx导出BERT示例BERT模型导出加载模型pt模型推理重新导出config导出onnx模型加载onnx测试参考资料BERT模型导出1.基于transformers载入PyTorch模型2.创建伪输入(dummyinputs),并利用伪输入在模型中前向inference,推理网络并在这个过程中追踪记录操作集合......
  • Seatunnel系列之:Apache Iceberg sink connector和往Iceberg同步数据任务示例
    Seatunnel系列之:ApacheIcebergsinkconnector和往Iceberg同步数据任务示例一、支持的Iceberg版本二、支持的引擎三、描述四、支持的数据源信息五、数据库依赖六、数据类型映射七、Sink选项八、往Iceberg同步数据任务示例一、支持的Iceberg版本1.4.2二......
  • ER图如何画?如何根据ER图转换成表结构?示例:图书管理系统ER图
    原文链接:https://blog.csdn.net/m0_61902905/article/details/131472145   ......
  • 三、MyBatis基础配置之映射文件Mapper.xml(均为单表查询示例)
    一)动态if需求:多条件组合查询。  二)动态foreach需求:多值查询。  三)动态抽取......
  • elasticsearch常用请求接口Rest API示例
    创建shopping索引PUT/shopping查看全部索引GET/_cat/indices查看指定索引GET/shopping删除指定索引DELETE/shopping索引的映射字段属性,是否关键字和加入索引PUT/shopping/_mapping{"properties":{"title":{"type":"text"},&qu......