将Matlab图形保存为图像的计算快速方法(例如PNG)
我有一个程序,可以创建许多绘图,我想将其另存为将Matlab图形保存为图像的计算快速方法(例如PNG),matlab,performance,matlab-figure,Matlab,Performance,Matlab Figure,我有一个程序,可以创建许多绘图,我想将其另存为fig001、fig002、。目前,我唯一能做的就是使用print()将它们逐个保存,或者将它们保存到图形对象FIG 不幸的是,我必须按顺序创建绘图(无法并行)。如果我边走边储蓄,那么这需要相当长的时间;如果我存储在FIG中,然后在所有图形上执行parfor-循环,则速度更快。然而,它仍然非常慢,这是我代码中的一个主要瓶颈 Matlab正在自动编写1200x900像素图像。实际上,它只是一个带有一些(水平)直线的图形。我真的不需要高质量的图像;也许减
fig001、fig002、
。目前,我唯一能做的就是使用print()
将它们逐个保存,或者将它们保存到图形对象FIG
不幸的是,我必须按顺序创建绘图(无法并行)。如果我边走边储蓄,那么这需要相当长的时间;如果我存储在FIG
中,然后在所有图形上执行parfor
-循环,则速度更快。然而,它仍然非常慢,这是我代码中的一个主要瓶颈
Matlab正在自动编写1200x900
像素图像。实际上,它只是一个带有一些(水平)直线的图形。我真的不需要高质量的图像;也许减少这个会有助于加快速度?我也不知道怎么做
我在网上看了一下,特别是其他SE问题,但我还没有找到解决方案。关于“玩弄核心功能”有各种各样的内容。我是一个数学家,想要一个代码来获得问题的直觉;我不是一个合适的程序员!因此,“玩转函数”(这可能会导致Matlab崩溃)对我来说相当困难
我已经使用Matlabmovie
函数对其进行了排序。谢谢塞西莉亚的帮助 因为您的目的是在幻灯片中使用图像。我建议拍一部电影,用它来代替。我已经运行了一些测试,保存一部电影要比保存单个PNG快得多。在我的简单测试中,我看到速度大约提高了5倍
numImages = 25;
%Saving one figure at a time
tic;
for i= 1:numImages
x = 0:0.1:2*pi;
y = i*sin(x);
plot(x, y);
fig = gcf;
print('img.png', '-dpng', '-r50'); %Downsample resolution
end
toc;
tic;
%Saving a movie
v = VideoWriter('mov.avi');
open(v);
for i = 1:numImages
x = 0:0.1:2*pi;
y = i*sin(x);
plot(x, y);
drawnow; %Force the figure to render
frame = getframe; %Convert the figure to a movie frame
writeVideo(v, frame); %Write the frame to the movie file
end
close(v);
toc;
使用writeVideo还有一个优点,就是永远不会将整个电影存储在内存中。相反,在捕获每个帧时,它会立即写入文件。一个缺点是,由于帧需要以正确的顺序写入,因此不能使用parfor
你也可以考虑制作一个电影矩阵。每个元素都是一个框架。所以要初始化矩阵的大小,需要
numImages = 25;
mov(numImages) = struct('cdata',[],'colormap',[]);
然后使用parfor
,您可以按照正确的顺序将所有图像分配给mov
矩阵。循环完成后,可以使用VideoWriter
将电影写入文件。但是,在生成图形时,您需要将整个电影保存在内存中,并且与parfor
相关的开销也很大,因此它可能不会更有效 如果您让Matlab输出这样一个名为“lines.txt”的文件,其中每一行描述输出图像上一行的x1、y1和x2、y2:
10 100 600 100
50 400 800 400
100 820 350 820
然后您可以使用ImageMagick绘制如下线条:
#!/bin/bash
# Create the output image, 1200x900
convert -size 1200x900 xc:gray80 result.png
# Loop, reading one line at a time from the file "lines.txt"
while read x1 y1 x2 y2; do
echo Read line $x1,$y1 $x2,$y2
# Tell ImageMagick to draw the line on the image
convert result.png -stroke blue -strokewidth 5 -draw "line $x1,$y1 $x2,$y2" result.png
done < lines.txt
#/bin/bash
#创建输出图像1200x900
转换-大小1200x900 xc:gray80 result.png
#循环,从文件“lines.txt”中一次读取一行
当读取x1 y1 x2 y2时;做
回显读取行$x1、$y1$x2、$y2
#让ImageMagick在图像上画线
convert result.png-蓝色笔划-笔划宽度5-绘制“line$x1,$y1$x2,$y2”result.png
done
显然,您可以绘制非水平线,并且可以在x、y坐标和/或厚度后输出颜色
ImageMagick安装在大多数Linux发行版上,可用于OSX和Windows。有更有效的方法绘制线条,但这可能足以让您开始
另一个选项可能是使用Gnuplot,请参阅我的其他答案。除了Cecilia的答案建议使用getframe
生成电影之外,我想补充一点,getframe
还可以用于提高保存静态图像的速度。将其与frame2im
组合以将图形转换为光栅化图像,然后使用imwrite
将光栅化图像保存到文件中
frame = getframe(fig); % fig is the figure handle to save
[raster, raster_map] = frame2im(frame); % raster is the rasterized image, raster_map is the colormap
if isempty(raster_map)
imwrite(raster, fig_file);
else
imwrite(raster, raster_map, fig_file); % fig_file is the path to the image
end
在我的特殊情况下,使用此方法保存数字的时间从19个文件的~60秒(使用saveas
)减少到7~9秒
请注意,此方法
不会像saveas
那样将背景颜色更改为白色李>
除目前的数字外,似乎不支持决议和新闻部李>
不支持保存为矢量图像(显然)
如果您对图形上定义直线的几个点感兴趣,可以将这些点坐标保存在文本文件中。然后您可以使用该文件快速复制图形。因此,是的,我只有几点,但我真的想将它们生成图形,我可以将其另存为,.png
文件。这样做的原因是,我想从图形中进行“幻灯片放映”(例如,使用FFMPEG)。为了回答您关于更改图像分辨率的问题:@Cecilia我更多地考虑一个特定的像素大小,但进一步看,我想我可以说“-r100”,这就给了我800x600
文件。在测试中,这些文件的编写速度比1200x900
文件快得多,但实际上并不比40x30
文件快。它仍然比我想要的慢很多…:/您是否考虑过制作4D矩阵并将其保存为.avi或动画gif以显示幻灯片?如果您需要有关制作电影的更多详细信息,请告诉我。只需添加到Cecilia,原因是它创建的文件数。不幸的是,matlab打开一个文件然后关闭它需要相当长的时间。这就是为什么视频比一系列图像要快得多(只有一个文件可以打开和关闭)。@Danielldrich这就是我发现的问题,即打印的开销太大了。@Cecilia谢谢你。与其说frame=getframe
,然后将该帧添加到视频的末尾(我假设writeVid),是否可能更好