Подтвердить что ты не робот

Отобразить фигуру 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(), и это проблематично при выполнении такой рендеринга в цикле (т.е. сохранение 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 растровому изображению?

4b9b3361

Ответ 1

Если вы создаете 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

Ответ 2

Я понимаю, что это старый поток, но я снова столкнулся с этой проблемой в последнее время, поэтому хотел обобщить мои выводы. Мой основной источник эта страница (кешировано). В соответствии с этим существует три альтернативы:

  • используя ADDFRAME непосредственно с помощью дескриптора фигуры (без использования GETFRAME). Это именно то, что @rescdsk показал в его ответе.

    hFig = figure('Visible','off');
    
    aviobj = avifile('file.avi');
    for k=1:N
        %#plot(...)
        aviobj = addframe(aviobj, hFig);
    end
    aviobj = close(aviobj);
    
  • используя 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);
    
  • используя недокументированную функцию 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 (хотя кажется, что она будет использовать PRINT для предстоящего HG2, где есть новый флаг печати -RGBImage):

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

Примечание: Поскольку AVIFILE теперь устарел, вы можете заменить его новым VIDEOWRITER в (2) и (3), но не в (1), так как он не поддерживает прямой передатчик фигуры.

Ответ 3

Запустите MATLAB в режиме безглавых: matlab -noFigureWindows

MATLAB работает в режиме без звука. Окна с рисунком не отображаются.

затем просто зарисуйте и сохраните цифры как обычно (вы не увидите графического вывода, конечно). Пример:

surf(peaks);
print output.eps     %# SAVEAS works as well
close

Я протестировал выше на машине под управлением Windows R2010a. У меня нет доступа к Unix-машине прямо сейчас, но я ответил на аналогичный вопрос в прошлом, и в то время он работал отлично (вам нужно будет отключите переменную $DISPLAY перед запуском MATLAB)


ИЗМЕНИТЬ

Другой вариант, если вы хотите сохранить нормальное рабочее пространство, - это запустить новый экземпляр MATLAB в фоновом режиме, который будет генерировать и сохранять графики (источник).

Запустите это из командной строки вашего текущего сеанса MATLAB (все в одной строке):

!start /B /MIN matlab -noFigureWindows 
                      -automation 
                      -r "cd('c:\yourpath'); myscript; quit"

Это запустит новый сеанс MATLAB в фоновом режиме (с использованием COM Automation) и выполнит script, называемый myscript (простой M файл), содержащий весь ваш код построения:

C:\yourpath\myscript.m

surf(peaks);
saveas(gcf, 'output.eps');

Ответ 4

Если 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);