Opencv将序列图片保存成avi视频
简介
Opencv是一个强大的计算机视觉库,它能将yuv图片转换为png/jpg等图片,同时它也能将一系列的png/jpg图片保存成avi格式的视频。注意:Opencv仅支持avi格式,且生成的视频文件不能大于2GB,且不能添加音频。如果想保存更多的视频格式或在视频文件中添加音频,需要使用更强大的多媒体开发工具FFmpeg。
示例代码
Opencv写avi视频具体举例如下:
#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { Mat src; char image_name[50]; int isColor = 1; int fps = 30; int frameWidth = 1260; int frameHeight = 680; VideoWriter writer("test.avi", VideoWriter::fourcc('M','J','P','G'), fps, Size(frameWidth, frameHeight), isColor); //VideoWriter writer("test.wav", VideoWriter::fourcc('I','2','6','3'), fps, Size(frameWidth, frameHeight), isColor); for (int i = 1; i < 369; i++) { sprintf(image_name, "./pic/pic_0/t-0_v0-1260x680_%d.png", i); src = imread(image_name, 1); if (src.empty()) { cout << "error in read pic" << endl; return -1; } writer.write(src); } }
核心函数分析
VideoWrite是写视频所用的类,其构造函数对应参数分析如下:
VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true)
- 函数参数:
- filename:输出视频文件名
- fourcc:四个字符用来表示压缩帧的编解码方式,对应编码方式主要有:
- CV_FOURCC(‘P’, ‘I’, ‘M’, ‘1’) = MPEG-1 codec
- CV_FOURCC(‘M’, ‘J’, ‘P’, ‘G’) = motion-jpeg codec
- CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) = MPEG-4.2 codec
- CV_FOURCC(‘D’, ‘I’, ‘V’, ‘3’) = MPEG-4.3 codec
- CV_FOURCC(‘D’, ‘I’, ‘V’, ‘X’) = MPEG-4 codec
- CV_FOURCC(‘U’, ‘2’, ‘6’, ‘3’) = H263 codec
- CV_FOURCC(‘I’, ‘2’, ‘6’, ‘3’) = H263I codec
- CV_FOURCC(‘F’, ‘L’, ‘V’, ‘1’) = FLV1 codec
- fps:帧率
- frameSize:每帧图片大小
- isColor:非0位彩色,0位黑白色
- 函数参数:
源码分析
Opencv写视频,其内部实现也是利用ffmpeg库实现的。具体序列图片写视频主要用的类为VideoWrite类,其内部实现相关代码如下:
// 初始化过程 // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap.cpp VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor) { open(filename, fourcc, fps, frameSize, isColor); } // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap.cpp bool VideoWriter::open(const string& filename, int fourcc, double fps, Size frameSize, bool isColor) { writer = cvCreateVideoWriter(filename.c_str(), fourcc, fps, frameSize, isColor); return isOpened(); } // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap.cpp CV_IMPL CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frameSize, int is_color ) { //CV_FUNCNAME( "cvCreateVideoWriter" ); CvVideoWriter *result = 0; if(!fourcc || !fps) result = cvCreateVideoWriter_Images(filename); #ifdef HAVE_FFMPEG if(!result) result = cvCreateVideoWriter_FFMPEG_proxy (filename, fourcc, fps, frameSize, is_color); #endif #ifdef HAVE_VFW if(!result) result = cvCreateVideoWriter_VFW(filename, fourcc, fps, frameSize, is_color); #endif #ifdef HAVE_MSMF if (!result) result = cvCreateVideoWriter_MSMF(filename, fourcc, fps, frameSize, is_color); #endif /* #ifdef HAVE_XINE if(!result) result = cvCreateVideoWriter_XINE(filename, fourcc, fps, frameSize, is_color); #endif */ #ifdef HAVE_AVFOUNDATION if (! result) result = cvCreateVideoWriter_AVFoundation(filename, fourcc, fps, frameSize, is_color); #endif #if defined(HAVE_QUICKTIME) || defined(HAVE_QTKIT) if(!result) result = cvCreateVideoWriter_QT(filename, fourcc, fps, frameSize, is_color); #endif #ifdef HAVE_GSTREAMER if (! result) result = cvCreateVideoWriter_GStreamer(filename, fourcc, fps, frameSize, is_color); #endif #if !defined(HAVE_FFMPEG) && \ !defined(HAVE_VFW) && \ !defined(HAVE_MSMF) && \ !defined(HAVE_AVFOUNDATION) && \ !defined(HAVE_QUICKTIME) && \ !defined(HAVE_QTKIT) && \ !defined(HAVE_GSTREAMER) // If none of the writers is used // these statements suppress 'unused parameter' warnings. (void)frameSize; (void)is_color; #endif if(!result) result = cvCreateVideoWriter_Images(filename); return result; } // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap_ffmpeg.cpp CvVideoWriter* cvCreateVideoWriter_FFMPEG_proxy( const char* filename, int fourcc, double fps, CvSize frameSize, int isColor ) { CvVideoWriter_FFMPEG_proxy* result = new CvVideoWriter_FFMPEG_proxy; if( result->open( filename, fourcc, fps, frameSize, isColor != 0 )) return result; delete result; return 0; } // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap_ffmpeg.cpp virtual bool open( const char* filename, int fourcc, double fps, CvSize frameSize, bool isColor ) { icvInitFFMPEG::Init(); close(); if( !icvCreateVideoWriter_FFMPEG_p ) return false; ffmpegWriter = icvCreateVideoWriter_FFMPEG_p( filename, fourcc, fps, frameSize.width, frameSize.height, isColor ); return ffmpegWriter != 0; } Witer过程 // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap.cpp void VideoWriter::write(const Mat& image) { IplImage _img = image; cvWriteFrame(writer, &_img); } // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap.cpp CV_IMPL int cvWriteFrame( CvVideoWriter* writer, const IplImage* image ) { return writer ? writer->writeFrame(image) : 0; } // d:\Program Files\OpenCV2\opencv\sources\modules\highgui\src\cap_ffmpeg.cpp virtual bool writeFrame( const IplImage* image ) { if(!ffmpegWriter) return false; CV_Assert(image->depth == 8); return icvWriteFrame_FFMPEG_p(ffmpegWriter, (const uchar*)image->imageData, image->widthStep, image->width, image->height, image->nChannels, image->origin) !=0; }