13

我尝试使用 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()
4

4 回答 4

20

None作为论据传递给subplots_adjust不做你认为它做的事情(doc)。这意味着“使用默认值”。要执行您想要的操作,请改用以下命令:

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')
于 2013-04-08T15:52:05.030 回答
3

我整天搜索这个并最终在创建每个图像时使用@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']

它工作得很好!

这是空白删除解决方案的链接:

1从图像中删除空格

于 2020-02-21T22:52:40.317 回答
1

在最近的 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"and传递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

所以看起来功能正在被添加。抓住这个版本并试一试!

于 2013-04-08T15:23:37.953 回答
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")
于 2015-06-11T20:16:12.653 回答