支持opencv的Mat图像采用x264等编码器编码的类
2016-07-05 15:27
357 查看
虽然在opencv中提供了videoWriter类可以将opencv图像编码成视频,但是由于自带的videoWriter支持的格式都是未经压缩的,具体参考如下:
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
对于视觉开发末期经常需要将处理过后的视频压缩存储,此时就需要借助一些特定编码器完成,opencv中视频支持相关的都是采用ffmpeg完成的,而原本的opencv中并不支持所有的ffmpeg功能。所以一种方案是自己编译opencv + ffmpeg,另一种就是自己使用对应编码器完成编码。
本文采用第二种方法,通过参考雷霄骅大神的代码,自己封装了一个可供opencv调用的视频编码类(videoEncode),类的接口和opencv的videoWriter比较类似,可以调用各种编码器直接将Mat数据压缩成avi封装格式的视频(理论上是可以各种封装格式的,无奈没有解决pts和dts的问题,其他格式播放过快)。
贴出部分代码:
完整工程(Qt工程,vs可以自己选取c文件和h,hpp文件建立):
videoEncoder
对于封装成其他格式如MP4,flv,mkv时出现播放过快的问题没有解决,希望知道的大神给与指点!同时该类并不是和opencv自带的videoWriter一样是线程安全的,如果希望线程安全需要自己改写!
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
对于视觉开发末期经常需要将处理过后的视频压缩存储,此时就需要借助一些特定编码器完成,opencv中视频支持相关的都是采用ffmpeg完成的,而原本的opencv中并不支持所有的ffmpeg功能。所以一种方案是自己编译opencv + ffmpeg,另一种就是自己使用对应编码器完成编码。
本文采用第二种方法,通过参考雷霄骅大神的代码,自己封装了一个可供opencv调用的视频编码类(videoEncode),类的接口和opencv的videoWriter比较类似,可以调用各种编码器直接将Mat数据压缩成avi封装格式的视频(理论上是可以各种封装格式的,无奈没有解决pts和dts的问题,其他格式播放过快)。
贴出部分代码:
#ifndef VIDEOENCODER_H #define VIDEOENCODER_H #include <iostream> #include <string> #include <strstream> #include <opencv.hpp> #include "ffCodecs.hpp" extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" #include "libavutil/opt.h" } using namespace std; using namespace cv; typedef unsigned long long uInt64;
class videoEncoder { public: videoEncoder(); videoEncoder(std::string filename, int codecID, double frameRate, int imgWidth, int imgHeight); //编码器和输出文件名 ~videoEncoder(); bool isOpened(); //编码器是否已经打开 bool open(std::string filename, int codecID, double frameRate, int imgWidth, int imgHeight); //打开编码器 void setParam(int codecID, double frameRate, int imgWidth, int imgHeight); //设置参数 void setBitrateControl(std::string controlMode, int bpsValue); //码流控制方式及大小 void close(); //关闭编码器 bool write(const Mat &frame); //写视频 protected: void init(); bool allocParamMem(); //为编码器参数分配空间 std::string int2String(int interger); int flushEncoder(AVFormatContext *fmt_ctx,unsigned int stream_index); //清空编码器的缓冲区 //设置编码器 int setCodec(char codec[4]); private: AVFormatContext* pFormatCtx; // AVOutputFormat* fmt; AVStream* video_st; AVCodecContext* pCodecCtx; AVCodec* pCodec; //编码器格式,可自主指定,默认由封装格式后缀名决定 AVPacket pkt; //视频帧packet //uint8_t* picture_buf; //图像buffer unsigned char* picture_buf; //图像buffer AVFrame* picture; int size; int y_size; //帧大小 int bpsValue; //码流控制方式的对应值 int bpsMode; //码流控制方式,0表示平均码率(abr),1表示固定码率(crf),2表示固定质量(cqp) cv::Mat image; //opencv中传来待编码的帧 int img_width; //帧宽 int img_height; //帧高 std::string outputFileName; //输出文件名,由后缀决定封装格式 int fourcc; //编码器的四字节码 double fps; //帧率 uInt64 frameIndex; //当前帧序号 bool isSetEncoderFlag; //是否自设定编码器 bool isOpenedFlag; //编码器是否已经打开 }; #endif // VIDEOENCODER_H
<pre name="code" class="cpp">//写视频帧 bool videoEncoder::write(const cv::Mat& frame) { cv::Mat temp; cvtColor(frame,temp,COLOR_BGR2YUV_I420); picture_buf = temp.data; picture->data[0] = picture_buf; //Y picture->data[1] = picture_buf+y_size; //U picture->data[2] = picture_buf+(y_size*5/4);//V picture->pts = frameIndex++; int got_picture = 0; int ret = avcodec_encode_video2(pCodecCtx,&pkt,picture,&got_picture); if(ret<0) { printf("encode error!\n"); return false; } if(got_picture==1) { pkt.stream_index = video_st->index; printf("pkt_pts:%d dts:%d\n",pkt.pts,pkt.dts); //ret = av_write_frame(pFormatCtx, &pkt); ret = av_interleaved_write_frame(pFormatCtx,&pkt); av_free_packet(&pkt); } return true; }
完整工程(Qt工程,vs可以自己选取c文件和h,hpp文件建立):
videoEncoder
对于封装成其他格式如MP4,flv,mkv时出现播放过快的问题没有解决,希望知道的大神给与指点!同时该类并不是和opencv自带的videoWriter一样是线程安全的,如果希望线程安全需要自己改写!
相关文章推荐
- python中使用OpenCV进行人脸检测的例子
- opencv 做人脸识别 opencv 人脸匹配分析
- 使用opencv拉伸图像扩大分辨率示例
- Android Studio中配置OpenCV库开发环境的教程
- 基于C++实现kinect+opencv 获取深度及彩色数据
- visual studio 2012安装配置方法图文教程 附opencv配置教程
- OpenCV 2.4.3 C++ 平滑处理分析
- Python中使用OpenCV库来进行简单的气象学遥感影像计算
- 利用Python和OpenCV库将URL转换为OpenCV格式的方法
- python结合opencv实现人脸检测与跟踪
- Python环境搭建之OpenCV的步骤方法
- Python+Opencv识别两张相似图片
- Python实现OpenCV的安装与使用示例
- 在树莓派2或树莓派B+上安装Python和OpenCV的教程
- opencv-python学习一--人脸检测
- 在Ubuntu上安装OpenCV3.0和Python-openCV的经历
- 使用 Java 开发 OpenCV 应用
- OpenCV配置,从来没有这么简单!
- ubuntu下opencv和qt的安装配置
- visual studio 2012安装配置方法图文教程 附opencv配置教程