Сжимайте фильмы с плоскими участками из нескольких точек и линий в Matlab (почему они такие тяжелые?)

Рассмотрим последовательность точек:

N = 8 * 360; t = (0:9:N) + N / 4;
x = sqrt(t) .* cos(t * pi / 180);
y = sqrt(t) .* sin(t * pi / 180);

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

f = figure('Position', [300 75 900 600]);
hold on
h_plot1 = plot(x(2:end), y(2:end), 'ob', 'MarkerEdgeColor', 'b', 'MarkerFaceColor', 'b', 'MarkerSize', 5);
h_plot2 = plot(x(1), y(1), 'o-r', 'MarkerEdgeColor', 'b', 'MarkerFaceColor', 'b', 'MarkerSize', 5, 'LineWidth', 3);
x_min = min(x); x_max = max(x); y_min = min(y); y_max = max(y);
x_w = x_max - x_min; y_w = y_max - y_min;
axis([x_min - x_w / 10 x_max + x_w / 10 y_min - y_w / 10 y_max + y_w / 10])
axis equal, axis off
set(f, 'Color', [1 1 .25])
set(gca, 'Color', [1 1 .25])
set(gca,'nextplot','replacechildren');
vid = VideoWriter('myveryheavymovie.avi');
vid.Quality = 100;
vid.FrameRate = 15;
open(vid);
for hh = 1:length(x)-1
  hold on
  set(h_plot1, 'XData', x((hh + 1):end), 'YData', y((hh + 1):end))
  set(h_plot2, 'XData', x(1:(hh + 1)), 'YData', y(1:(hh + 1)))
  tmp = plot(x(hh:hh+1), y(hh:hh+1), 'or', 'MarkerSize', 8, 'MarkerFaceColor', 'r');
  writeVideo(vid, getframe(f));
  delete(tmp)
  writeVideo(vid, getframe(f));
end
close(vid);

Фильм 111,840 KB, неоправданно тяжелый - есть ли способ сжать фильм? Изображения представляют собой всего лишь несколько точек и линий: можно ли сжать фильм, скажем, до 1,000 KB?

ИЗМЕНИТЬ следующие ответы от A. Donda, chappjc и horchler

По-видимому, я не могу изменить профиль, и на данный момент я не пробовал стороннее программное обеспечение. Я попытался создать анимацию gif с помощью imwrite:

% Consider a sequence of points:
N = 8 * 360; t = (0:9:N) + N / 4;
x = sqrt(t) .* cos(t * pi / 180);
y = sqrt(t) .* sin(t * pi / 180);
x_min = min(x); x_max = max(x); y_min = min(y); y_max = max(y);
x_w = x_max - x_min; y_w = y_max - y_min;

% Create figure:
f = figure('Position', [300 75 900 600]);
set(f, 'Color', [1 1 .25])
h_plot1 = plot(x(2:end), y(2:end), 'ob', 'MarkerEdgeColor', 'b', 'MarkerFaceColor', 'b', 'MarkerSize', 3);
hold on
h_plot2 = plot(x(1), y(1), 'o-r', 'MarkerEdgeColor', 'b', 'MarkerFaceColor', 'b', 'MarkerSize', 3, 'LineWidth', 3);
axis([x_min - x_w / 10 x_max + x_w / 10 y_min - y_w / 10 y_max + y_w / 10])
axis equal, axis off
set(gca, 'nextplot','replacechildren', 'Visible','off');

% preallocate mov fo gif animation
nFrames = length(x)-1;
frame = getframe(gca);
[frame, map] = rgb2ind(frame.cdata, 256, 'nodither');
map = [map; 1 0 0];
mov = repmat(frame, [1 1 1 2*nFrames]);

% Visualize it, get the frames and save gif animation
for hh = 1:nFrames
  set(h_plot1, 'XData', x((hh + 1):end), 'YData', y((hh + 1):end))
  set(h_plot2, 'XData', x(1:(hh + 1)), 'YData', y(1:(hh + 1)))
  hold on
  tmp = plot(x(hh:hh+1), y(hh:hh+1), 'or', 'MarkerSize', 8, 'MarkerEdgeColor', 'r', 'MarkerFaceColor', 'r');
  frame = getframe(gca);
  mov(:, :, 1, 2*hh-1) = rgb2ind(frame.cdata, map, 'nodither');
  delete(tmp)
  frame = getframe(gca);
  mov(:, :, 1, 2*hh) = rgb2ind(frame.cdata, map, 'nodither');
end
close(gcf)
imwrite(mov, map, 'mynotsoheavygif.gif', 'DelayTime', 0, 'LoopCount', inf)

Файл gif 4,420 KB - это не хорошо и не плохо, но лучше, чем файл avi.


