【opencv】教程代码 —videoio(3)读取输入的视频文件,提取出R、G或B颜色通道,并将结果写入新的视频文件...

cpp 复制代码
#include <iostream>  // 引入标准输入输出流库,用于输入输出
#include <string>   // 引入字符串库


#include <opencv2/core.hpp>     // 引入OpenCV基础结构(cv::Mat等)
#include <opencv2/videoio.hpp>  // 引入OpenCV视频读写


using namespace std; // 使用标准命名空间std
using namespace cv;  // 使用OpenCV命名空间cv


// 帮助函数,用于显示程序的使用说明
static void help()
{
    cout
        << "------------------------------------------------------------------------------" << endl
        << "This program shows how to write video files."                                   << endl
        << "You can extract the R or G or B color channel of the input video."              << endl
        << "Usage:"                                                                         << endl
        << "./video-write <input_video_name> [ R | G | B] [Y | N]"                          << endl
        << "------------------------------------------------------------------------------" << endl
        << endl;
}


// 主函数入口
int main(int argc, char *argv[])
{
    help(); // 调用帮助函数


    // 检查参数数量是否正确
    if (argc != 4)
    {
        cout << "Not enough parameters" << endl;
        return -1;
    }


    const string source      = argv[1];           // 命令行参数1:输入视频文件名
    const bool askOutputType = argv[3][0] =='Y';  // 命令行参数3:是否询问输出视频的类型(编码格式)


    VideoCapture inputVideo(source);              // 打开输入视频
    if (!inputVideo.isOpened())
    {
        cout  << "Could not open the input video: " << source << endl;
        return -1;
    }


    // 查找视频文件名中的扩展名位置
    string::size_type pAt = source.find_last_of('.');                  
    const string NAME = source.substr(0, pAt) + argv[2][0] + ".mp4";  //avi 生成新的视频文件名


    // 获取输入视频的编码格式
    int ex = static_cast<int>(inputVideo.get(CAP_PROP_FOURCC));     


    // 通过位运算将编码格式从int转换成字符形式
    char EXT[] = {(char)(ex & 0XFF) , (char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24), 0};


    // 获取输入视频的尺寸
    Size S = Size((int) inputVideo.get(CAP_PROP_FRAME_WIDTH),    // 宽
                  (int) inputVideo.get(CAP_PROP_FRAME_HEIGHT));  // 高


    VideoWriter outputVideo;                                    // 创建视频写入对象
    if (askOutputType)
        outputVideo.open(NAME, ex=-1, inputVideo.get(CAP_PROP_FPS), S, true);
    else
        outputVideo.open(NAME, ex, inputVideo.get(CAP_PROP_FPS), S, true);


    // 打开输出视频
    if (!outputVideo.isOpened())
    {
        cout  << "Could not open the output video for write: " << source << endl;
        return -1;
    }


    // 显示输入视频的相关信息
    cout << "Input frame resolution: Width=" << S.width << "  Height=" << S.height
         << " of nr#: " << inputVideo.get(CAP_PROP_FRAME_COUNT) << endl;
    cout << "Input codec type: " << EXT << endl;


    // 选择要保存的颜色通道
    int channel = 2; // 默认选择蓝色通道
    switch(argv[2][0])
    {
      case 'R' : channel = 2; break;
      case 'G' : channel = 1; break;
      case 'B' : channel = 0; break;
    }
    
    // 创建相关的Mat对象
    Mat src, res;
    vector<Mat> spl;


    // 无限循环,直到视频读取完毕
    for(;;)
    {
        inputVideo >> src;              // 读取视频帧
        if (src.empty()) break;         // 如果读取到空帧,则停止


        split(src, spl);                // 处理视频帧,分离色彩通道
        for (int i =0; i < 3; ++i)
            if (i != channel)
                spl[i] = Mat::zeros(S, spl[0].type()); // 将非选定通道置零
        merge(spl, res); // 合并通道


        outputVideo << res; // 将处理后的帧写入输出视频
    }


    cout << "Finished writing" << endl; // 写入完成
    return 0;
}

这段代码是一个C++程序,使用OpenCV库来处理视频文件。具体功能如下:

  1. 程序读取一个输入视频,并允许用户选择摘取红(R)、绿(G)或蓝(B)色彩通道。

  2. 用户可以选择是否询问输出视频的编码格式

  3. 如果输入视频成功打开,程序会通过用户选择提取特定的颜色通道,并将这些帧写入到一个新的视频文件中。

  4. 程序最终输出一个只包含选定颜色通道的视频文件。

char EXT[] = {(char)(ex & 0XFF) , (char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24), 0};

outputVideo.open(NAME, ex=-1, inputVideo.get(CAP_PROP_FPS), S, true);

./test.exe baseDraw.mp4 R Y 运行示例

报错:[ERROR:0@1.220] global cap.cpp:645 cv::VideoWriter::open VIDEOIO(CV_IMAGES): raised OpenCV exception:

split(src, spl);

Mat::zeros(S, spl[0].type())

merge(spl, res);

相关推荐
中关村科金5 分钟前
中关村科金智能客服机器人如何解决客户个性化需求与标准化服务之间的矛盾?
人工智能·机器人·在线客服·智能客服机器人·中关村科金
逸_8 分钟前
Product Hunt 今日热榜 | 2024-12-25
人工智能
Luke Ewin14 分钟前
基于3D-Speaker进行区分说话人项目搭建过程报错记录 | 通话录音说话人区分以及语音识别 | 声纹识别以及语音识别 | pyannote-audio
人工智能·语音识别·声纹识别·通话录音区分说话人
DashVector29 分钟前
如何通过HTTP API检索Doc
数据库·人工智能·http·阿里云·数据库开发·向量检索
说私域32 分钟前
无人零售及开源 AI 智能名片 S2B2C 商城小程序的深度剖析
人工智能·小程序·零售
Calvin88082841 分钟前
Android Studio 的革命性更新:Project Quartz 和 Gemini,开启 AI 开发新时代!
android·人工智能·android studio
西西弗Sisyphus1 小时前
基于推理的目标检测 DetGPT
目标检测·计算机视觉
Jamence1 小时前
【深度学习数学知识】-贝叶斯公式
人工智能·深度学习·概率论
feifeikon1 小时前
机器学习DAY4续:梯度提升与 XGBoost (完)
人工智能·深度学习·机器学习
凡人的AI工具箱2 小时前
每天40分玩转Django:实操多语言博客
人工智能·后端·python·django·sqlite