Matlabフィギュアをメモリにレンダリングします
-
30-09-2019 - |
質問
使用する代替手段はありますか getframe
と saveas
図の内容をラスター画像に保存するために、さらに処理するために?
アプローチ1: getframe
h = figure('visible', 'off');
a = axes('parent', h);
% render using `scatter3()` or other plot function.
content = frame2im(getframe(h));
これには、コールでスクリーンキャプチャを実行するためにフィギュアを表示するという深刻な欠点があります 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');
このアプローチには、ディスクへの書き込みの深刻な欠点があります。これは、マルチスレッドアプリケーションでは問題があり、メモリに直接レンダリングするよりも遅くなります。以来 saveas()
PNGエンコーダーを呼び出す前に明らかにメモリにレンダリングされますが、私が望むことは可能ですが、レンダリングパーツのみを実行するMATLABドキュメントには機能が見つかりません。
質問:
任意をレンダリングする別の方法を知っていますか axes
ラスター画像へのコンテンツ?
解決
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
他のヒント
私はこれが古いスレッドであることに気づきましたが、最近この問題に出会ったので、私の調査結果を要約したかったのです。私の主な情報源はです このページ (キャッシュ)。それによると、3つの選択肢があります。
使用 addframe フィギュアハンドルと直接(使用せずに GetFrame)。これはまさにそのことです @rescdsk 彼の答えに示されています。
hFig = figure('Visible','off'); aviobj = avifile('file.avi'); for k=1:N %#plot(...) aviobj = addframe(aviobj, hFig); end aviobj = close(aviobj);
使用 印刷/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);
文書化されていないハードコピー関数を使用して、フィギュア内のフィギュアをキャプチャします。
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はハードコピーではなく、CaptureScreenという名前の文書化されていない組み込み関数を呼び出します(ただし、今後の印刷を使用するようですが HG2システム 新しい場所があります
-RGBImage
フラグを印刷):getframe [M-file] --> capturescreen [builtin]
注:それ以来 Avifile これで非推奨になりました、あなたはそれを新しいものに置き換えることができます ビデオライター (2)および(3)では、(1)ではそうではありません。
ヘッドレスモードでMATLABを開始します: matlab -noFigureWindows
Matlabはヘッドレスモードで実行されています。図ウィンドウは表示されません。
次に、単に図をプロットして保存するだけです(もちろんグラフィカルな出力は表示されません)。例:
surf(peaks);
print output.eps %# SAVEAS works as well
close
R2010Aを実行しているWindowsマシンで上記をテストしました。私は今Unixマシンにアクセスしていませんが、私は答えました 同様の質問 過去に、そしてそれはその時点でうまくいった(あなたはセットする必要があるでしょう $DISPLAY
MATLABを開始する前の変数)
編集
別のオプションは、通常のワークスペースを保持したい場合に備えて、プロットを生成して保存するバックグラウンドで新しいMATLABインスタンスを開始することです(ソース).
現在のMATLABセッションのコマンドプロンプト(すべて同じ行)からこれを実行します。
!start /B /MIN matlab -noFigureWindows
-automation
-r "cd('c:\yourpath'); myscript; quit"
これにより、バックグラウンドで新しいMATLABセッションが開始され(com Automationを使用)、呼ばれるスクリプトを実行します 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);