Конвертировать последовательность изображений TensorBoard в видео / GIF - PullRequest
1 голос
/ 23 января 2020

У меня есть скрипт, который генерирует последовательность фигур matplotlib и записывает их на диск, используя TensorBoard SummaryWriter(). TensorBoard предлагает возможность перемещать небольшой ползунок для перемещения вперед и назад по последовательности изображений, но я хотел бы преобразовать последовательность изображений в видео или анимацию. Есть ли способ сделать это?

Редактировать 1: Вот упрощенный пример того, что делает мой текущий код. Я хотел бы взять изображения, которые записываются в файл журнала по .add_figure и преобразовать их в GIF.

import matplotlib.pyplot as plt
import numpy as np
from torch.utils.tensorboard import SummaryWriter

n = 200
nframes = 25
x = np.linspace(-np.pi*4, np.pi*4, n)
tensorboard_writer = SummaryWriter()

for i, t in enumerate(np.linspace(0, np.pi, nframes)):
    plt.plot(x, np.cos(x + t))
    plt.plot(x, np.sin(2*x - t))
    plt.plot(x, np.cos(x + t) + np.sin(2*x - t))
    plt.ylim(-2.5,2.5)
    fig = plt.gcf()
    tensorboard_writer.add_figure(
        tag='temp',
        figure=fig,
        global_step=i,
        close=True)

1 Ответ

1 голос
/ 24 января 2020

Вы можете использовать imageio или matplotlib FuncAnimation для создания анимации из набора файлов, представляющих кадры. В качестве примера я создал набор файлов в соответствии с

import matplotlib.pyplot as plt
import numpy as np

n = 200
nframes = 25
x = np.linspace(-np.pi*4, np.pi*4, n)

for i, t in enumerate(np.linspace(0, np.pi, nframes)):
    plt.plot(x, np.cos(x + t))
    plt.plot(x, np.sin(2*x - t))
    plt.plot(x, np.cos(x + t) + np.sin(2*x - t))
    plt.ylim(-2.5,2.5)
    plt.savefig('frame.'+str(i)+'.png', bbox_inches='tight', dpi=300)
    plt.clf()

, который создает серию файлов nframes (25 для примера) с соглашением об именах 'frame.n.png', где n - это номер кадра. Две распространяющиеся синусоидальные волны и созданная волна строятся в течение одного полупериода.

При подходе FuncAnimation вы затем выполняете

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig = plt.figure(figsize=(10, 6), dpi=300)
nframes = 25

def animate(i):
    im = plt.imread('frame.'+str(i)+'.png')
    plt.imshow(im)
    plt.axis('off')

anim = FuncAnimation(fig, animate, frames=nframes, interval=(2000.0/nframes))
anim.save('output.gif', writer='imagemagick')

При подходе imageio вы просто делаете

import imageio

nframes = 25
files = ['frame.'+str(i)+'.png' for i in range(nframes)]

frames = [imageio.imread(f) for f in files]
imageio.mimsave('output.gif', frames, fps=(nframes / 2.0))

Любой подход создает эту анимацию:

enter image description here

Однако метод imageio на намного быстрее по сравнению с FuncAnimation method:

> $ time python3 imageio.py
real    0m9.483s
user    0m9.484s
sys     0m1.156s

> $ time python3 FuncAnimation.py
real    15m36.151s
user    3m28.375s
sys     12m3.578s

Также стоит отметить, что файл, сгенерированный с помощью подхода FuncAnimation, на намного меньше, чем файл, созданный с помощью подхода imageio.

2.5M Jan 23 18:36 FuncAnimation.gif
 13M Jan 23 18:08 imageio.gif

Конечно, вы также можете использовать ffmpeg, чтобы сделать это, если вы предпочитаете программный c подход.

...