在内存中渲染MATLAB图

有没有其他方法可以使用getframesaveas将graphics的内容保存到光栅图像中作进一步处理?

方法1: getframe

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

这具有严重的缺点,即在调用getframe()时执行屏幕截图,并且在循环中执行这样的渲染(即,在每次迭代时将content保存为video帧)是有问题的。

方法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'); 

这种方法存在严重的写入磁盘的缺点,这在multithreading应用程序中是有问题的,而且比直接渲染到内存要慢。 因为在调用PNG编码器之前saveas()显然会呈现给内存,所以我想要的是可能的,但是在MATLAB文档中我找不到任何只执行渲染部分的函数。

问题

您是否知道将任意axes内容渲染为光栅图像的替代方法?

如果你用addframe创build一个avi文件,然后用addframe向它添加帧,MATLAB不会像getframe那样打开额外的可见graphics。

 avi = avifile('/path/to/output'); figure_handle = figure('visible', 'off'); % ... for something = 1:1000 cla % (draw stuff...) avi = addframe(avi, figure_handle); end 

我意识到这是一个古老的线索,但最近又遇到了这个问题,所以我想总结一下我的发现。 我的主要来源是这个页面 ( caching )。 据此,有三种select:

  1. 直接使用ADDFRAME和数字句柄(不使用GETFRAME )。 这正是@rescdsk在他的回答中所performance的。

     hFig = figure('Visible','off'); aviobj = avifile('file.avi'); for k=1:N %#plot(...) aviobj = addframe(aviobj, hFig); end aviobj = close(aviobj); 
  2. 使用PRINT / SAVEAS / HGEXPORT将graphics导出到图像文件,然后从磁盘读取图像。 这是你在上面的问题中列出你自己的方法#2。

     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. 使用未logging的HARDCOPY函数来捕获内存中的数字。

     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); 

    实际上,这是其他函数直接或间接使用的基础函数。 通过在可能的情况下检查源代码,下面是相关函数的依赖关系的图示,其中A --> B表示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] 

    另一方面,GETFRAME不会调用HARDCOPY,而是一个名为CAPTURESCREEN的未logging的内置函数(虽然看起来它将在即将到来的HG2系统中使用PRINT,其中有一个新的-RGBImage打印标志):

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

注意:由于AVIFILE现在已经被弃用,可以用(2)和(3)中较新的VIDEOWRITERreplace它,但是不能在(1)中replace它,因为它不支持直接传递graphics句柄。

以无头模式启动MATLAB: matlab -noFigureWindows

MATLAB正在无头模式下运行。 graphics窗口将不会显示。

那么就像往常一样简单地绘制和保存数据(当然,您不会看到任何graphics输出)。 例:

 surf(peaks); print output.eps %# SAVEAS works as well close 

我在运行R2010a的Windows机器上testing了上述内容。 我现在还没有访问Unix机器,但是我回答了过去的一个类似的问题 ,当时它工作得很好(在启动MATLAB之前,您需要取消设置$DISPLAYvariables)


编辑

另一个选项,如果你想保持你的正常的工作空间,是在后台启动一个新的MATLAB实例,将生成并保存图( 源 )。

从当前MATLAB会话的命令提示符下运行(全部在同一行):

 !start /B /MIN matlab -noFigureWindows -automation -r "cd('c:\yourpath'); myscript; quit" 

这将在后台启动一个新的MATLAB会话(使用COM自动化),并执行一个名为myscript (一个简单的M文件)的脚本,其中包含所有的绘图代码:

C:\ yourpath \ myscript.m

 surf(peaks); saveas(gcf, 'output.eps'); 

随着avifile被弃用,这是你怎么用VideoWriter做到这一点:

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