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库来处理视频文件。具体功能如下:
-
程序读取一个输入视频,并允许用户选择摘取红(R)、绿(G)或蓝(B)色彩通道。
-
用户可以选择是否询问输出视频的编码格式。
-
如果输入视频成功打开,程序会通过用户选择提取特定的颜色通道,并将这些帧写入到一个新的视频文件中。
-
程序最终输出一个只包含选定颜色通道的视频文件。
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);