Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Render MATLAB figure in memory

Tags:

Are there any alternatives to using getframe and saveas for saving the contents of a figure to a raster image for further processing?

Approach 1: getframe

h = figure('visible', 'off'); a = axes('parent', h);  % render using `scatter3()` or other plot function.  content = frame2im(getframe(h)); 

This has the serious drawback of showing the figure to perform a screen capture in the call to getframe() and it is problematic when performing such a render in a loop (i.e. saving content at each iteration as a video frame).

Approach 2: saveas

h = figure('visible', 'off'); a = axes('parent', h);  % render using `scatter3()` or other plot function.  saveas(h, '/path/to/file.png'); content = imread(/path/to/file.png'); 

This approach has the serious drawback of writing to disk, which is problematic in multithreaded applications, as well as being slower than rendering directly to memory. Since saveas() will obviously render to memory before invoking the PNG encoder, what I want is possible, but I can't find any function it in the MATLAB documentation that only performs the rendering part.

Question:

Does you know of an alternate way of rendering an arbitrary axes content to a raster image?

like image 709
André Caron Avatar asked Nov 09 '10 19:11

André Caron


People also ask

How do I save a figure in MATLAB?

To save the current figure, specify fig as gcf . saveas( fig , filename , formattype ) creates the file using the specified file format, formattype .

How do I free up memory in MATLAB?

To clear all variables from the current workspace, use clear or clearvars . To clear all global variables, use clear global or clearvars –global . To clear a particular class, use clear myClass . To clear a particular function or script, use clear functionName .

Can I allocate more RAM to MATLAB?

Direct link to this answer On a 32 bit OS with 32 bit matlab, matlab can only 2GB (3GB with some special settings) regardless of how much memory you have on your computer.


1 Answers

I realize this is an old thread, but I ran into this problem again lately, so I wanted to summarize my findings. My main source is this page (cached). According to it, there are three alternatives:

  1. using ADDFRAME directly with the figure handle (without using GETFRAME). This is exactly what @rescdsk has shown in his answer.

    hFig = figure('Visible','off');  aviobj = avifile('file.avi'); for k=1:N     %#plot(...)     aviobj = addframe(aviobj, hFig); end aviobj = close(aviobj); 
  2. using PRINT/SAVEAS/HGEXPORT to export the figure to an image file, then reading the image back from disk. This is approach#2 that you listed yourself in the question above.

    hFig = figure('Visible','off'); set(hFig, 'PaperPositionMode','auto', 'InvertHardCopy','off')  aviobj = avifile('file.avi'); for k=1:N     %#plot(...)     print(['-f' num2str(hFig)], '-zbuffer', '-r0', '-dpng', 'file.png')     img = imread('file.png');     aviobj = addframe(aviobj, im2frame(img)); end aviobj = close(aviobj); 
  3. using the undocumented HARDCOPY function to capture the figure in-memory.

    hFig = figure('Visible','off'); set(hFig, 'PaperPositionMode','auto')  aviobj = avifile('file.avi'); for k=1:N     %#plot(...)     img = hardcopy(hFig, '-dzbuffer', '-r0');     aviobj = addframe(aviobj, im2frame(img)); end aviobj = close(aviobj); 

    In fact, this is the underlying function that other functions use either directly or indirectly. By inspecting the source codes where possible, here is an illustration of the dependencies of the related functions where A --> B denotes A calls B:

    saveas [M-file] --> print [M-file] --> render [private M-file] --> hardcopy [P-file] hgexport [P-file] --> print [M-file] --> ... @avifile/addframe [M-file] --> hardcopy [P-file] 

    On the other hand, GETFRAME does not call HARDCOPY but an undocumented built-in function named CAPTURESCREEN (although it seems that it will be using PRINT for the upcoming HG2 system where there is a new -RGBImage print flag):

    getframe [M-file] --> capturescreen [builtin] 

Note: Since AVIFILE is now deprecated, you can replace it with the newer VIDEOWRITER in (2) and (3), but not in (1) since it does not support passing figure handle directly.

like image 119
Amro Avatar answered Oct 21 '22 19:10

Amro