【OpenCV】视频制作

来源:互联网 发布:如何变文艺知乎 编辑:程序博客网 时间:2024/06/11 13:22

视频

  视频文件本身就是一个容器,包含视频feeds、音频feeds和其他轨道如字幕。视频格式有avi、mov或mkv。

  由于OpenCV提供的视频容器只能支持avi扩展,限制了保存的视频文件不能大于2 GB。当然,还可以使用其他更专业的视频编写库如HuffYUV, CorePNG and LCL。常用视频编解码器有XVID, DIVX or H264。

  本节的测试视频下载地址:https://github.com/opencv/opencv/blob/master/samples/data/Megamind.avi


代码示例

#include <iostream>#include <string>#include <opencv2/core.hpp>#include <opencv2/videoio.hpp>using namespace std;using namespace cv;int main(){    string source = "../data/Megamind.avi";    VideoCapture inputVideoB(source), inputVideoG(source), inputVideoR(source);    if (!inputVideoB.isOpened() || !inputVideoG.isOpened() || !inputVideoR.isOpened()) { return -1; }    // 四个字符的编解码器代码,get获得8字符的double,static_cast<int>    int ex = static_cast<int>(inputVideoB.get(CAP_PROP_FOURCC));    char EXT[] = { (char)(ex & 0XFF) , (char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24), 0 };    Size S = Size((int)inputVideoB.get(CAP_PROP_FRAME_WIDTH), (int)inputVideoB.get(CAP_PROP_FRAME_HEIGHT));    cout << "Input frame resolution: Width=" << S.width << "  Height=" << S.height        << " of nr#: " << inputVideoB.get(CAP_PROP_FRAME_COUNT) << endl;    cout << "Input codec type: " << EXT << endl;    Mat srcB, srcG, srcR, resB, resG, resR;    VideoWriter outputVideoB, outputVideoG, outputVideoR;    vector<Mat> spB, spG, spR;    // 查找字符串中最后一个出现的c。有匹配,则返回匹配位置;否则返回-1    string::size_type pAt = source.find_last_of('.');    string NameB = source.substr(0, pAt) + 'B' + ".avi";    string NameG = source.substr(0, pAt) + 'G' + ".avi";    string NameR = source.substr(0, pAt) + 'R' + ".avi";    bool outputType = 0;  // 若为 0 则与输入的编解码器相同    if (outputType)    {        outputVideoB.open(NameB, ex = -1, inputVideoB.get(CAP_PROP_FPS), S, true);        outputVideoG.open(NameG, ex = -1, inputVideoG.get(CAP_PROP_FPS), S, true);        outputVideoR.open(NameR, ex = -1, inputVideoR.get(CAP_PROP_FPS), S, true);    }    else    {        outputVideoB.open(NameB, ex, inputVideoB.get(CAP_PROP_FPS), S, true);        outputVideoG.open(NameG, ex, inputVideoG.get(CAP_PROP_FPS), S, true);        outputVideoR.open(NameR, ex, inputVideoR.get(CAP_PROP_FPS), S, true);    }    if (!outputVideoB.isOpened() || !outputVideoG.isOpened() || !outputVideoR.isOpened()) { return -1; }    for (;;)    {        inputVideoB >> srcB;                        // 矩阵形式读取视频        if (srcB.empty())   break;        split(srcB, spB);                           // 分离BGR三个通道        spB[1] = Mat::zeros(S, spB[1].type());        spB[2] = Mat::zeros(S, spB[2].type());        merge(spB, resB);                           // 合并BGR三个通道        outputVideoB << resB;    }       for (;;)    {        inputVideoG >> srcG;                        // 矩阵形式读取视频        if (srcG.empty())   break;        split(srcG, spG);                           // 分离BGR三个通道        spG[0] = Mat::zeros(S, spG[0].type());        spG[2] = Mat::zeros(S, spG[2].type());        merge(spG, resG);                           // 合并BGR三个通道        outputVideoG << resG;    }       for (;;)    {        inputVideoR >> srcR;                        // 矩阵形式读取视频        if (srcR.empty())   break;        split(srcR, spR);                           // 分离BGR三个通道        spR[0] = Mat::zeros(S, spR[0].type());        spR[1] = Mat::zeros(S, spR[1].type());        merge(spR, resR);                           // 合并BGR三个通道        outputVideoR << resR;    }    cout << "视频制作完成" << endl;    return 0;}

运行结果

这里写图片描述