在内存中渲染 MATLAB 图窗
除了使用 getframe 和 saveas 将图形内容保存到光栅图像以供进一步处理之外,还有其他选择吗?
方法 1:getframe
h = figure('visible', 'off');
a = axes('parent', h);
% render using `scatter3()` or other plot function.
content = frame2im(getframe(h));
这有一个严重的缺点,即在调用 getframe()
时显示图形以执行屏幕捕获,并且存在问题在循环中执行此类渲染时(即在每次迭代时将内容保存为视频帧)。
方法 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');
这种方法具有写入磁盘的严重缺点,这在多线程应用程序中是有问题的,并且比直接渲染到内存要慢。由于 saveas()
显然会在调用 PNG 编码器之前渲染到内存,所以我想要的是可能的,但我在 MATLAB 文档中找不到任何仅执行渲染部分的函数。
问题:
您是否知道将任意轴
内容渲染到光栅图像的替代方法?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我意识到这是一个旧线程,但最近我又遇到了这个问题,所以我想总结一下我的发现。我的主要来源是此页面(缓存)。根据它,有三种选择:
使用ADDFRAME 直接使用图形句柄(不使用 GETFRAME)。这正是 @rescdsk 在他的答案中所显示的内容。
使用打印/保存/HGEXPORT 将图形导出到图像文件,然后从磁盘读回图像。这是您在上面的问题中列出的方法#2。
使用未记录的 HARDCOPY 函数来捕获内存中的图形。
事实上,这是其他函数直接或间接使用的底层函数。通过尽可能检查源代码,以下是相关函数的依赖关系的说明,其中
A --> B
表示A 调用 B
:另一方面,GETFRAME 不会调用 HARDCOPY,而是调用一个名为 CAPTURESCREEN 的未记录的内置函数(尽管它似乎将在即将推出的 HG2 系统,其中有一个新的
-RGBImage
打印标志):注意:由于 AVIFILE 现已弃用,您可以将其替换为(2) 和 (3) 中较新的 VIDEOWRITER ,但不在(1) 因为它不支持直接传递图形句柄。
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:
using ADDFRAME directly with the figure handle (without using GETFRAME). This is exactly what @rescdsk has shown in his answer.
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.
using the undocumented HARDCOPY function to capture the figure in-memory.
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
denotesA calls B
: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):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.
如果您使用
avifile
创建一个 avi 文件,然后使用addframe
添加帧,MATLAB 不会像使用getframe< 那样打开额外的可见图形。 /代码>。
If you create an avi file with
avifile
, and then add frames to it withaddframe
, MATLAB doesn't open up extra visible figures like it does withgetframe
.以无头模式启动 MATLAB:
matlab -noFigureWindows
然后像往常一样简单地绘制并保存图形(当然您不会看到任何图形输出)。示例:
我在运行 R2010a 的 Windows 机器上测试了上述内容。我现在无法访问 Unix 机器,但我回答了 过去有过类似的问题,当时效果很好(您需要在开始之前取消设置
$DISPLAY
变量MATLAB)编辑
如果您想保留正常工作区,另一种选择是在后台启动一个新的 MATLAB 实例,该实例将生成并保存绘图 (来源)。
从当前 MATLAB 会话的命令提示符运行此命令(全部在同一行):
这将在后台启动一个新的 MATLAB 会话(使用 COM 自动化),并执行名为
myscript
的脚本(简单的 M 文件),其中包含所有绘图代码:c:\yourpath\myscript.m
Start MATLAB in headless mode:
matlab -noFigureWindows
then simply plot and save the figures as usual (you won't see any graphical output of course). Example:
I tested the above on a Windows machine running R2010a. I don't have access to a Unix machine right now, but I answered a similar question in the past, and it worked just fine at the time (you will need to unset the
$DISPLAY
variable before starting MATLAB)EDIT
Another option, in case you want to keep your normal workspace, is to start a new MATLAB instance in the background which will generate and save the plots (source).
Run this from the command prompt of your current MATLAB session (all on the same line):
This will start a new MATLAB session in the background (using COM Automation), and execute a script called
myscript
(a simple M-file) that contains all your plotting code:c:\yourpath\myscript.m
随着
avifile
被弃用,您可以使用 VideoWriter 执行此操作:With
avifile
being deprecated, this is how you do it with VideoWriter: