MatlabMovies

From NA-Wiki

Jump to: navigation, search

The process of exporting graphics from Matlab can be tricky. Here are some ideas and links that help with exporting high-quality images and movies.

Contents

Case 1: Print to jpeg images and rescale

The problem with printing to images in Matlab is controlling the quality of the output. First, the flag to print is

  • -djpeg for jpeg
  • -dtiff for tiff
  • -dpng for png.

With these one needs to set the resolution pretty high to get nice-looking images. This is done with the -r### flag, i.e. -r300 gives 300 dpi resolution. But then the image will be very large in terms of pixels, so one needs to resize it. One way to go is to use the UNIX command convert. See this link.

In a script, it would look something like

>> (some plotting command)
>> s = 'filename.jpg';
>> set(gcf,'PaperPositionMode','auto')
>> print(gcf,'-djpeg90','-r300',s)
>> rescale_comm = ['convert ' s ' -resize 35% ' s];
>> unix(rescale_comm);

Here is a longer example which prints a sequence of images:

clear, close all

% some simple function
f = inline('exp(-x-t).*sin(x-t)','x','t');
x = linspace(0,5,100);

% set up figure
figure;
set(gcf,'PaperPositionMode','auto')
grid on

% filenames
s_pre = 'img_';
s_post = '.jpg';

k = 1;
for t = 0:0.01:1
  g = f(x,t);
  plot(x,g); axis([0 5 -0.05 0.35]), grid on
  
  % make a filename
  s = [s_pre sprintf('%06d',k) s_post];

  % now plot and rescale
  print(gcf, '-djpeg','-r300', s); 
  convert_comm = ['convert ' s ' -resize 35% ' s];
  unix(convert_comm);

  k = k+1;
end

Case 2: Print eps images and convert to png

A more pleasing option is to have Matlab print .eps files and then have ImageMagick convert them to png. The trick is then that convert should render the eps at a high resolution before converting it to png.

>> (some plotting command)
>> epsfile = 'filename.eps';
>> pngfile = 'filename.png'
>> set(gcf,'PaperPositionMode','auto')
>> print(gcf,'-depsc',epsfile)
>> rescale_comm = ['convert -density 288 -scale x480 ' epsfile ' ' pngfile];
>> unix(rescale_comm);

This gives the output file of size x by 480 pixes (scaled preserving aspect ratio). Note that the value 288 is 4*72, the default rendering dpi.

In a script:

clear, close all

% some simple function
f = inline('exp(-x-t).*sin(x-t)','x','t');
x = linspace(0,5,100);

% set up figure
figure;
set(gcf,'PaperPositionMode','auto')
set(gcf,'Position',[10 10 650 490])
grid on

% filenames
s_pre = 'fig/example2_';
s_post = '.eps';

k = 1;
for t = 0:0.01:1
  g = f(x,t);
  plot(x,g); axis([0 5 -0.05 0.35]), grid on
  
  % make a filename
  fn = sprintf('%06d',k);
  s = [s_pre fn s_post];
  
  % now print to eps
  print(gcf, '-depsc', s);
  
  % use convert to get a nice png
  s_out = [s_pre fn '.png'];
  convert_comm = ['convert -density 288 -scale x480 ' s ' ' s_out];
  unix(convert_comm);

  k = k+1;
end

!mencoder "mf://fig/*.png" -mf fps=25 -o output.avi -ovc lavc -lavcopts vcodec=mpeg4

Compressing images into an avi movie

The best tool for compressing a sequence of images into a movie is MEncoder. With this tool you can get DivX compression, but it will require that a comprehensive set of codecs are present in the system. For some tips on usage, go here, or do something like

$ mencoder "mf://*.jpg" -mf fps=25 -o output.avi -ovc lavc -lavcopts vcodec=mpeg4

It works equally well with "mf://*.png" instead of jpg.

If MEncoder is not present in your system one alternative is jpegtoavi. This is a simple tool that does only one thing: making an avi from jpeg pictures. JpegToAvi does not provide advanced codecs, but can be easily built in a user directory.

Case 3: Movies using avifile and MEncoder

On a UNIX system the Matlab command movie2avi does not provide video compression. A good substitution is to let Matlab write an uncompressed avi and then let mencoder compress it. Invoke MEncoder with something like this:

$ mencoder input.avi -o output.avi -ovc lavc

One may want to add some flags to the mencoder call, like -mpegopts format=mpeg2:tsaf:vbitrate=8000 -nosound

An example using Matlab

clear, close all

% some simple function
f = inline('exp(-x-t).*sin(x-t)','x','t');
x = linspace(0,5,100);

% set up figure
figure;
set(gca,'nextplot','replacechildren');
grid on

% set up movie
mov = avifile('output.avi');

k = 1;
for t = 0:0.01:1
  g = f(x,t);
  plot(x,g); axis([0 5 -0.05 0.35]), grid on, drawnow
  F = getframe(gcf);
  
  mov = addframe(mov,F);
  k = k+1;
end

mov = close(mov);

% now encode
!mencoder output.avi -o output_comp.avi -ovc lavc
!mv output_comp.avi output.avi

Mplayer playback

If you have a Dell 2007WFP monitor and are using a 1680x1050 resolution you can put this in your ~/.mplayer/config file:

monitoraspect=16:10

Then all movies will playback at the correct aspect ratio.

Personal tools