Video Input and Output2(Creating a video with OpenCV)

Goal

Whenever you work with video feeds you may eventually want to save your image processing result in a form of a new video file. For simple video outputs you can use the OpenCV built-in cv::VideoWriter class, designed for this.想要保存图片处理的结果为一个新的视频文件。对于简单的视频输出,可以使用    OpenCV的内置函数:cv::VideoWriter。

  • How to create a video file with OpenCV
  • 如何使用OpenCV创建视频文件
  • What type of video files you can create with OpenCV
  • 什么类型的视频文件可以用OpenCV创建
  • How to extract a given color channel from a video
  • 如何从视频中提取给定的颜色通道

As a simple demonstration I'll just extract one of the BGR color channels of an input video file into a new video. You can control the flow of the application from its console line arguments:作为一个简单的演示,我将把输入视频文件的BGR一个色彩通道提取到一个新视频中。您可以从其控制台行参数中控制应用程序的流程:

  • The first argument points to the video file to work on
  • 第一个参数指向要处理的视频文件
  • The second argument may be one of the characters: R G B. This will specify which of the channels to extract.
  • 第二个参数可能是其中一个字符:R G B.这将指定要提取哪个通道。
  • The last argument is the character Y (Yes) or N (No). If this is no, the codec used for the input video file will be the same as for the output. Otherwise, a window will pop up and allow you to select yourself the codec to use.
  • 最后一个参数是字符Y(是)或N(否)。如果不是,则用于输入视频文件的编解码器将与输出相同。否则,会弹出一个窗口,让您选择要使用的编解码器。

code

#include <iostream> // for standard I/O
#include <string>   // for strings
#include <opencv2/core.hpp>     // Basic OpenCV structures (cv::Mat)

#include <opencv2/videoio.hpp>  // Video write

#include <opencv2/highgui.hpp>

using namespace std;
using namespace 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()
{
//    help();
//    if (argc != 4)
//    {
//        cout << "Not enough parameters" << endl;
//        return -1;
//    }

    const string source      = "Megamind.avi";           // the source file name
    const bool askOutputType = 'Y';  // If false it will use the inputs codec type
    VideoCapture inputVideo(source);              // Open input
    if (!inputVideo.isOpened())
    {
        cout  << "Could not open the input video: " << source << endl;
        return -1;
    }
    //找到下标
    string::size_type pAt = source.find_last_of('.');                  // Find extension point
    //新的视频
    const string NAME = source.substr(0, pAt) + 'R' + ".avi";   // Form the new name with container
    //得到4个字符的视频解码器代码

    int ex = static_cast<int>(inputVideo.get(CAP_PROP_FOURCC));     // Get Codec Type- Int form
    // Transform from int to char via Bitwise operators
    //把数字转换为字符,使用移动操作

    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),    // Acquire input size
                  (int) inputVideo.get(CAP_PROP_FRAME_HEIGHT));


    VideoWriter outputVideo;                                        // Open the output
    if (askOutputType)
        outputVideo.open(NAME, ex, inputVideo.get(CAP_PROP_FPS), S, true);
    //视频编写初始化函
    //name,视频编码,帧率,尺寸,不为零,彩色帧;否则灰色帧

    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; // Select the channel to save

    switch('R')
    {
    case 'R' : channel = 2; break;
    case 'G' : channel = 1; break;
    case 'B' : channel = 0; break;
    }

    Mat src, res;
    vector<Mat> spl;
    for(;;) //Show the image captured in the window and repeat
    {
        inputVideo >> src;              // read
        if (src.empty()) break;         // check if at end
        split(src, spl);                // process - extract only the correct channel
        for (int i =0; i < 3; ++i)
            if (i != channel)
                spl[i] = Mat::zeros(S, spl[0].type());
       merge(spl, res);
       //outputVideo.write(res); //save or
       outputVideo << res;
    }

    cout << "Finished writing" << endl;

//播放视频,自己添加的程序

int delay=100;
VideoCapture cap(NAME);
Mat frame;
for(;;)
{
    cap >> frame;
     if (frame.empty())
     {
            cout << " < < <  Game over!  > > > ";
            break;
      }
      imshow("New",frame);
     char c = (char)waitKey(delay);
            if (c == 27) break;
    }

  return 0;
}

Results

Video Input and Output2(Creating a video with OpenCV)