Рабочий процесс от алгоритма обработки видео MATLAB до его аппаратной реализации в Simulink

В этом примере показано, как создать аппаратно-целевой проект в Simulink ®, которая реализует то же поведение, что и исходный проект MATLAB ®.

Рабочий процесс

Функции Image Processing Toolbox™ и Computer Vision Toolbox™ работают с обрамленными, с целочисленными данными с плавающей точкой и обеспечивают отличные поведенческие ссылки. Аппаратные проекты должны использовать потоковые логические данные или данные с фиксированной точкой.

Этот пример показывает, как выполнить операцию обработки изображения с рамкой в MATLAB, а затем реализовать эту же операцию в модели Simulink с использованием потоковых данных. Модель Simulink преобразует входное видео в поток пикселей для аппаратного проекта. Те же данные применяются и к аппаратному алгоритму в Simulink, и к поведенческому алгоритму в MATLAB. Модель Simulink преобразует выход пикселя в системы координат и экспортирует эти системы координат в MATLAB для сравнения с поведенческими результатами.

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

Источник видео

Создайте объект файла чтения видео, чтобы импортировать видео файла в Рабочее пространство MATLAB. Исходный файл видео имеет формат 240p. Создайте объект видеоплеера, чтобы отобразить входной кадр, систему координат Simulink filtered и системы координат MATLAB.

videoIn = vision.VideoFileReader(...
        'Filename','rhinos.avi',...
        'ImageColorSpace','Intensity',...
        'VideoOutputDataType','uint8');

numFrm = 10;
% active frame dimensions
actPixelsPerLine = 320;
actLines = 240;
% dimensions including blanking
totalPixelsPerLine = 402;
totalLines = 324;

% viewer for results
viewer = vision.DeployableVideoPlayer(...
        'Size','Custom',...
        'CustomSize',[3*actPixelsPerLine actLines]);

Обнаружение ребер и наложение

Обнаружите ребра в видеокадрах, а затем наложите эти ребра на исходную систему координат. В расчете наложения используется alpha значение для смешения двух значений пикселей. Модель Simulink также использует edgeThreshold и alpha параметры, указанные здесь.

Система MATLAB edge функция интерпретирует порог как значение двойной точности от 0 до 1. Поэтому выразите порог как часть области значений uint8 тип данных, от 0 до 255. Значения пикселей, возвращенные edge функции logical тип данных. Чтобы преобразовать эти пиксельные значения в uint8 тип для наложения, умножить на 255. Эта операция масштабирования преобразует логические таковые в 255 и логические нули остаются 0.

edgeThreshold = 8;
alpha = 0.75;
frmFull = uint8(zeros(actLines,actPixelsPerLine,numFrm));
frmRef = frmFull;
for f = 1:numFrm
    frmFull(:,:,f) = videoIn();
    edges = edge(frmFull(:,:,f),'Sobel',edgeThreshold/255,'nothinning');
    edges8 = 255*uint8(edges)*(1-alpha);
    frmRef(:,:,f) = alpha*frmFull(:,:,f) + edges8;
    viewer([edges edges8 frmRef(:,:,f)]);
end

Настройте для симуляции Simulink

Модель Simulink загружает входное видео в модель с помощью блока Video Source. Сконфигурируйте шаг расчета модели с помощью totPixPerFrame переменная. Это значение включает неактивные пиксельные области вокруг 240 на 320 системы координат. Video Source шага расчета 1 временной шаг в систему координат, и скорость в разделах потокового пикселя модели 1/ totPixPerFrame . Установите длину симуляции с simTime переменная.

totPixPerFrame = totalPixelsPerLine*totalLines;
simTime = (numFrm+1)*totPixPerFrame;

modelname = 'VerifySLDesignAgainstMLReference';
open_system(modelname);
set_param(modelname,'SampleTimeColors','on');
set_param(modelname,'SimulationCommand','Update');
set_param(modelname,'Open','on');

Аппаратно-целевой алгоритм

Подсистема Алгоритма HDL предназначена для поддержки генерации HDL-кода.

