编解码器codec概念
如果是图像文件我们可以通过文件扩展名得知图像的格式,但是视频文件并不适用,在opencv中,都是avi视频文件,有些能用opencv打开,有些则不能。
视频的格式主要由压缩算法决定。压缩算法称之为编码器(coder),解压算法称之为解码器(decoder),编解码算法统称为编解码器(codec)。
视频文件能读或者写,关键看是否有相应的编解码器。编解码器的种类非常多,比如MJPG,XVID,DIVX等,因此视频文件的扩展名往往只能表示这是一个视频文件。
编码格式
视频容器中,一般有视频和音频数据,它们采取的编码方式不一样。
视频常见的编码方式通常有: x264、h264、mpeg-4
音频常见的编码方式通常有: mp3、AAC、flac
编码的目的主要是为了高效存储和传输,如果你不采用编码压缩的话,那么视频可以看做是一系列的图片序列,体积会非常大。
写视频
与读视频不同的是,需要在创建视频时设置一系列参数,包括文件名,编解码器,帧率,高度和宽度等。编解码器使用四个字符表示,可以是CV_FOURCC(‘M’,‘J’,‘P’,‘G’),CV_FOURCC(‘D’, ‘I’, ‘V’, ‘X’)等。
将图像写入视频可以使用VideoWriter::write(),VideoWriter类函数中也重载了<<操作符,另外需要注意的是:待写入的图像尺寸必须与创建视频时指定的尺寸一致
VideoWriter
构造函数:
VideoWriter writer(const string& filename, int fourcc, double fps,Size frameSize, bool isColor=true);
参数说明:
文件名,codec,帧率,宽和高
fourcc 表示所使用的编码方式,为四个字符用来表示压缩帧的codec
如果输入-1,会弹出一个选择对话框来选择编码器
视频编解码器,视频容器和视频文件格式之间的区别
视频文件由两部分组成:编解码器(codec)和容器( container)。
- 视频编解码器是用于对视频进行编码和解码的协议。常见的编解码器包括H.264,MPEG-4和DivX。精心设计的编解码器具有很高的效率,或者可以在减小文件大小的同时保持质量。
- 容器(文件格式,file format)是文件元数据和数据结构的定义,不包括视频的实际编码方式(编解码器确定)。容器文件保存使用编解码器编码的元数据和压缩视频数据。容器格式通常也称为“格式”,并反映在文件的扩展名中。常见的容器格式括.AVI,.MP4和.MOV。容器格式可以与不同的编解码器配对,这些编解码器会影响文件兼容的设备和程序。
目前常见的视频编解码格式如下
由于视频编码的主要任务是缩小视频文件的存储空间,因此,视频编码又称视频压缩编码或视频压缩,简单地说就是去除视频数据中的冗余信息。可以对视频或音频进行编码(encode)和解码(decode )的程序(或硬件)称为编解码器( codec)。
在图像/视频处理中通常使用的工具库有ffmpeg和opencv。
opencv 中视频流数据的编解码可以分为两个步骤:
- 使用 VideoCapture视频捕获对象,去捕获视频流, opencv会自动完成视频流的解码操作,并返回视频流的编码格式、帧率等信息。
- VideoWriter_fourcc获取对应编解码器的fourcc字节码标识符,VideoWrite 生成一个写入器
获取视频流的编码格式
参考fourcc编码规范,可以得到解码方式
def get_video_format(cap):
"""
get video format
"""
raw_codec_format = int(cap.get(cv.CAP_PROP_FOURCC))
decoded_codec_format = (chr(raw_codec_format & 0xFF), chr((raw_codec_format & 0xFF00) >> 8),
chr((raw_codec_format & 0xFF0000) >> 16), chr((raw_codec_format & 0xFF000000) >> 24))
return decoded_codec_format
参考:
- 视频的编解码格式:https://zhuanlan.zhihu.com/p/143720720
- 基于opencv实现视频流的编解码和存储:https://zhuanlan.zhihu.com/p/143993517