Opencv将序列图片保存成avi视频

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;
    }
    
  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值