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;
}