person randomatlabuser    schedule 02.12.2013    source источник
comment
Есть ли ошибка при создании VideoWriter с профилем 'MPEG-4'?   -  person chappjc    schedule 04.12.2013
comment
@chappjc У меня есть только два варианта профиля: Motion JPEG AVI и Uncompressed AVI. Работает на Matlab R2012b, на Windows.   -  person randomatlabuser    schedule 04.12.2013


Ответы (3)


Если вы сможете переключиться на профиль 'MPEG-4', это очень поможет. Убедитесь, что вы также указали 'Quality' — по умолчанию 75 из 100.

Одна из причин того, что фильмы могут быть большими, заключается в том, что доступные кодеки не обязательно являются наиболее подходящими для типичного содержимого Matlab. Похоже, вы пишете видео о довольно простом окне сюжета: плоский контент с областями постоянного цвета и, вероятно, небольшое использование градиентов и сглаживания. Если вам подходит QuickTime и вы заинтересованы в использовании сторонней функции, вы можете попробовать мою QTWriter. Примечательно, что он поддерживает кодек QuickTime «Photo PNG», который может сжимать ваш контент более эффективно, чем кодек MPEG-4 (или очень близкий), при этом не теряя потерь и поддерживая прозрачность. QTWriter очень похож на класс VideoWriter Matlab, поэтому переключение должно быть легким. Это единственный M-файл, который имеет несколько других уникальных и полезных функций. Вы можете просмотреть пример кода и видео на веб-сайте проекта.

Кроме того, если у вас Mac с дисплеем Retina, я думаю, что в getframe есть ошибка, которая приводит к размытию изображений и видео. В зависимости от кодека это может улучшить или ухудшить сжатие. Несмотря ни на что, выглядит плохо. Вы можете попробовать getframebg, если это проблема для вас.

person horchler    schedule 02.12.2013
comment
Разве не для этого когда-то должен был быть MNG? Жаль, что так и не взлетел... - person A. Donda; 03.12.2013
comment
@A.Donda: Photo PNG от QuickTime — это видеокодек (результатом является файл «.mov»), тогда как MNG (и aPNG) — это форматы анимированных изображений. В некоторых случаях различия могут быть несущественными, но данные Photo PNG, как и любое видео QuickTime, можно комбинировать с различными аудиокодеками (и даже видео с использованием других кодеков). - person horchler; 03.12.2013

Тип сжатого видео, которое вы можете создать, зависит от платформы: doc VideoWriter говорит

VideoWriter может создавать несжатые файлы AVI и Motion JPEG 2000, сжатые в формате AVI, на всех платформах и файлы MPEG-4 в Windows® 7 и Mac OS X 10.7 и выше.

Если вы работаете на платформе, не поддерживающей MPEG-4, и не хотите использовать Motion JPEG, вы можете попробовать использовать внешний инструмент, например ffmpeg для сжатия видео после его создания.

Обратите внимание, что почти все алгоритмы сжатия видео оптимизированы для реальных фотографических сцен с плавными движениями. Как правило, они плохо работают с линейной графикой, но быстро вызывают артефакты сжатия даже при небольшом уменьшении размера файла. VideoWriter предоставляет одну альтернативу сжатию с потерями, а именно Motion JPEG 2000 без потерь через профиль «Архивный».

В зависимости от того, для чего вам нужна анимация, написание анимированного gif с использованием imwrite может быть еще одной альтернативой без потерь.

person A. Donda    schedule 02.12.2013

Попробуйте изменить аргумент profile при создании VideoWriter (т.е. writerObj = VideoWriter(filename,profile)). Вас интересуют следующие профили:

profile

Строка, заключенная в одинарные кавычки, описывающая тип создаваемого файла. Указание профиля устанавливает значения по умолчанию для свойств видео, таких как VideoCompressionMethod. Возможные значения:

'Archival' Файл Motion JPEG 2000 со сжатием без потерь

'Motion JPEG AVI' Сжатый файл AVI с использованием кодека Motion JPEG

'Motion JPEG 2000' Сжатый файл Motion JPEG 2000

'MPEG-4' Сжатый файл MPEG-4 с кодировкой H.264 (системы с Windows 7 или Mac OS X 10.7 и выше)

'Uncompressed AVI' Несжатый файл AVI с видео RGB24

В частности, 'MPEG-4' обеспечит наилучший компромисс качества сжатия, если ваша система поддерживает кодировку H.264.

Однако для видео сюжетов может потребоваться использование метода сжатия без потерь, например 'Archival'. Обратите внимание, что при сжатии без потерь параметр Quality не используется.

Для методов сжатия с потерями (например, 'MPEG-4' или 'Motion JPEG AVI') можно просто использовать более низкую настройку Quality.

person chappjc    schedule 02.12.2013