从视频中提取关键帧

时间:2012-01-30 13:56:53

标签: opencv computer-vision keyframe

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

5 个答案:

答案 0 :(得分:15)

使用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

答案 1 :(得分:7)

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

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

对于遇到选择过滤器'eq(pict_type \,PICT_TYPE_I)'问题的人,您可能希望将过滤器设为'eq(pict_type \,I)'。这已经被打破了一段时间,因此某些版本的ffmpeg可能无法识别常量。修复程序可以看作here

最终对我有用的命令是:

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

答案 4 :(得分: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,"