从视频中提取关键帧
我需要从视频/流中提取关键帧。那么有没有标准的实现。 我正在使用开放式简历。 (目前我每秒提取帧,这比较慢,我需要提高性能。) 因此,如果有人有优化实施,请在这里回复。
I need Need To extract Key Frames from Video/Stream.So is there any standard implementation.
I am using open CV.
(Currently i am extracting frames each second which is slower i need to improve performance.)
So if any one has optimized implementation please reply in here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用 ffmpeg,您可以使用以下代码提取所有关键帧:
ffmpeg 命令行中 -vf 后面的内容是 Filtergraph 描述。选择过滤器选择要传入输出的帧。过滤器的常量是“pict_type”,值为“PICT_TYPE_I”。所以 ffmpeg 仅将关键帧传递到输出。
-vsync 2 防止 ffmpeg 为每个关键帧生成多个副本。
-f image2 将视频帧写入图像文件。输出文件名由模式指定,该模式可用于生成按顺序编号的文件系列。该模式可能包含字符串“%d”或“%0Nd”。
参考:
http://www.videoproductslondon.com /blog/scene-change-detection-during-encoding-key-frame-extraction-code
Using ffmpeg you can extract all key frames using the following code:
What follows -vf in a ffmpeg command line is a Filtergraph description. The select filter selects frames to pass in output. The constant of the filter is “pict_type” and the value “ PICT_TYPE_I”. So ffmpeg is only passing key frames to the output.
-vsync 2 prevents ffmpeg to generate more than one copy for each key frame.
-f image2 writes video frames to image files. The output filenames are specified by a pattern, which can be used to produce sequentially numbered series of files. The pattern may contain the string "%d" or "%0Nd".
Reference:
http://www.videoproductionslondon.com/blog/scene-change-detection-during-encoding-key-frame-extraction-code
我假设关键帧是一个呈现与以前的内容有很大不同的框架(这不是一个正式的定义,但它适合)。取帧 i 和 i+1。使用 cv2.absDiff 进行计算框架和 cv2.sumElems 获取总和所有像素差异。对所有帧i执行此操作。这会将您的视频流减少为一维信号。在此信号中查找峰值并选择与这些峰值相对应的关键帧。要找到峰值,请在此信号上选择一个阈值,方法是手动查找您认为关键的帧,并将其误差作为误差阈值,或者自动使用统计数据(例如,误差大于 1 个标准差的任何帧 i+1)。平均误差)。
I will assume that a keyframe is a frame presenting content a lot different from the previous ones (it's not a formal definition, but it fits). Take frames i and i+1. Use cv2.absDiff to compute the difference between the frames and cv2.sumElems to get the sum of all pixels differences. Do this for all frames i. This will reduce your video stream to an one dimensional signal. Look for peaks in this signal and pick keyframes corresponding to these peaks. To find peaks choose a threshold on this signal either manually by finding a frame you deem to be key, and letting its error be the error threshold or automatically using statistics (e.g. any frame i+1 where the error is greater than 1 stdev from the mean error).
如果上述代码有问题,请尝试使用此参数顺序。
If something wrong with the above code, try this argument order instead.
ffmpeg 解决方案应该运行良好。
对于在选择过滤器“eq(pict_type\,PICT_TYPE_I)”时遇到问题的人,您可能想尝试使用“eq(pict_type\,I)”过滤器。这个问题已经被打破了一段时间,因此某些版本的 ffmpeg 可能无法识别该常量。您可以在此处查看该修复。
最终对我有用的最终命令是:
The ffmpeg solution should work well.
For someone facing problems with the select filter 'eq(pict_type\,PICT_TYPE_I)', you might want to try the filter as 'eq(pict_type\,I)'. This was broken for a while so some versions of ffmpeg might not recognize the constant. The fix can be seen here.
The final command which worked for me finally was:
您可以使用 ffprobe 提取关键帧。它是ffmpeg中的一个工具。
使用命令:
You can use ffprobe to extract key frames. It is a tool in ffmpeg.
Use the command: