包含视频格式知识(编解码和封装格式);如何获取视频信息及视频编解码格式;opencv读取及保存视频,及opencv fourcc编码格式

一、基础知识

视频的编解码格式和封装格式

参考如山似水 视频编码与封装⽅式详解

参考迷之程序员 opencv视频编码格式

参考Alex Chung 视频的编解码格式 - 知乎

常⻅的AVI、RMVB、MKV、ASF、WMV、MP4、3GP、FLV等⽂件(.后缀)其实只能算是⼀种封装标准。 ⼀个完整的视频⽂件是由⾳频和视频两部分组成的,例如H264、Xvid等就是视频编码格式,MP3、AAC等就是⾳频编码格式

常⽤视频编码⽅式

Xvid(MPEG4),H264,MPEG1,MPEG2 (感兴趣的可以了解下DivX和XviD的故事,这两兄弟,前者收费,后者开源,用后者就对了)

常⻅存储封装格式

总体上说AVI和RM是⽬前最常⻅的格式,⽽AVI由于先天缺陷不利于⽹络传输;m2ts和mkv是先进的下⼀ 代标准,今后可能逐步流⾏。WMV和ASF通常是微软MPEG4算法的存储格式, DAT和MPG是MPEG1算法编码的⽂件的存储⽅式,其中DAT主要⽤于VCD,VOB则是MPEG2 算法编码的⽂件的存储⽅式,通常⽤于DVD。

python使用ffmpeg 获取视频文件信息

!!!注意使用以下命令安装包,不然会使用报错!!!

pip install ffmpeg-python

参考代码

import ffmpeg

input_video = './data/rafting.avi'

if __name__ == "__main__":

    probe = ffmpeg.probe(input_video)

    video_stream_info = probe["streams"][0]
audio_stream_info = probe["streams"][1]
format_info = probe["format"]
# show video codec info
print("codec_type: {0} | codec_name: {1}| codec_long_name: {2}".format(video_stream_info["codec_type"],
video_stream_info["codec_name"],
video_stream_info["codec_long_name"]))
# show audo codec info
print("codec_type: {0} | codec_name: {1}| codec_long_name: {2}".format(audio_stream_info["codec_type"],
audio_stream_info["codec_name"],
audio_stream_info["codec_long_name"]))
# show container(encapsulation) format
print("filename:{0} | format_name: {1} | format_long_name: {2}".format(format_info["filename"],
format_info["format_name"],
format_info["format_long_name"]))

参考视频信息输出样例

{'streams': [{'index': 0, 'codec_name': 'msmpeg4v2', 'codec_long_name': 'MPEG-4 part 2 Microsoft variant version 2', 'codec_type': 'video', 'codec_time_base': '1/12', 'codec_tag_string': 'MP42', 'codec_tag': '0x3234504d', 'width': 1920, 'height': 1080, 'coded_width': 1920, 'coded_height': 1080, 'closed_captions': 0, 'has_b_frames': 0, 'pix_fmt': 'yuv420p', 'level': -99, 'refs': 1, 'r_frame_rate': '12/1', 'avg_frame_rate': '12/1', 'time_base': '1/12', 'start_pts': 0, 'start_time': '0.000000', 'duration_ts': 19999, 'duration': '1666.583333', 'bit_rate': '2422022', 'nb_frames': '19999', 'disposition': {'default': 0, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0}}], 'format': { ...}

二、opencv视频相关操作

1.视频信息读取相关

首先读取视频文件,函数部分使用方式如下

video_reader = cv2.VideoCapture('test.mp4')

cv2.VideoCapture()

如果传的参数是数字,表示使用摄像头。如 cv2.VideoCapture(0),表示使用计算机第一个摄像头。

如果传的是一个视频的地址,则表示读取本地视频。这里我只用第二种,给一个视频的绝对路径并读取它。另有如下两常用函数:

  • cv2.VideoCapture().isOpened() 检测视频读取状态是否正常
  • cv2.VideoCapture().read() 获取视频某一帧,返回两个值,第一个是布尔值,表示“这一帧”是否获取正确;第二个值是这一帧的内容,是一个矩阵。

获取视频的基本信息

例如获取视频的编解码信息 FOURCC ,例如输出 1145656920

print( int(video_reader.get(cv2.CAP_PROP_FOURCC)))
## 或者直接整数参数替代,参考下面表格
print(int(video_reader.get(6)))

**cv2.VideoCapture.get参数 ** 参考官网

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M7Hq3u1I-1637575947898)(../../figure/20210425103045721.png)]

FOURCC

关于fourCC的一段讲述

FourCC is a 4-byte code used to specify the video codec. The list of available codes can be found in fourcc.org. It is platform dependent. Following codecs work fine: In Fedora: DIVX, XVID, MJPG, X264, WMV1, WMV2. ( XVID is more preferable. MJPG results in high size video. X264 gives very small size video ) In Windows: DIVX ( more to be tested and added )

