【问题标题】:Sample frames of video视频样本帧
【发布时间】:2017-09-03 13:27:49
【问题描述】:

我正在寻找一种在 OS X/Python3.5 中获取 .avi 视频文件的方法,每 100 帧进行二次采样,然后将这些帧组合成自己的视频。

在我的特定情况下,视频为 30 秒,每秒 20 秒,因此新视频只有 6 帧长(我想为多个视频执行此操作,然后稍后将它们组合在一起)。

我安装了opencv,但找不到有关如何执行此操作的文档。如果更简单,我也可以使用其他库。

【问题讨论】:

  • 也许考虑将ffmpeg 与子进程一起使用;我认为OpenCV 无论如何都需要它,所以只需去掉中间人......
  • 我对任何事情都持开放态度,但我必须为跨越数百个子目录的数万个视频执行此操作。 ffmpeg 是否有任何方法可以自动执行此操作,或者一次只播放一个视频?想使用 python,因为我对 os 库有一些经验。
  • bash 中,您可以在find 的帮助下递归遍历目录。您需要Python 有什么原因吗?是的,ffmpeg 可以通过正确的脚本技能轻松实现自动化。一个这样的例子:stackoverflow.com/a/41657131/499581
  • 不是我只是想,否则我必须学习多种我没有经验的不同工具,比如 bash/regex/ffmpeg,而且我有点时间限制
  • 实际上并没有那么难,在我看来,坚持Bash 简化了这个过程,因为你不依赖任何其他语言及其特性。我写了一个快速的答案......虽然我首先有几个问题。 1) 您计划创建多少个视频 2) 对视频进行二次采样后,您希望将它们合并为一个 3) 您想在创建视频后删除捕获的图像吗?

标签: macos opencv video python-3.5 subsampling


【解决方案1】:

使用ffmpeg 并创建几个自定义bash 函数:

subsample () { export target=$2 ; find . -type f -name "*$1*" \
              -execdir bash -c 'ffmpeg -i "${0}" -vf "select=not(mod(n\,100))" \
              -vsync vfr -q:v 2 "${target}/${0}_%03d.png"' {} \; \
              -execdir bash -c 'ffmpeg -r 60 -f image2 -i "${target}/${0}_%03d.png" \
              -vcodec libx264 -crf 25 -pix_fmt yuv420p "${target}/clip_${0}"' {} \; \
              ; rm -f ${target}/*$1_*.png ;
             }

subconcat () { export target=$2 ; ffmpeg -f concat -safe 0 -i \
              <(printf "file '$PWD/%s'\n" ./clip_*.${1}) -copytb 1 \
              -c copy ${2}/combined_output.${1} ; 
             }

将函数保存在您的~/.bash_profile 中。

$ source ~/.bash_profile

概要

subsample|subconcat <ext> <target path>

(例如密码/path/movies):

subsample avi /path/to/output

subsample - 递归查找任何avi 并将每100 帧组合成一个新视频@目标。

subconcat - 合并指定扩展@目标的所有clip_*.ext视频。

假设您需要调整ffmpeg 设置以适合您, 尽管上面的示例应该让您大致了解仅使用 ffmpeg 和 bash find 的可能性。

【讨论】:

  • 感谢这个单独运行每个函数的效果很好。我编辑了第二个函数的路径,因此管道可以工作,因为它试图进入/./vid.avi
  • 不客气!我不确定它是否会做你想做的一切,所以我很高兴它对你有用。它处理路径的方式肯定可以改进,(但通常很容易做到)。最难理解的部分通常是 ffmpeg 使用的神秘命令...
  • 通常我cd 进入我想要开始的目录,然后运行命令——这样你就会知道它在正确的地方工作,而不是在不受欢迎的地方。如果你不注意它从哪里开始,使用带有find 的某些命令很容易造成灾难......
【解决方案2】:

needed functions 的简单逻辑:

make 
  VideoCapture
  VideoWriter

do
   fr = cv.GrabFrame until file end
   if 0 = (counter % 100)
        WriteFrame(writer, fr)

Python examples

【讨论】:

  • 谢谢,尽管以我有限的经验,这可能需要我很长时间。我尝试的第一件事,cv2.VideoWriter.open(): AttributeError: 'builtin_function_or_method' object has no attribute 'open'
  • @Jake 我没有 Python 实现经验,所以在我的答案中添加了示例页面
  • 那很干净:) @MBo
猜你喜欢
  • 2013-03-22
  • 2019-04-26
  • 2016-02-26
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 2011-03-29
  • 2016-05-26
相关资源
最近更新 更多