Автор хочет поделится своим опытом организации быстрой перерисовки графиков (точнее сказать, изображений,) в Матлабе на примере организации радиолокационного индикатора кругового обзора (ИКО, он же в англоязычной литературе PPI).
Суть в том, что в том же Матлабе был написан имитатор радиолокационного сигнала, отправлявшего данные по сети. И, с другой стороны, для проверки, подключалась машинка с Матлабом, которая принимал данные по сети и отображала их на ИКО-подобном индикаторе. Даже те, кто далёк от радиолокационной тематики, наверняка видели ИКО хотя бы в фильмах. В Матлабе эта штука выглядит так:
![image](https://habrastorage.org/getpro/habr/post_images/59b/64b/d4e/59b64bd4e09d0c477d1bd7046657ceaf.gif)
Угловой ползунок изображает положение луча антенны РЛС. У реальной РЛС антенна делала полный оборот за 4-6 секунд и была поставлена задача добиться скорости отображения максимально близкой к real-time.
Но как выводить такое изображение на график? Использовать оператор Матлаба polar? Не реально, скорость вывода будет просто черепашьей.
В начале была предпринята попытка вывести на экран изображение с помощью стандартных средств Matlab'а: указаний image (ну, или, imagesc). Результат был печален: image позволял сделать один полный оборот на экране минуты за 2, т.е. раз в 20 медленнее требуемого.
Но выход из положения был найден. Оказалось, что есть многократно более быстрый способ вывода изображения на экран. Для этого команда image даётся только один раз и ссылка на неё запоминается
Далее — создаётся матрица — копия изображения. Начальную загрузку этой матрицы можно сделать из свойств объекта h например так:
Выполняются необходимые расчёты и внесение изменений в матрицу ImageMatrix. После чего новая матрица выводится на экран командами
Такой вывод минимум на порядок (а реально — больше) быстрее, чем когда каждый раз вызывают команду image.
Для того, что бы не перерисовывать разметку и бегунок (тем более, что использовалась палитра gray, так что было бы проблематично их нарисовать цветными) линии, дальностные окружности, угловой бегунок и цифры рисовались командами line, text, ellipse и т.д. Единственная проблема, которая при этом возникала — пересчёт координат (график и линии, увы, живут в разных мирах в Матлабе). Причём, т.к.было очень лень не было времени досконально разбираться с этими перерасчётами делалось так: включив меню «Annotation», элементы разметки рисовались от руки и переносились в код автоматически. В результате есть некоторые неточности: на картинке видно, что начало углового бегунка слегка не попадает в центр ИКО.
В конечном итоге на машине с процессором i7, 16Гбайт ОЗУ и видеокартой GeForce 690 при применении CUDA-возможностей видеокарты программа укладывалась в real-time, даже несмотря на использование объектно-ориентированного стиля программирования в Матлабе. Это позволило избежать утомительного этапа переноса программы из Матлаба на C/C++ или Delphi.
Надеюсь, этот приём кому-нибудь пригодится.
Суть в том, что в том же Матлабе был написан имитатор радиолокационного сигнала, отправлявшего данные по сети. И, с другой стороны, для проверки, подключалась машинка с Матлабом, которая принимал данные по сети и отображала их на ИКО-подобном индикаторе. Даже те, кто далёк от радиолокационной тематики, наверняка видели ИКО хотя бы в фильмах. В Матлабе эта штука выглядит так:
![image](https://habrastorage.org/getpro/habr/post_images/59b/64b/d4e/59b64bd4e09d0c477d1bd7046657ceaf.gif)
Угловой ползунок изображает положение луча антенны РЛС. У реальной РЛС антенна делала полный оборот за 4-6 секунд и была поставлена задача добиться скорости отображения максимально близкой к real-time.
Но как выводить такое изображение на график? Использовать оператор Матлаба polar? Не реально, скорость вывода будет просто черепашьей.
В начале была предпринята попытка вывести на экран изображение с помощью стандартных средств Matlab'а: указаний image (ну, или, imagesc). Результат был печален: image позволял сделать один полный оборот на экране минуты за 2, т.е. раз в 20 медленнее требуемого.
Но выход из положения был найден. Оказалось, что есть многократно более быстрый способ вывода изображения на экран. Для этого команда image даётся только один раз и ссылка на неё запоминается
h = image(...
Далее — создаётся матрица — копия изображения. Начальную загрузку этой матрицы можно сделать из свойств объекта h например так:
ImageMatrix = get(h,'CData');
Выполняются необходимые расчёты и внесение изменений в матрицу ImageMatrix. После чего новая матрица выводится на экран командами
set(h,'CData',ImageMatrix); drawnow;
Такой вывод минимум на порядок (а реально — больше) быстрее, чем когда каждый раз вызывают команду image.
Для того, что бы не перерисовывать разметку и бегунок (тем более, что использовалась палитра gray, так что было бы проблематично их нарисовать цветными) линии, дальностные окружности, угловой бегунок и цифры рисовались командами line, text, ellipse и т.д. Единственная проблема, которая при этом возникала — пересчёт координат (график и линии, увы, живут в разных мирах в Матлабе). Причём, т.к.
В конечном итоге на машине с процессором i7, 16Гбайт ОЗУ и видеокартой GeForce 690 при применении CUDA-возможностей видеокарты программа укладывалась в real-time, даже несмотря на использование объектно-ориентированного стиля программирования в Матлабе. Это позволило избежать утомительного этапа переноса программы из Матлаба на C/C++ или Delphi.
Надеюсь, этот приём кому-нибудь пригодится.