25

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');

このアプローチには、ディスクへの書き込みという重大な欠点があります。これは、マルチスレッドアプリケーションでは問題があり、メモリに直接レンダリングするよりも低速です。PNGエンコーダーを呼び出す前に明らかにメモリにレンダリングされるのでsaveas()、私が望むことは可能ですが、レンダリング部分のみを実行する関数をMATLABドキュメントで見つけることができません。

質問

任意のaxesコンテンツをラスターイメージにレンダリングする別の方法を知っていますか?

4

4 に答える 4

18

これは古いスレッドだと思いますが、最近またこの問題に遭遇したので、調査結果を要約したいと思います。私の主な情報源はこのページですキャッシュされています)。それによると、3つの選択肢があります:

  1. フィギュアハンドルで直接ADDFRAMEを使用する( GETFRAMEを使用しない)。これはまさに@rescdskが彼の答えで示したものです。

    hFig = figure('Visible','off');
    
    aviobj = avifile('file.avi');
    for k=1:N
        %#plot(...)
        aviobj = addframe(aviobj, hFig);
    end
    aviobj = close(aviobj);
    
  2. 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);
    
  3. 文書化されていない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);
    

    実際、これは他の関数が直接または間接的に使用する基本的な関数です。可能な場合はソースコードを調べて、関連する関数の依存関係を示します。ここで、は次のことを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はHARDCOPYを呼び出しませんが、CAPTURESCREENという名前の文書化されていない組み込み関数を呼び出します(ただし、新しい印刷フラグがある次のHG2システムにはPRINTを使用するようです)。-RGBImage

    getframe [M-file] --> capturescreen [builtin]
    

注:AVIFILEは非推奨になったため、(2)と(3)で新しいVIDEOWRITERに置き換えることができますが、図のハンドルを直接渡すことはサポートされていないため、(1)では置き換えることができません。

于 2012-10-25T22:51:29.240 に答える
10

を使用して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
于 2010-11-09T21:09:06.560 に答える
7

ヘッドレスモードで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"

これにより、バックグラウンドで(COM Automationを使用して)新しいMATLABセッションが開始され、myscriptすべてのプロットコードを含む(単純なMファイル)というスクリプトが実行されます。

c:\ yourpath \ myscript.m

surf(peaks);
saveas(gcf, 'output.eps');
于 2010-11-09T21:05:26.550 に答える
2

非推奨になったことで、 VideoWriteravifileでこれを行う方法は次のとおりです。

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);
于 2015-05-06T07:18:49.853 に答える