Подсистема использует блок Edge Detector для поиска ребер. Выходы блока являются потоком boolean пиксельные значения. Модель масштабирует эти значения, чтобы uint8 значения типа данных для наложения.

Блок возвращает поток пикселей обнаруженных ребер после нескольких строк задержки, из-за внутренних буферов линий и логики фильтра. Перед выполнением наложения модель должна задержать входной поток, чтобы соответствовать пограничному потоку. Блок Pixel Stream Aligner выполняет это выравнивание, используя сигналы управления выходного пограничного потока в качестве опорного. Этот блок сохраняет входной поток в FIFO до тех пор, пока обнаруженные ребра не будут доступны.

Подсистема наложения изображений масштабирует оба потока по alpha и добавляет их вместе. Учитывая аппаратную реализацию, подсистема Image Overlay включает этапы конвейера вокруг каждого множителя и после сумматора.

Для получения дополнительной информации об этой конструкции детектора ребер смотрите пример обнаружения ребер и наложения изображений.

open_system([modelname '/HDL Algorithm']);

Запуск модели Simulink

Запустите модель Simulink, чтобы вернуть десять систем координат, наложенных на обнаруженные ребра.

sim('VerifySLDesignAgainstMLReference');

Сравнение результатов Simulink с результатами MATLAB

Сравните каждый видеокадр, возвращенный Simulink, с результатом, возвращенным поведенческим кодом MATLAB. Изображения выглядят очень похожими, но имеют небольшие различия в значениях пикселей из-за смешения наложений. Смешение наложения MATLAB выполняется с использованием значений с плавающей точкой, и смешение наложения Simulink осуществляется с использованием значений с фиксированной точкой. Это сравнение отсчитывает пиксели в каждой системе координат, значения которых различаются более чем на 2, и вычисляет отношение пик-сигнал к шуму (PSNR) между системами координат. Чтобы просмотреть подробные различия в каждой системе координат, раскомментируйте последние две линии в цикле.

 for f = 1:numFrm
    frmResult = frmOut.signals.values(:,:,f);
    viewer([frmFull(:,:,f) frmResult frmRef(:,:,f)]);
    diff = frmRef(:,:,f) - frmResult;
    errcnt = sum(diff(:) > 2);
    noisecheck = psnr(frmRef(:,:,f),frmResult);
    fprintf(['\nFrame #%d has %d pixels that differ from behavioral result (by more than 2). PSNR = %2.2f\n'],f,errcnt,noisecheck);
    %bar3(diff);
    %viewer([frmResult frmRef(:,:,f) diff]);
 end
Frame #1 has 2 pixels that differ from behavioral result (by more than 2). PSNR = 48.33

Frame #2 has 1 pixels that differ from behavioral result (by more than 2). PSNR = 48.72

Frame #3 has 1 pixels that differ from behavioral result (by more than 2). PSNR = 48.80

Frame #4 has 2 pixels that differ from behavioral result (by more than 2). PSNR = 48.66

Frame #5 has 2 pixels that differ from behavioral result (by more than 2). PSNR = 48.70

Frame #6 has 4 pixels that differ from behavioral result (by more than 2). PSNR = 48.27

Frame #7 has 2 pixels that differ from behavioral result (by more than 2). PSNR = 48.88

Frame #8 has 3 pixels that differ from behavioral result (by more than 2). PSNR = 48.58

Frame #9 has 3 pixels that differ from behavioral result (by more than 2). PSNR = 48.55

Frame #10 has 3 pixels that differ from behavioral result (by more than 2). PSNR = 48.53

Сгенерируйте HDL-код и проверьте его поведение

Когда ваш проект работает в симуляции, вы можете использовать HDL- Coder™ для генерации HDL-кода и испытательного стенда для подсистемы HDL-алгоритма.

makehdl([modelname '/HDL Algorithm'])   % Generate HDL code
makehdltb([modelname '/HDL Algorithm']) % Generate HDL Test bench

См. также

|

Похожие темы