2016-12-14 79 views
1

我有一個程序,創建了很多我想保存爲fig001, fig002, ...的地塊。目前,我可以做的唯一方法是在我使用print()或者將它們保存到圖形對象FIG中時一個一個地保存它們。計算快速的方法來保存Matlab圖像作爲圖像(例如PNG)

不幸的是,我必須按順序創建圖(不能平行)。如果我隨時保存,那麼這需要相當長的時間;如果我存儲在FIG那麼做一個parfor - 回放所有的數字,然後這是更快。但是,它仍然很慢,而且這是我的代碼中的一個主要瓶頸。

Matlab正在自動編寫一個1200x900像素的圖像。實際上,它只是一個包含一些(水平)直線的圖形。我真的不需要高質量的圖像,也許減少這將有助於加快速度?我也無法找到如何做到這一點。

我已經看過網上,特別是在其他SE問題,但我一直沒有能夠想出一個解決方案。有很多關於「玩弄hardcore功能」的東西。我是一個數學家,他想要一個代碼來獲得問題的直覺;我不是一個合適的程序員!因此,「玩弄一個功能」(可能會導致Matlab崩潰)對我來說是相當困難的!


我已經使用Matlab movie函數對此進行了排序。謝謝Cecilia的幫助!

+1

如果您只是對定義一條線的圖上的幾個點感興趣,則可以將這些點座標保存在文本文件中。然後您可以使用該文件快速重現圖形。 – Cecilia

+0

所以是的,我只有幾點,但我真的想把它們生成圖形,我可以保存爲'.png'文件。原因是我然後想從圖表中做出'幻燈片'(例如,使用FFMPEG)。 –

+0

要回答您關於更改圖像分辨率的問題:[以特定大小和分辨率保存圖形](https://www.mathworks.com/help/matlab/creating_plots/save-figure-at-specific-size-and-resolution .html) – Cecilia

回答

3

由於您的目的是在幻燈片中使用圖像。我會建議製作一部電影並使用它。我已經運行了一些測試,保存電影比保存單個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相關的開銷,所以它可能不會更高效。

+0

讓我知道你是否需要製作電影的更多細節。 – Cecilia

+0

只需添加到塞西莉亞,其原因是基於它創建的文件數量。不幸的是,matlab需要相當長的時間來打開文件然後關閉它。這就是爲什麼視頻比一系列圖像顯着更快(僅打開和關閉一個文件)的原因。 –

+0

@DanielAldrich這是我發現的問題,即'print'的開銷太大了。 –

1

如果您製作Matlab輸出一個像這樣的文件,稱爲「行」。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 

enter image description here

顯然,可以繪製非水平線和你能輸出的x,y座標和/或厚度後的彩色...

ImageMagick安裝在大多數Linux發行版上,可用於OSX和Windows。有更有效的方式來繪製線條,但這可能是很多讓你開始。

另一種選擇可能是使用Gnuplot,看我的其他答案here

+0

非常感謝。我要先試試'電影'選項,但如果我不能得到這個工作,那麼我會看看你的! :) –