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