前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >视频数据处理方法!关于开源软件FFmpeg视频抽帧的学习

视频数据处理方法!关于开源软件FFmpeg视频抽帧的学习

作者头像
Datawhale
发布2019-10-23 17:51:55
3.7K0
发布2019-10-23 17:51:55
举报
文章被收录于专栏:Datawhale专栏Datawhale专栏

视频文件是多媒体数据中比较常见的一种,也是入门门槛比较高的一个领域。视频数据相关的领域任务包括视频物体检测、视频物体追踪、视频分类、视频检索和视频摘要抽取等。

视频数据与图像数据非常类似,都是由像素点组成的数据。在视频数据在非音频部分基本上可以视为多帧(张)图像数据的拼接,即三维图像的组合。由于视频数据与图像数据的相似性,在上述列举的视频领域任务中大都可以借助图像方法来完成。

文本将讲解视频抽帧的几种方法,具体包括以下几种抽帧方式:

  • 抽取视频关键帧(IPB帧)
  • 抽取视频场景转换帧
  • 按照时间进行均匀抽帧
  • 抽取制定时间的视频帧

在进行讲解具体的抽帧方式之前,我不得不介绍下FFmpeg。FFmpeg是一套可以用来编码、解码、合成和转换音频和视频数据的开源软件,提供了非常全面的音视频处理功能。如果你的工作内容是视频相关,那么ffmpeg是必须要掌握的软件了。FFmpeg提供了常见音视频和编解码方式,能够对众多的音视频格式进行读取,基本上所有的软件都会借助FFmpeg来完成音视频的读取操作。

FFmpeg的学习资料可以参考:

  • http://ffmpeg.org/documentation.html
  • https://blog.csdn.net/leixiaohua1020/article/details/15811977
代码语言:javascript
复制
# 查看视频信息
> ffmpeg -i 666051400.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '666051400.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.56.100
  Duration: 00:17:02.00, start: 0.000000, bitrate: 374 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p,
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz
    Metadata:
      handler_name    : SoundHandler
At least one output file must be specified

1. 抽取视频关键帧(IPB帧)

视频关键帧(Video Keyframes)是用于视频压缩和视频编解码的帧,视频关键帧是包含了完整信息的帧,其他的非关键帧将会使用与关键帧的差值进行压缩。视频帧具体可以分为IPB帧三种:

  • I帧表示关键帧,是最完整的帧画面,一般视频封面都选择I帧;
  • P帧单预测帧,利用之前的I帧或P帧,采用运动预测的方式进行帧间预测编码;
  • B帧双向预测帧,利用双向帧进行预测编码;

一般情况下关键帧`I帧`是信息最多的帧,也是用途最多的帧。在视频检索和视频分类任务中一般都借助`I帧`来完成,在一个时长60s的视频中,可以抽取得到16个I帧、84个P帧和184个B,I帧数量少包含的信息却是最多的。

  • 使用ffprobe提取出IPB帧的时间:
代码语言:javascript
复制
ffprobe -i 666051400.mp4 -v quiet -select_streams v -show_entries frame=pkt_pts_time,pict_type
  • 抽取IPB帧到jpg图片:
代码语言:javascript
复制
# 抽取I帧
ffmpeg -i 666051400.mp4 -vf "select=eq(pict_type\,I)"  -vsync vfr -qscale:v 2 -f image2 ./%08d.jpg

# 抽取P帧
ffmpeg -i 666051400.mp4 -vf "select=eq(pict_type\,P)"  -vsync vfr -qscale:v 2 -f image2 ./%08d.jpg

# 抽取B帧
ffmpeg -i 666051400.mp4 -vf "select=eq(pict_type\,B)"  -vsync vfr -qscale:v 2 -f image2 ./%08d.jpg

由于ffmpeg抽取帧并无法按照时间戳来命名,需要手动将ffprobe提取出来的帧时间与抽取帧的图片进行对应重命名。关键帧具体的定义和用途可以参考: https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Key_frame

2. 抽取视频场景转换帧

在视频中可以按照视频的镜头切换可以将视频分为不同的场景(scene boundaries),为了直观感受可以观看下面一个视频。

http://www.scikit-video.org/stable/_static/scene_cuts.mp4

视频场景抽取算法一般是使用帧间的相似差异程度来衡量,如果视频帧大于某一个阈值则认为是一个新的场景,否则不是一个新的场景。在scikit-video中提供了颜色相似度和边缘相似度两种度量方式,思路非常简单:

https://github.com/scikit-video/scikit-video/blob/master/skvideo/measure/scene.py

但是在我自己试验的过程中发现scikit-video中的场景检测非常慢,一个视频需要几分钟才能计算得到结果。后来在阅读ffmpeg文档过程中发现,ffmpeg早就有场景检测的命令,而且速度飞快。

代码语言:javascript
复制
# https://ffmpeg.org/ffmpeg-filters.html#select_002c-aselect
# 其中0.1表示帧为新场景的概率
ffmpeg -i 666051400.mp4 -filter:v "select='gt(scene,0.1)',showinfo" -f null - 2>&1

scikit-video的场景检测速度慢是以下原因:scikit-video中场景检测的实现方式是读取所有的视频帧,这个步骤非常耗时;而ffmpeg能够根据视频帧的压缩情况来选择性读取帧,速度就非常快了。但是scikit-video库还是很直观的,我也从库源代码学习到了很多。

如果ffmpeg有对应的功能命令,优先使用ffmpeg来完成。

3. 均匀抽帧

代码语言:javascript
复制
# -r 指定抽取的帧率,即从视频中每秒钟抽取图片的数量。1代表每秒抽取一帧。
ffmpeg -i 666051400.mp4 -r 1 -q:v 2 -f image2 ./%08d.000000.jpg

4. 抽取制定时间的帧

代码语言:javascript
复制
# 耗时0.07s
ffmpeg -ss 00:00:30 -i 666051400.mp4 -vframes 1 0.jpg

# 耗时0.68s
ffmpeg -i 666051400.mp4 -ss 00:00:30  -vframes 1 0.jpg

为什么上述两个命令时间差距这么大呢,也就是-i与-ss的位置换了一下。区别就是如果-ss在前面,则会使用关键帧信息来进行索引,则会非常快。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Datawhale 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 抽取视频关键帧(IPB帧)
  • 2. 抽取视频场景转换帧
  • 3. 均匀抽帧
  • 4. 抽取制定时间的帧
相关产品与服务
媒体处理
媒体处理(Media Processing Service,MPS)是一种云端音视频处理服务。基于腾讯多年音视频领域的深耕,为您提供极致的编码能力,大幅节约存储及带宽成本、实现全平台播放,同时提供视频截图、音视频增强、内容理解、内容审核等能力,满足您在各种场景下对视频的处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档