FourCC code is passed as cv2.VideoWriter_fourcc('M','J','P','G') or cv2.VideoWriter_fourcc(\*'MJPG) for MJPG.

这里针对FOURCC专门写一下,可以看到例如上面的输出 1145656920,opencv中默认把FOURCC从字符转为int类型对应的转换原理可以参考维基中的Technical details。

int转换为四位的字符,参考以下python代码

def decode_fourcc(cc):
return "".join([chr((int(cc) >> 8 * i) & 0xFF) for i in range(4)]) decode_fourcc(1145656920)
'XVID'

或者参考这c++代码

unsigned int f = (unsigned)capture.get(cv::CAP_PROP_FOURCC);
char fourcc[] = {
(char)f, // First character is lowest bits
(char)(f >> 8), // Next character is bits 8-15
(char)(f >> 16), // Next character is bits 16-23
(char)(f >> 24), // Last character is bits 24-31
'\0' // and don't forget to terminate
};
cout << "the return int fourcc was: " << f << endl;
cout << "FourCC for this video was: " << fourcc << endl;
/*运行结果为:
the return int fourcc was: 1145656920
FourCC for this video was: XVID
*/

或者这个在线转换的, 在线int fourCC转字符;另外opencv有函数自动把四位字符的fourCC转为int

cv2.VideoWriter_fourcc(*'XVID')     ###  1145656920

一些常见的fourCC 字符和 integer 对照表

字符 对应integer
"XVID" 1145656920
"MJPG" 1196444237
"X264" 875967064
"DIB" 541215044
"WMV1" 827739479
"WMV2" 844516695

3. 读取视频相关

这一部分比较简单,网上教程也很多,贴一个代码就行

    success = True
video_reader = cv2.VideoCapture(video_path)
while success and video_reader.isOpened():
# get a frame
success, frame = video_reader.read()
# show a frame
cv2.imshow("capture", frame)
if cv2.waitKey(100) & 0xFF == ord('q'):
break
video_reader.release()
cv2.destroyAllWindows()

3. 保存视频相关

cv2.VideoWriter()

保存视频需要使用cv2.VideoWriter()函数

VideoWriter(filename, fourcc, fps, frameSize[, isColor]) -> <VideoWriter object>

参数说明:

比较重要的三个fourcc 指定编码格式,注意格式和对应的后缀匹配;frameSize 视频分辨率,一定要确保写入的图像和此分辨率一致,如果像改分辨率得先把图resize再保存成特定分辨率;isColor,True,输入图必须是RGB,否则无法保存,但是却不会报错,只不过发现保存的视频为空的,也打不开

  • filename,要保存的视频路径
  • fourcc,视频压缩帧的编码codec,例如 cv2.VideoWriter_fourcc('M', 'P', '4', '2') 或者 cv2.VideoWriter_fourcc(*"MP42") 表示使用 MPEG-4.2 codec, 可以参考这个: 可以使用的fourcc列表大全
  • fps,输出视频的帧率
  • frameSize,输出视频每帧图像的大小,要和写入的那帧图大小一直,不然会有问题
  • isColor,如果非零,编码器将希望得到彩色帧并进行编码;否则,是灰度帧(只有在Windows下支持这个标志)

附加一个关于fourCC的说明

四个字符用来表示压缩帧的codec 例如:

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

NOTE:生成文件占用空间最小的编码方式是MPEG-4.2 codec。在VideoWriter类的构造函数参数为CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) 。

最大的是MPEG-1 codec,对应在VideoWriter类的构造函数参数为CV_FOURCC(‘P’,‘I’,‘M’,‘1’) ,所占磁盘空间是前者的5.7倍。所以如果需要24小时全天候录制监控,可以优先使用MPEG-4.2的编解码方式。

若编码器代号为 -1,则运行时会弹出一个编码器选择框.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nkdl9PlK-1637575947899)(../../figure/aHR0cDovL3VwbG9hZC1pbWFnZXMuamlhbnNodS5pby91cGxvYWRfaW1hZ2VzLzU1Mjk5OTctYTkyMzFiOGRjZmZkMTRkMQ)]

原文链接:https://blog.csdn.net/qiu931110/article/details/85174069

例子

先定义输出文件

    fps_cv = video_reader.get(cv2.CAP_PROP_FPS)  ### 视频fps, opencv检测到的
fourcc = cv2.VideoWriter_fourcc(*'XVID') ### 保存视频的格式
h, w, c = frame.shape
out = cv2.VideoWriter(save_path, fourcc, fps_cv, (w, h), isColor=True) ## 保存视频

然后一遍读视频每帧一遍保存成新的视频

    success = True
video_reader = cv2.VideoCapture(video_path)
while success and video_reader.isOpened():
# get a frame
success, frame = video_reader.read()
### save frame
out.write(frame)
out.release() ### 完成保存,释放
video_reader.release()

各种视频格式测试

保存1080p的视频,共300帧的内容,H.265 和H.264暂未测试,opencv需要相关的依赖包

