And*_*ron 24 video matlab image screen-capture off-screen
是否有任何替代方法可以使用getframe和saveas将图形内容保存到光栅图像中以进行进一步处理?
方法1: getframe
h = figure('visible', 'off');
a = axes('parent', h);
% render using `scatter3()` or other plot function.
content = frame2im(getframe(h));
Run Code Online (Sandbox Code Playgroud)
这具有显示图形在调用中执行屏幕捕获的严重缺点,getframe()并且当在循环中执行这样的渲染时(即,content在每次迭代时将其保存为视频帧)存在问题.
方法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');
Run Code Online (Sandbox Code Playgroud)
这种方法具有写入磁盘的严重缺点,这在多线程应用程序中存在问题,并且比直接渲染到内存要慢.因为saveas()在调用PNG编码器之前显然会渲染到内存,所以我想要的是可能的,但我在MATLAB文档中找不到任何只执行渲染部分的函数.
问题:
您是否知道将任意axes内容渲染到光栅图像的替代方法?
Amr*_*mro 17
我意识到这是一个老线程,但我最近又遇到了这个问题,所以我想总结一下我的发现.我的主要来源是此页面(缓存).根据它,有三种选择:
直接使用ADDFRAME和数字句柄(不使用GETFRAME).这正是@rescdsk在答案中所表现出来的.
hFig = figure('Visible','off');
aviobj = avifile('file.avi');
for k=1:N
%#plot(...)
aviobj = addframe(aviobj, hFig);
end
aviobj = close(aviobj);
Run Code Online (Sandbox Code Playgroud)使用PRINT/SAVEAS/HGEXPORT将图形导出到图像文件,然后从磁盘读回图像.这是你在上面的问题中列出的方法#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);
Run Code Online (Sandbox Code Playgroud)使用未记录的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);
Run Code Online (Sandbox Code Playgroud)
实际上,这是其他函数直接或间接使用的基础函数.通过在可能的情况下检查源代码,这里是相关函数的依赖关系的说明,其中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]
Run Code Online (Sandbox Code Playgroud)
另一方面,GETFRAME不会调用HARDCOPY,而是一个名为CAPTURESCREEN的未记录的内置函数(虽然它似乎将使用PRINT用于即将出现的新打印标志的HG2系统-RGBImage):
getframe [M-file] --> capturescreen [builtin]
Run Code Online (Sandbox Code Playgroud)注意:由于现在不推荐使用AVIFILE,您可以将其替换为(2)和(3)中较新的VIDEOWRITER,但不能替换为(1),因为它不支持直接传递数字句柄.
如果用它创建一个avi文件avifile,然后用它添加帧addframe,MATLAB就不会像开始那样打开额外的可见数字getframe.
avi = avifile('/path/to/output');
figure_handle = figure('visible', 'off');
% ...
for something = 1:1000
cla
% (draw stuff...)
avi = addframe(avi, figure_handle);
end
Run Code Online (Sandbox Code Playgroud)
以无头模式启动MATLAB: matlab -noFigureWindows
MATLAB以无头模式运行.图窗口不会显示.
然后像往常一样简单地绘制并保存图形(当然,您不会看到任何图形输出).例:
surf(peaks);
print output.eps %# SAVEAS works as well
close
Run Code Online (Sandbox Code Playgroud)
我在运行R2010a的Windows机器上测试了上述内容.我现在无法访问Unix机器,但我过去回答了类似的问题,当时它运行得很好($DISPLAY在启动MATLAB之前需要取消设置变量)
编辑
如果你想保持正常的工作空间,另一个选择是在后台启动一个新的MATLAB实例,它将生成并保存图(源).
从当前MATLAB会话的命令提示符运行此命令(全部在同一行):
!start /B /MIN matlab -noFigureWindows
-automation
-r "cd('c:\yourpath'); myscript; quit"
Run Code Online (Sandbox Code Playgroud)
这将在后台启动一个新的MATLAB会话(使用COM Automation),并执行一个myscript包含所有绘图代码的脚本(一个简单的M文件):
surf(peaks);
saveas(gcf, 'output.eps');
Run Code Online (Sandbox Code Playgroud)