从Python生成电影而不将单个帧保存到文件中
我想根据在 matplotlib 中的 python 脚本中生成的帧创建 h264 或 divx 影片。这部电影大约有 100k 帧。
在网络上的示例中[例如。 1],我只见过将每一帧保存为png,然后在这些文件上运行mencoder或ffmpeg的方法。就我而言,保存每一帧是不切实际的。有没有办法获取从 matplotlib 生成的图并将其直接通过管道传输到 ffmpeg,而不生成中间文件?
使用 ffmpeg 的 C-api 编程对我来说太困难了 [例如。 2]。另外,我需要一种具有良好压缩性的编码,例如 x264,否则电影文件对于后续步骤来说太大。所以坚持使用 mencoder/ffmpeg/x264 会很棒。
有什么可以用管道来做的事情[3]吗?
[1] http://matplotlib.sourceforge.net/examples/animation/movie_demo.html< /a>
I would like to create an h264 or divx movie from frames that I generate in a python script in matplotlib. There are about 100k frames in this movie.
In examples on the web [eg. 1], I have only seen the method of saving each frame as a png and then running mencoder or ffmpeg on these files. In my case, saving each frame is impractical. Is there a way to take a plot generated from matplotlib and pipe it directly to ffmpeg, generating no intermediate files?
Programming with ffmpeg's C-api is too difficult for me [eg. 2]. Also, I need an encoding that has good compression such as x264 as the movie file will otherwise be too large for a subsequent step. So it would be great to stick with mencoder/ffmpeg/x264.
Is there something that can be done with pipes [3]?
[1] http://matplotlib.sourceforge.net/examples/animation/movie_demo.html
[2] How does one encode a series of images into H264 using the x264 C API?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
此功能现在(至少从 1.2.0 开始,也许是 1.1)通过
MovieWriter
类及其在animation
模块中的子类融入到 matplotlib 中。您还需要提前安装ffmpeg
。动画文档
This functionality is now (at least as of 1.2.0, maybe 1.1) baked into matplotlib via the
MovieWriter
class and it's sub-classes in theanimation
module. You also need to installffmpeg
in advance.Documentation for
animation
修补 ffmpeg 后(请参阅 Joe Kington 对我的问题的评论),我能够将管道 png 传输到 ffmpeg,如下所示:
如果没有 patch,它简单地修改了两个文件并添加了
libavcodec/png_parser.c
。我必须手动将补丁应用到 libavcodec/Makefile。最后,我从Makefile
中删除了“-number”以获取要构建的手册页。使用编译选项,After patching ffmpeg (see Joe Kington comments to my question), I was able to get piping png's to ffmpeg as follows:
It would not work without the patch, which trivially modifies two files and adds
libavcodec/png_parser.c
. I had to manually apply the patch tolibavcodec/Makefile
. Lastly, I removed '-number' fromMakefile
to get the man pages to build. With compile options,转换为图像格式非常慢并且会增加依赖性。在查看这些页面和其他页面之后,我使用 mencoder 使用原始未编码缓冲区使其工作(仍然需要 ffmpeg 解决方案)。
详细信息位于: http://vokicodder.blogspot.com/2011/ 02/numpy-arrays-to-video.html
我得到了一些不错的加速。
Converting to image formats is quite slow and adds dependencies. After looking at these page and other I got it working using raw uncoded buffers using mencoder (ffmpeg solution still wanted).
Details at: http://vokicodder.blogspot.com/2011/02/numpy-arrays-to-video.html
I got some nice speedups.
这些都是非常好的答案。这是另一个建议。 @user621442 是正确的,瓶颈通常是图像的写入,因此如果您将 png 文件写入视频压缩器,它会非常慢(即使您通过管道发送它们而不是写入磁盘)。我找到了一个使用纯 ffmpeg 的解决方案,我个人认为它比 matplotlib.animation 或 mencoder 更容易使用。
另外,就我而言,我只想将图像保存在轴中,而不是保存所有刻度标签、图形标题、图形背景等。基本上我想使用 matplotlib 代码制作电影/动画,但没有它“看起来像一个图表”。我已经包含了该代码 在这里,但如果您愿意,您可以制作标准图表并将它们通过管道传输到 ffmpeg。
These are all really great answers. Here's another suggestion. @user621442 is correct that the bottleneck is typically the writing of the image, so if you are writing png files to your video compressor, it will be pretty slow (even if you are sending them through a pipe instead of writing to disk). I found a solution using pure ffmpeg, which I personally find easier to use than matplotlib.animation or mencoder.
Also, in my case, I wanted to just save the image in an axis, instead of saving all of the tick labels, figure title, figure background, etc. Basically I wanted to make a movie/animation using matplotlib code, but not have it "look like a graph". I've included that code here, but you can make standard graphs and pipe them to ffmpeg instead if you want.
这太棒了!我也想做同样的事。但是,我永远无法在 Vista 中使用 MingW32+MSYS+pr 环境编译修补后的 ffmpeg 源代码(0.6.1)... png_parser.c 在编译过程中产生了 Error1。
因此,我使用 PIL 提出了一个 jpeg 解决方案。只需将 ffmpeg.exe 放在与此脚本相同的文件夹中即可。这应该可以在 Windows 下使用 ffmpeg,无需补丁。我必须使用 stdin.write 方法而不是有关子进程的官方文档中推荐的通信方法。请注意,第二个 -vcodec 选项指定编码编解码器。管道由 p.stdin.close() 关闭。
This is great! I wanted to do the same. But, I could never compile the patched ffmpeg source (0.6.1) in Vista with MingW32+MSYS+pr enviroment... png_parser.c produced Error1 during compilation.
So, I came up with a jpeg solution to this using PIL. Just put your ffmpeg.exe in the same folder as this script. This should work with ffmpeg without the patch under Windows. I had to use stdin.write method rather than the communicate method which is recommended in the official documentation about subprocess. Note that the 2nd -vcodec option specifies the encoding codec. The pipe is closed by p.stdin.close().
这是@tacaswell 答案的修改版本。修改以下内容:
pylab
依赖项非常感谢@tacaswell 的精彩回答!
Here is a modified version of @tacaswell 's answer. Modified the following:
pylab
dependencyThanks so much for @tacaswell 's wonderful answer!!!