分辨率 格式 需要时间 文件大小
1920*1080 'XVID' MPEG-4 codec 1.7377230167388915 6.2MB
1920*1080 ‘MP42’ MPEG-4.2 codec 1.7837894439697266 6.1MB
1920*1080 "DIVX" MPEG-4 codec 1.7331401348114013 6.2MB
1920*1080 "DIV3" MPEG-4.3 codec 3.3492454290390015 6.1MB

opencv 视频处理相关的更多相关文章

  1. OpenCV视频读取播放,视频转换为图片

    转载请注明出处!!! http://blog.csdn.net/zhonghuan1992 OpenCV视频读取播放,视频转换为图片 介绍几个有关视频读取的函数: VideoCapture::Vide ...

  2. video播放视频以及相关事件

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  3. 庞锋 OpenCV 视频 学习进度备忘

    书签:另外跳过的内容有待跟进 学习资源: opencv视频教程目录(初级)   主讲:庞锋,毕业于电子科技大学 知识基础支持: 线性代数 应用数学 跳过的内容: 1.第1~6集跳过,简单.(2014- ...

  4. OpenCV 视频与图片序列相互转换

    我们在计算机视觉相关的实验中都需要视频与图片序列之间相互转换,在平时的实验中,经常需要将视频保存为一帧一帧的图片,以获取实验结果:另一方面,很多标准的算法测试数据库都是图片序列(文件名以帧号+图片扩展 ...

  5. 1.6 opencv视频操作基础

    利用opencv中的VideoCapture类,来对视频进行读取显示,以及调用摄像头. VideoCapture是opencv 2.X中新增的一个类,对应于之前C语言版本的CvCapture结构体.它 ...

  6. 学习opencv跟轮廓相关的

    查找轮廓 轮廓到底是什么?一个轮廓一般对应一系列的点,也就是图像中的一条曲线.表示的方法可能根据不同情况而有所不同.有多重方法可以表示曲线.在openCV中一般用序列来存储轮廓信息.序列中的每一个元素 ...

  7. 立体视觉-opencv中立体匹配相关代码

    三种匹配算法比较 BM算法: 该算法代码: view plaincopy to clipboardprint? CvStereoBMState *BMState = cvCreateStereoBMS ...

  8. opencv视频跟踪2

    在前面的报告中我们实现了用SURF算法计算目标在移动摄像机拍摄到的视频中的位置.由于摄像机本身像素的限制,加之算法处理时间会随着图像质量的提高而提高,实际实验发现在背景复杂的情况下,结果偏差可能会很大 ...

  9. H5 视频直播相关技术

    一.移动视频直播发展 大家首先来看下面这张图: 可以看到,直播从 PC 到一直发展到移动端,越来越多的直播类 App 上线,同时移动直播进入了前所未有的爆发阶段,但是对于大多数移动直播来说,还是要以 ...

随机推荐

  1. 洛谷3648 [APIO2014]序列分割(斜率优化+dp)

    首先对于这个题目. qwq 存在一个性质就是,最终的答案只跟你的分割的位置有关,而和顺序无关. 举一个小栗子 \(a\ b\ c\) 将这个东西分成两块. 如果我们先分割\(ab\)之间的话,\(an ...

  2. 洛谷4103 HEOI2014大工程(虚树+dp)

    又是一道虚树好题啊 我们建出来虚树,然后考虑dp过程,我们分别令\(sum[x],mndis[x],mxdis[x],size[x]\)为子树内的路径长度和,最短链,最长链,子树内关键点个数. 对于一 ...

  3. Java(21)内部类

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228411.html 博客主页:https://www.cnblogs.com/testero ...

  4. Vim合并行

    日常常用到多行合并的功能,记录如下: 第一种, 多行合并成一行,即: AAAAABBBBBCCCCC 合并为:AAAAA BBBBB CCCCC 方法1: normal状态下 3J 其中的3是范围,可 ...

  5. Kali Linux修改root密码

    今天在官网下载了一个Kali虚拟机的压缩包, 解压缩后直接在VM中打开,点了好多次打开发现都打不开,查了一下说是没有关闭共享虚拟机,于是操作了一番: 编辑→首选项→共享虚拟机→选择禁用. 操作完之后果 ...

  6. Netty学习笔记(2)ByteBuffer

    1. 测试ByteBuffer 1.1 依赖 <dependencies> <dependency> <groupId>io.netty</groupId&g ...

  7. Java:并发笔记-01

    Java:并发笔记-01 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 1. 进程与线程 本章内容 进程和线程的概念 并行和并发的概念 线程基本应用 1.1 ...

  8. 看动画学算法之:队列queue

    目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...

  9. 2021.10.27考试总结[冲刺NOIP模拟17]

    T1 宝藏 发现每个数成为中位数的长度是关于权值单调的.线段树二分判断是否合法,单调指针扫即可. 考场上写了二分,平添\(\log\). \(code:\) T1 #include<bits/s ...

  10. 2021.8.15考试总结[NOIP模拟40]

    T1 送花 线段树.枚举右端点,线段树记录左端点对应的值. 每次对当前颜色上上次出现的位置到上次出现的位置区间减,上次出现的位置到当前位置区间加. $code:$ 1 #include<bits ...