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

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

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

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

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

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

Источник видеосигнала

Создайте объект читателя видеофайла импортировать видеофайл в рабочее пространство MATLAB. Файл источника видеосигнала является форматом на 240 пунктов. Создайте объект видеоплеера отобразить входной кадр, Simulink отфильтровал кадр и кадр ссылки 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, заданные здесь.

Функция edge MATLAB интерпретирует порог как значение с двойной точностью от 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 кадры. Шаг расчета Источника видеосигнала является 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 и добавляет их вместе. С аппаратной реализацией в памяти, подсистема Наложения Изображений включает настройки канала связи вокруг каждого множителя и после сумматора.

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

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

Смотрите также

|

Похожие темы