我尝试使用matplotlib电影编剧器制作电影。如果我这样做,我总是在视频周围留下白色边缘。有谁知道如何删除该保证金?
来自http://matplotlib.org/examples/animation/moviewriter.html
的调整后的示例# This example uses a MovieWriter directly to grab individual frames and
# write them to a file. This avoids any event loop integration, but has
# the advantage of working with even the Agg backend. This is not recommended
# for use in an interactive setting.
# -*- noplot -*-
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import matplotlib.animation as manimation
FFMpegWriter = manimation.writers['ffmpeg']
metadata = dict(title='Movie Test', artist='Matplotlib',
comment='Movie support!')
writer = FFMpegWriter(fps=15, metadata=metadata, extra_args=['-vcodec', 'libx264'])
fig = plt.figure()
ax = plt.subplot(111)
plt.axis('off')
fig.subplots_adjust(left=None, bottom=None, right=None, wspace=None, hspace=None)
ax.set_frame_on(False)
ax.set_xticks([])
ax.set_yticks([])
plt.axis('off')
with writer.saving(fig, "writer_test.mp4", 100):
for i in range(100):
mat = np.random.random((100,100))
ax.imshow(mat,interpolation='nearest')
writer.grab_frame()
答案 0 :(得分:10)
将None
作为subplots_adjust
的争论传递不符合您的想法(doc)。这意味着'使用deault值'。要做你想做的事,请改用以下内容:
fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None)
如果您重复使用ImageAxes
对象,也可以使代码更有效率
mat = np.random.random((100,100))
im = ax.imshow(mat,interpolation='nearest')
with writer.saving(fig, "writer_test.mp4", 100):
for i in range(100):
mat = np.random.random((100,100))
im.set_data(mat)
writer.grab_frame()
默认情况下imshow
修正宽高比相等,即像素为方形。您需要将图形重新调整为与图像相同的宽高比:
fig.set_size_inches(w, h, forward=True)
或告诉imshow
使用任意宽高比
im = ax.imshow(..., aspect='auto')
答案 1 :(得分:2)
我整天都在搜索此图片,最终在创建每个图像时使用@matehat的此解决方案。
import matplotlib.pyplot as plt
import matplotlib.animation as animation
要制作没有边框的图形:
fig = plt.figure(frameon=False)
fig.set_size_inches(w,h)
要使内容填满整个数字
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
假设您的电影存储在“ imageStack”中,绘制第一帧:
movieImage = ax.imshow(imageStack[0], aspect='auto')
然后我写了一个动画函数:
def animate(i):
movieImage.set_array(imageStack[i])
return movieImage
anim = animation.FuncAnimation(fig,animate,frames=len(imageStack),interval=100)
anim.save('myMovie.mp4',fps=20,extra_args=['-vcodec','libx264']
效果很好!
以下是空白删除解决方案的链接:
答案 2 :(得分:1)
在最近的build of matplotlib中,看起来你可以将参数传递给作者:
def grab_frame(self, **savefig_kwargs):
'''
Grab the image information from the figure and save as a movie frame.
All keyword arguments in savefig_kwargs are passed on to the 'savefig'
command that saves the figure.
'''
verbose.report('MovieWriter.grab_frame: Grabbing frame.',
level='debug')
try:
# Tell the figure to save its data to the sink, using the
# frame format and dpi.
self.fig.savefig(self._frame_sink(), format=self.frame_format,
dpi=self.dpi, **savefig_kwargs)
except RuntimeError:
out, err = self._proc.communicate()
verbose.report('MovieWriter -- Error running proc:\n%s\n%s' % (out,
err), level='helpful')
raise
如果是这种情况,您可以将bbox_inches="tight"
和pad_inches=0
传递给grab_frame - > savefig,这应该删除大部分边框。然而,Ubuntu上最新的版本仍然有这个代码:
def grab_frame(self):
'''
Grab the image information from the figure and save as a movie frame.
'''
verbose.report('MovieWriter.grab_frame: Grabbing frame.',
level='debug')
try:
# Tell the figure to save its data to the sink, using the
# frame format and dpi.
self.fig.savefig(self._frame_sink(), format=self.frame_format,
dpi=self.dpi)
except RuntimeError:
out, err = self._proc.communicate()
verbose.report('MovieWriter -- Error running proc:\n%s\n%s' % (out,
err), level='helpful')
raise
所以看起来功能正在被放入。抓住这个版本并试一试!
答案 3 :(得分:0)
如果你"只是"想要在没有轴注释的情况下保存matshow / imshow矩阵渲染,那么scikit-video(skvideo)的最新开发者版本也可能是相关的 - 如果你安装了avconv。分布中的一个示例显示了由numpy函数构建的动态图像:https://github.com/aizvorski/scikit-video/blob/master/skvideo/examples/test_writer.py
以下是我对该示例的修改:
# Based on https://github.com/aizvorski/scikit-video/blob/master/skvideo/examples/test_writer.py
from __future__ import print_function
from skvideo.io import VideoWriter
import numpy as np
w, h = 640, 480
checkerboard = np.tile(np.kron(np.array([[0, 1], [1, 0]]), np.ones((30, 30))), (30, 30))
checkerboard = checkerboard[:h, :w]
filename = 'checkerboard.mp4'
wr = VideoWriter(filename, frameSize=(w, h), fps=8)
wr.open()
for frame_num in range(300):
checkerboard = 1 - checkerboard
image = np.tile(checkerboard[:, :, np.newaxis] * 255, (1, 1, 3))
wr.write(image)
print("frame %d" % (frame_num))
wr.release()
print("done")