opencv 保存视频VideoWrite
2015-12-06 18:43
323 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。
尽早过来学习了一下opencv中如何写入视频,顿时发现Opencv太强大了 !!!!
你可能已经不满足于读取视频,还想要将你产生的一系列结果保存到一个新建的视频文件中。使用OpenCV中的
VideoWriter 类就可以简单的完成创建视频的工作。在接下来的教程中,我们将告诉你:
如何用OpenCV创建一个视频文件
用OpenCV能创建什么样的视频文件
如何释放视频文件当中的某个颜色通道
为了使例子简单,我就仅仅释放原始视频RGB通道中的一个,并把它放入新视频文件中。你可以使用命令行参数来控制程序的一些行为:
第一个参数指向你需要操作的视频文件。
第二个参数可以是如下的几个字母之一:R G B。用来指定你需要释放哪一个通道。
首先,你需要知道一个视频文件是什么样子的。每一个视频文件本质上都是一个容器,文件的扩展名只是表示容器格式(例如
avi ,
mov ,或者mkv )而不是视频和音频的压缩格式。容器里可能会有很多元素,例如视频流,音频流和一些字幕流等等。这些流的储存方式是由每一个流对应的编解码器(codec)决定的。通常来说,视频流很可能使用mp3
或 aac 格式来储存。而视频格式就更多些,通常是
XVID ,
DIVX ,
H264 或
LAGS (Lagarith Lossless Codec)等等。具体你能够使用的编码器种类可以在操作系统的编解码器列表里找到
如你所见,视频文件确实比图像文件要复杂很多。然而OpenCV只是个计算机视觉库而不是一个视频处理编码库。所以开发者们试图将这个部分尽可能地精简,结果就是OpenCV能够处理的视频只剩下avi 扩展名的了。另外一个限制就是你不能创建超过2GB的单个视频,还有就是每个文件里只能支持一个视频流,不能将音频流和字幕流等其他数据放在里面。尽管如此,任何系统支持的编解码器在这里应该都能工作。如果这些视频处理能力不够你使用的话,我想你应该去找一些专门处理视频的库例如FFMpeg
或者更多的编解码器例如 HuffYUV ,
CorePNG 和
LCL 。你可以先用OpenCV创建一个原始的视频流然后通过其他编解码器转换成其他格式并用VirtualDub 和
AviSynth 这样的软件去创建各种格式的视频文件
好了 上代码啦 :
[cpp]
view plaincopyprint?
int main()
{
const string source="e:\\kankan\\1.avi";
VideoCapture cap(source);
const bool askOutputType = true;
if(!cap.isOpened())
{
cout<<"could not open the video"<<endl; }
string ::size_type pAt=source.find_last_of('.');
const string NAME=source.substr(0,pAt)+'r'+".avi";
int ex=static_cast<int>(cap.get(CV_CAP_PROP_FOURCC));
char EXT[] = {ex & 0XFF , (ex & 0XFF00) >> 8,(ex & 0XFF0000) >> 16,(ex & 0XFF000000) >> 24, 0};
Size S=Size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH),
(int)cap.get(CV_CAP_PROP_FRAME_HEIGHT) );
VideoWriter outputVideo; // Open the output
if (askOutputType)
outputVideo.open(NAME , ex=-1, cap.get(CV_CAP_PROP_FPS),S, true);
else
outputVideo.open(NAME , ex, cap.get(CV_CAP_PROP_FPS),S, true);
union { int v; char c[5];} uEx ;
uEx.v = ex; // From Int to char via union
uEx.c[4]='\0';
cout << "Input frame resolution: Width=" << S.width << " Height=" << S.height
<< " of nr#: " << cap.get(CV_CAP_PROP_FRAME_COUNT) << endl;
cout << "Input codec type: " << EXT << endl;
int channel=2;
Mat frame;
Mat res;
vector<Mat>spl;
while(true)
{
cap>>frame;
if(frame.empty())
{
cout<<"over"<<endl;
break;
}
split(frame,spl);
for(int i=0;i<3;++i)
{
if(i!=channel)
spl[i]=Mat::zeros(frame.size(),spl[0].type());
merge(spl,res);
imshow("r",res);
outputVideo << res;
}
}
waitKey(33);
return 0;
}
我选择的是R通道。效果图如下:
![](http://img.my.csdn.net/uploads/201210/13/1350093632_6572.png)
部分代码:
[cpp]
view plaincopyprint?
split(src, spl); // 分离三个通道
for( int i =0; i < 3; ++i)
if (i != channel)
spl[i] = Mat::zeros(S, spl[0].type()); //创建相同大小的黑色图像
merge(spl, res); //重新合并
尽早过来学习了一下opencv中如何写入视频,顿时发现Opencv太强大了 !!!!
你可能已经不满足于读取视频,还想要将你产生的一系列结果保存到一个新建的视频文件中。使用OpenCV中的
VideoWriter 类就可以简单的完成创建视频的工作。在接下来的教程中,我们将告诉你:
如何用OpenCV创建一个视频文件
用OpenCV能创建什么样的视频文件
如何释放视频文件当中的某个颜色通道
为了使例子简单,我就仅仅释放原始视频RGB通道中的一个,并把它放入新视频文件中。你可以使用命令行参数来控制程序的一些行为:
第一个参数指向你需要操作的视频文件。
第二个参数可以是如下的几个字母之一:R G B。用来指定你需要释放哪一个通道。
首先,你需要知道一个视频文件是什么样子的。每一个视频文件本质上都是一个容器,文件的扩展名只是表示容器格式(例如
avi ,
mov ,或者mkv )而不是视频和音频的压缩格式。容器里可能会有很多元素,例如视频流,音频流和一些字幕流等等。这些流的储存方式是由每一个流对应的编解码器(codec)决定的。通常来说,视频流很可能使用mp3
或 aac 格式来储存。而视频格式就更多些,通常是
XVID ,
DIVX ,
H264 或
LAGS (Lagarith Lossless Codec)等等。具体你能够使用的编码器种类可以在操作系统的编解码器列表里找到
如你所见,视频文件确实比图像文件要复杂很多。然而OpenCV只是个计算机视觉库而不是一个视频处理编码库。所以开发者们试图将这个部分尽可能地精简,结果就是OpenCV能够处理的视频只剩下avi 扩展名的了。另外一个限制就是你不能创建超过2GB的单个视频,还有就是每个文件里只能支持一个视频流,不能将音频流和字幕流等其他数据放在里面。尽管如此,任何系统支持的编解码器在这里应该都能工作。如果这些视频处理能力不够你使用的话,我想你应该去找一些专门处理视频的库例如FFMpeg
或者更多的编解码器例如 HuffYUV ,
CorePNG 和
LCL 。你可以先用OpenCV创建一个原始的视频流然后通过其他编解码器转换成其他格式并用VirtualDub 和
AviSynth 这样的软件去创建各种格式的视频文件
好了 上代码啦 :
[cpp]
view plaincopyprint?
int main()
{
const string source="e:\\kankan\\1.avi";
VideoCapture cap(source);
const bool askOutputType = true;
if(!cap.isOpened())
{
cout<<"could not open the video"<<endl; }
string ::size_type pAt=source.find_last_of('.');
const string NAME=source.substr(0,pAt)+'r'+".avi";
int ex=static_cast<int>(cap.get(CV_CAP_PROP_FOURCC));
char EXT[] = {ex & 0XFF , (ex & 0XFF00) >> 8,(ex & 0XFF0000) >> 16,(ex & 0XFF000000) >> 24, 0};
Size S=Size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH),
(int)cap.get(CV_CAP_PROP_FRAME_HEIGHT) );
VideoWriter outputVideo; // Open the output
if (askOutputType)
outputVideo.open(NAME , ex=-1, cap.get(CV_CAP_PROP_FPS),S, true);
else
outputVideo.open(NAME , ex, cap.get(CV_CAP_PROP_FPS),S, true);
union { int v; char c[5];} uEx ;
uEx.v = ex; // From Int to char via union
uEx.c[4]='\0';
cout << "Input frame resolution: Width=" << S.width << " Height=" << S.height
<< " of nr#: " << cap.get(CV_CAP_PROP_FRAME_COUNT) << endl;
cout << "Input codec type: " << EXT << endl;
int channel=2;
Mat frame;
Mat res;
vector<Mat>spl;
while(true)
{
cap>>frame;
if(frame.empty())
{
cout<<"over"<<endl;
break;
}
split(frame,spl);
for(int i=0;i<3;++i)
{
if(i!=channel)
spl[i]=Mat::zeros(frame.size(),spl[0].type());
merge(spl,res);
imshow("r",res);
outputVideo << res;
}
}
waitKey(33);
return 0;
}
int main() { const string source="e:\\kankan\\1.avi"; VideoCapture cap(source); const bool askOutputType = true; if(!cap.isOpened()) { cout<<"could not open the video"<<endl; } string ::size_type pAt=source.find_last_of('.'); const string NAME=source.substr(0,pAt)+'r'+".avi"; int ex=static_cast<int>(cap.get(CV_CAP_PROP_FOURCC)); char EXT[] = {ex & 0XFF , (ex & 0XFF00) >> 8,(ex & 0XFF0000) >> 16,(ex & 0XFF000000) >> 24, 0}; Size S=Size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH), (int)cap.get(CV_CAP_PROP_FRAME_HEIGHT) ); VideoWriter outputVideo; // Open the output if (askOutputType) outputVideo.open(NAME , ex=-1, cap.get(CV_CAP_PROP_FPS),S, true); else outputVideo.open(NAME , ex, cap.get(CV_CAP_PROP_FPS),S, true); union { int v; char c[5];} uEx ; uEx.v = ex; // From Int to char via union uEx.c[4]='\0'; cout << "Input frame resolution: Width=" << S.width << " Height=" << S.height << " of nr#: " << cap.get(CV_CAP_PROP_FRAME_COUNT) << endl; cout << "Input codec type: " << EXT << endl; int channel=2; Mat frame; Mat res; vector<Mat>spl; while(true) { cap>>frame; if(frame.empty()) { cout<<"over"<<endl; break; } split(frame,spl); for(int i=0;i<3;++i) { if(i!=channel) spl[i]=Mat::zeros(frame.size(),spl[0].type()); merge(spl,res); imshow("r",res); outputVideo << res; } } waitKey(33); return 0; }
我选择的是R通道。效果图如下:
![](http://img.my.csdn.net/uploads/201210/13/1350093632_6572.png)
部分代码:
[cpp]
view plaincopyprint?
split(src, spl); // 分离三个通道
for( int i =0; i < 3; ++i)
if (i != channel)
spl[i] = Mat::zeros(S, spl[0].type()); //创建相同大小的黑色图像
merge(spl, res); //重新合并
split(src, spl); // 分离三个通道 for( int i =0; i < 3; ++i) if (i != channel) spl[i] = Mat::zeros(S, spl[0].type()); //创建相同大小的黑色图像 merge(spl, res); //重新合并
相关文章推荐
- Linux虚拟内存与交换空间机制
- CentOS编译PHP的错误信息处理
- OpenCV入门:(六:基础画图函数)
- 分享一个Openstack的社区消息获取工具
- Linux第13周学习笔记
- 解决tomcat的startup.bat开启闪退问题
- Apache mina VS Netty
- linux常用查看硬件设备信息命令
- wireshark抓取OpenFlow数据包
- 【OpenCV】边缘检测:梯度,sobel算子的理解
- Hadoop 文件的数量怎么比block的数量多?
- Linux添加硬盘与fdisk分区、mke2fs格式化分区、自动挂载
- LINUX打印
- Nginx 配置SSL访问
- linux 解决Ubuntu编译内核uImage出现问题“mkimage” command not found - U-Boot images will not be built问题
- CentOS 6.5 64 安装多个mysql 服务 -阿里云服务器ECS
- VS2010+OpenCV2.4.3配置
- MapReduce实现单表关联(微博关注推荐)
- 厚道舒适的字体 -- Adobe Source Code Pro -- 在Linux上安装以及在Emacs中的配置
- nginx学习(六) 负载均衡、反向代理、rewrite