在Matlab中压缩几个点和线的平面电影(为什么它们如此沉重?)

时间:2013-12-02 20:16:00

标签: matlab animated-gif movie image-compression

考虑一系列要点:

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

显然我无法更改个人资料,目前我还没有尝试过第三方软件。我尝试用imwrite生成一个gif动画:

% 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文件更好。

3 个答案:

答案 0 :(得分:3)

您可以生成的压缩视频类型取决于平台:doc VideoWriter

  

VideoWriter可以创建未压缩的AVI和Motion JPEG 2000   所有平台上的压缩AVI文件和Windows®7上的MPEG-4文件   和Mac OS X 10.7及更高版本。

如果您所使用的平台不支持MPEG-4并且您不想使用Motion JPEG,则可以尝试使用ffmpeg之类的外部工具在生成视频后压缩视频

请注意,几乎所有视频压缩算法都针对真实世界的摄影场景进行了优化,运动平稳。它们通常在线图形上表现不佳,但即使文件大小略微减小,也会迅速引起压缩伪影。 VideoWriter提供了一种有损压缩的替代方案,即通过“档案”配置文件实现无损Motion JPEG 2000。

根据您需要动画的内容,使用imwrite编写动画gif可能是另一种无损替代方案。

答案 1 :(得分:2)

尝试在创建profile时更改VideoWriter参数(即writerObj = VideoWriter(filename,profile))。您感兴趣的是以下配置文件:

  

profile

     

用单引号括起来的字符串,用于描述要创建的文件类型。指定配置文件会为VideoCompressionMethod等视频属性设置默认值。可能的值:

     

'Archival' Motion JPEG 2000文件,无损压缩

     

'Motion JPEG AVI'使用Motion JPEG编解码器的压缩AVI文件

     

'Motion JPEG 2000'压缩的Motion JPEG 2000文件

     

'MPEG-4'使用H.264编码的压缩MPEG-4文件(使用Windows 7或Mac OS X 10.7及更高版本的系统)

     

'Uncompressed AVI'带有RGB24视频的未压缩AVI文件

如果您的系统支持H.264编码, 'MPEG-4'将提供最佳的压缩质量折衷

但是,对于绘图视频,可能需要使用无损压缩方法,例如'Archival'。请注意,使用无损压缩时,不使用Quality选项。

对于有损压缩方法(例如'MPEG-4''Motion JPEG AVI'),请考虑使用较低的Quality设置。

答案 2 :(得分:2)

如果您可以切换到'MPEG-4'个人资料,那将会有很大帮助。确保您同时指定'Quality' - 默认值为75分(满分100分)。

电影可能很大的一个原因是可用的编解码器不一定最适合典型的Matlab内容。看起来你正在编写一个相当基本的绘图窗口的视频:平面内容,颜色恒定,可能很少使用渐变和抗锯齿。如果您接受QuickTime并且您对使用第三方功能感兴趣,则可以尝试我的QTWriter。值得注意的是,它支持QuickTime“Photo PNG”编解码器,可以比MPEG-4编解码器(或非常接近)更有效地压缩您的内容,同时无损并支持透明度。 QTWriter在Matlab的VideoWriter类后紧密建模,因此切换应该很容易。它是一个单独的M-File,还有其他一些独特而有用的功能。您可以查看示例代码和视频on the project website

此外,如果您的Mac配有Retina显示屏,我认为getframe有一个导致模糊图像和视频的错误。根据编解码器,这可能会使压缩变得更好或更糟。无论如何,它看起来很糟糕。如果您遇到问题,可以尝试getframebg