支持opencv的Mat图像采用x264等编码器编码的类
来源:互联网 发布:hydra windows版使用 编辑:程序博客网 时间:2024/04/29 04:41
虽然在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的问题,其他格式播放过快)。
贴出部分代码:
#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一样是线程安全的,如果希望线程安全需要自己改写!
- 支持opencv的Mat图像采用x264等编码器编码的类
- 支持将opencv的Mat图像采用x264等编码器编码的类
- x264编码器的参数设置。
- x264编码器的参数设置。
- x264编码器的参数设置
- x264编码器的参数设置
- x264编码器的参数设置
- x264编码器的参数设置
- x264编码器的参数设置。
- x264编码器的参数设置
- x264编码器的参数设置。
- x264编码器的参数设置
- X264编码器的参数设置
- x264编码器的参数设置。
- opencv Mat - 图像的容器
- 编码器的参数设定 X264
- ffmpeg使用x264编码的配置+ ffmpeg与 x264编码器参数完整对照表
- ffmpeg使用x264编码的配置+ ffmpeg与 x264编码器参数完整对照表
- #if 与#endif
- 计算广告中的名词解释
- 7.5.实验 解题参考
- 配置sonar、jenkins进行持续审查
- 论代码稳定
- 支持opencv的Mat图像采用x264等编码器编码的类
- C#学习篇(三)C#关键字this和base
- OpenJudge百炼 1321 棋盘问题
- Jsoup的简单使用
- 转自郭霖大神的反编译
- VS2012C++学习笔记2(第3-6章)
- zabbix 监控windows 性能计数器中的值
- TYVJ1403(NOIP2010提高组T3)关押罪犯
- RecyclerView实现填加头部