OPENCV2.4学习笔记——用OpenCv创建视频

来源:互联网 发布:pureftpd mac 安装 编辑:程序博客网 时间:2024/04/30 18:15

视频文件的结构:

   每一个视频文件本质上都是一个容器,文件的扩展名只是表示容器格式(例如avi , mov ,或者 mkv )而不是视频和音频的压缩格式

   容器里可能会有很多元素,例如视频流音频流和一些字幕流等等。这些流的储存方式是由每一个流对应的编解码器(codec)决定的。通常来说,音频流很可能使用mp3 或 aac 格式来储存。而视频格式就更多些,通常是 XVID , DIVX , H264 或 LAGS (Lagarith Lossless Codec)等等。

 

        如你所见,视频文件确实比图像文件要复杂很多。然而OpenCV只是个计算机视觉库而不是一个视频处理编码库。所以开发者们试图将这个部分尽可能地精简,结果就是OpenCV能够处理的视频只剩下avi 扩展名的了。另外一个限制就是你不能创建超过2GB的单个视频,还有就是每个文件里只能支持一个视频流,不能将音频流和字幕流等其他数据放在里面。尽管如此,任何系统支持的编解码器在这里应该都能工作。如果这些视频处理能力不够你使用的话,我想你应该去找一些专门处理视频的库例如FFMpeg 或者更多的编解码器例如 HuffYUVCorePNGLCL 。你可以先用OpenCV创建一个原始的视频流然后通过其他编解码器转换成其他格式并用VirtualDubAviSynth 这样的软件去创建各种格式的视频文件

    视频文件比图像文件要复杂很多。然而OpenCV只是个计算机视觉库而不是一个视频处理编码库。所以开发者们试图将这个部分尽可能地精简,结果就是OpenCV能够处理的视频只剩下 avi 扩展名的了。

    另外一个限制就是不能创建超过2GB的单个视频,还有就是每个文件里只能支持一个视频流,不能将音频流和字幕流等其他数据放在里面。

 

关于视频编解码器:

    编码解码器的主要作用是对视频信号进行压缩和解压缩。计算机工业定义通过24位测量系统的真彩色,这就定义了百万种颜色,接近人类视觉的极限。现在,最基本的VGA显示器就有640×480像素。这意味着如果视频需要以每秒30帧的速度播放,则每秒要传输高达27MB的信息。在如此速度下,1GB容量的硬盘仅能存储约37秒的视频信息。因而必须对信息进行压缩处理。通过抛弃一些数字信息或精选出容易被我们的眼睛和大脑常忽略的可视化信息的方法,使视频消耗的硬盘容量减小。这个视频压缩过程就是编码解码器。编码解码器的压缩率从一般的2:1~100:1不等,使处理大量的视频数据成为可能。

    如果是用在数字多媒体上,解码器则包括视频解码器和音频解码器.数字媒体的图象和声音都使用特殊的软件编码格式,像视频的mpeg4,音频的mp3,ac3,dts等,这些编码器可以将原始数据压缩存放,刚才都是常用的编码格式,还有些专业的编码格式,一般家庭基本不会用到。为了在家用设备或者电脑上重放这些视频和音频则需要用到解码软件,一般称为插件。比如mpeg4解码插件ffdshow,ac3解码插件ac3fliter等。只有装了各种解码插件你的电脑才能重放这些图像和声音。

 

用OpenCv创建视频:

1.其操作在 VideoWriter 类中,open 函数来打开,write 函数向这个对象按照序列发送一些图像帧。

2.下面的程序代码做的工作主要有这几样:

    (1):创建一个视频文件

    (2):获取视频的解码器

     编解码器,现在所有的视频编解码器都使用最多四个字节的名称来标识,例如 XVID, DIVX, 和 H264 等。这个被称作FourCC(four character code)。你可以通过 get 函数来向视频询问这个编码,get 函数会返回一个double数,仅仅是因为double包含了64位数据而已,由于FourCC编码只占据了其中低位的4个字节,所以可以直接通过强制转换成int型来扔掉高位的四个字节。详细代码见下面的程序。

    (3): 释放视频文件当中的某个颜色通道

 

源代码:

#include <iostream>

#include <string>  


#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace  std;
using namespace cv;
int main(int argc,char *argv[],char *window_name)
{
   //读取视频
 const string source = "Global.avi";
 VideoCapture inputVideo(source);

 //判断是否读取成功
 if (!inputVideo.isOpened())
 {
  cout<<"could not open the video"<<endl;
  return -1;

 }

 string::size_type pAt = source.find_last_of('.');

 char channelNum;
 cout<<"Please input the number of channel you want to release(R,G,B):";
 cin>>channelNum;
 const string NAME = source.substr(0,pAt) + channelNum + ".avi";
 int ex = static_cast<int>(inputVideo.get(CV_CAP_PROP_FOURCC));

 char EXT[] = {ex & 0XFF,(ex & 0XFF00)>>8,(ex & 0XFF0000) >> 16,(ex & 0XFF000000) >> 24,0};
 Size S = Size((int)inputVideo.get(CV_CAP_PROP_FRAME_WIDTH),(int) inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT));  

 char choice;
 cout<<"Please input yes 'Y' or no 'N'(N:使用视频输入格式来创建输出文件,Y:弹出一个对话框来让你选择编码器。):"<<endl;
 cin>>choice;
 const bool askOutputType = choice =='Y';

 VideoWriter outputVideo;

 if (askOutputType)
 {
  outputVideo.open(NAME,ex = -1,inputVideo.get(CV_CAP_PROP_FPS),S,true);
 }
 else
  outputVideo.open(NAME , ex, inputVideo.get(CV_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(CV_CAP_PROP_FRAME_COUNT) << endl;


 //输出编码器类型
 cout << "Input codec type: " << EXT << endl;

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

 Mat src,res;
 vector<Mat> spl;

 while(true)
 {
  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;
}

 运行结果:

原创粉丝点击