12

我需要需要从视频/流中提取关键帧。所以有没有标准的实现。我正在使用开放式简历。(目前我每秒都在提取帧,这较慢,我需要提高性能。)因此,如果有人优化了实现,请在此处回复。

4

5 回答 5

17

使用 ffmpeg,您可以使用以下代码提取所有关键帧:

ffmpeg -vf select="eq(pict_type\,PICT_TYPE_I)" -i yourvideo.mp4 -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg

ffmpeg 命令行中的 -vf 后面是 Filtergraph 描述。选择过滤器选择要传入输出的帧。过滤器的常数是“pict_type”,值是“PICT_TYPE_I”。所以 ffmpeg 只是将关键帧传递给输出。

-vsync 2 防止 ffmpeg 为每个关键帧生成多个副本。

-f image2 将视频帧写入图像文件。输出文件名由模式指定,可用于生成按顺序编号的文件系列。该模式可能包含字符串“%d”或“%0Nd”。

参考: http: //www.videoproductionslondon.com/blog/scene-change-detection-during-encoding-key-frame-extraction-code

于 2012-03-02T10:50:23.650 回答
8

我将假设关键帧是一个呈现与以前的内容大不相同的内容的帧(它不是一个正式的定义,但它适合)。取帧ii+1。使用cv2.absDiff计算帧之间的差异,使用cv2.sumElems获得所有像素差异的总和。对所有帧i执行此操作。这会将您的视频流减少为一维信号。寻找高峰在这个信号中选择与这些峰值相对应的关键帧。要找到峰值,可以通过手动找到一个您认为是关键的帧,并将其错误作为错误阈值来手动选择该信号的阈值,或者自动使用统计信息(例如,任何帧 i+1,其中错误大于 1 标准差平均误差)。

于 2012-01-31T11:57:45.410 回答
4

如果上述代码有问题,请尝试使用此参数顺序。

ffmpeg -i yourVideo.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg
于 2014-11-14T06:05:13.440 回答
2

ffmpeg 解决方案应该运行良好。

对于遇到选择过滤器“eq(pict_type\,PICT_TYPE_I)”问题的人,您可能想尝试使用“eq(pict_type\,I)”过滤器。这被破坏了一段时间,因此某些版本的 ffmpeg 可能无法识别该常量。可以在这里看到修复。

最后对我有用的命令是:

ffmpeg -vf select='eq(pict_type\,I)' -i yourVideo.mp4 -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg
于 2014-02-12T21:58:04.037 回答
0

您可以使用 ffprobe 提取关键帧。它是ffmpeg中的一个工具。

使用命令:

ffprobe in.mp4 -select_streams v -show_entries frame=key_frame,pkt_pts_time -of csv=nk=1:p=0 | findstr "1,"
于 2017-06-07T09:35:18.320 回答