#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
using namespace std;
using namespace cv;
static void help()
{
cout
<< "------------------------------------------------------------------------------" << endl
<< "这个程序展示了如何编写视频文件." << endl
<< "您可以提取输入视频的 R 或 G 或 B 颜色通道." << 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]; //源文件名
const bool askOutputType = argv[3][0] =='Y'; //如果为 false,它将使用输入编解码器类型
VideoCapture inputVideo(source); // 打开输入
if (!inputVideo.isOpened())
{
cout << "无法打开输入视频: " << source << endl;
return -1;
}
string::size_type pAt = source.find_last_of('.'); // 查找扩展点 Find extension point
const string NAME = source.substr(0, pAt) + argv[2][0] + ".avi"; // 形成容器新名称
int ex = static_cast<int>(inputVideo.get(CAP_PROP_FOURCC)); //获取编码器类型 整型 Get Codec Type- Int form
// 通过位运算符从 int 转换为 char 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=-1, inputVideo.get(CAP_PROP_FPS), S, true);
else
outputVideo.open(NAME, ex, inputVideo.get(CAP_PROP_FPS), S, true);
if (!outputVideo.isOpened())
{
cout << "无法打开输出视频进行写入: " << 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(argv[2][0])
{
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());//其他通道设置为0
merge(spl, res);//混合后输出
//outputVideo.write(res); //save or
outputVideo << res;//写入视频文件
}
cout << "Finished writing" << endl;
return 0;
}
07-06
1360

01-20
09-08
419
