Как сделать анимацию в MATLAB и сохранить её в формате GIF

В прошлой заметке мы с вами создавали видеролик при помощи MATLAB. Иногда полезно иметь анимацию не в видео формате, а в виде популярного в интернете формата GIF.

За основу мы возьмём код и данные, которые использовали в вышеупомянутой заметке:

for n =1:365
worldmap('world')
setm(gca,'Origin', [0 180 0])
geoshow(lat,lon,air(:,:,n),'displaytype','texture')
geoshow('landareas.shp','FaceColor','none','EdgeColor','w')
caxis([-80 40])
cmocean('thermal')
colorbar
title(datestr(t(n)))
frame(n) = getframe(gcf);
close(gcf)
end

v = VideoWriter('air_temp2018.mp4','MPEG-4');
v.FrameRate = 10;
open(v)
writeVideo(v,frame)
close(v)

Напомню, что первая часть строит все нужные нам картинки (отдельные кадры будущего видео) и записывает их в переменную frame. Затем, используя эту самую переменную frame во второй части кода мы создаём их этих кадров видеоролик. Сейчас эта вторая часть нам не понадобится, мы теперь используем переменную frame для создания GIF. Давайте я сначала сразу приведу здесь готовый код, а уже потом сделаю некоторые пояснения:

for n = 1:size(frame,2)
[A,map] = rgb2ind(frame2im(frame(n)),256);
if n == 1       
imwrite(A,map,'test1.gif','gif','LoopCount',Inf,'DelayTime',1);
else   
imwrite(A,map,'test1.gif','gif','WriteMode','append','DelayTime',1);
end
end
Для уменьшения размера файла я взял только первые 10 дней.

Если вы не хотите разбираться, то можете прямо его использовать и не задумываться о деталях.

Итак, как вы наверное поняли, gif создаётся при помощи функции imwrite, которая создана, вообще говоря, для записи разных типов графических файлов, не только gif (png, jpg и т.п.).

GIF файл создаётся в несколько этапов, сначала создаётся первый кадр (он может остаться единственным, если нам не нужна анимация), в коде это отражено в строке, идущей сразу после "if n == 1". Затем остальные кадры анимации записываются в наш файл при помощи опции 'WriteMode','append'.

Поскольку формат gif работает с индексированными цветами, то нам нужно перевести изображения из RGB в эти самые индексированные цвета, т.е. получить в нашем случае само изображение, которое будет записано в переменную A и карту цветов (т.е. какому цвету соответствует каждое число в переменной A), записанную в переменную map. Делает это всё функция rgb2ind. У нас, как вы видите, в качестве второго входного аргумента этой функции стоит число 256, это количество цветов, которые мы будем иметь в изображении. Если вам нужно уменьшить размер итогового файла, то вы может пожертвовать палитрой и создать гифку, состоящую из меньшего количества цветов. Например, так будет выглядить наша анимация, если мы оставим всего 8 цветов:

Также обратите внимание, что функция rgb2ind не поймёт, если вы попытаетесь скормить ей наши кадры, которые мы записывали в переменную frame, поэтому для начала мы должны перевести из в изображение при помощи функции frame2im.

Осталось только сказать, что 'LoopCount',Inf - означает, что наше изображение будет зацикленное, т.е. повторяться снова и снова, а 'DelayTime',1 - устанавливает задержку по времени между кадрами (в секундах).

 telegram

Чтобы не пропустить новые материалы с рецептами по работе с океанологическими данными, подпишитесь на канал в Telegram: https://t.me/koldunovaleksey

Данные для заметки:

NCEP Reanalysis data provided by the NOAA/OAR/ESRL PSD, Boulder, Colorado, USA, from their Web site at https://www.esrl.noaa.gov/psd/

Kalnay et al., The NCEP/NCAR 40-year reanalysis project, Bull. Amer. Meteor. Soc., 77, 437-470, 1996