exponenta event banner

Определение полосы движения

В этом примере показано, как реализовать алгоритм обнаружения разметки полосы для FPGA.

Обнаружение полосы движения является важным этапом обработки в расширенных системах помощи при вождении (ADAS). Автоматическое обнаружение границ полосы движения из видеопотока является сложной вычислительной задачей, и поэтому для достижения производительности в реальном времени часто требуются аппаратные ускорители, такие как FPGA и GPU.

В этой примерной модели генератор-кандидат на дорожку на основе FPGA связан с программным механизмом полиномиальных фитингов для определения границ полосы.

Обзор системы

Систему LaneDetectionHDL.slx показывают ниже. Подсистема HDLaneDetector представляет аппаратно ускоренную часть конструкции, в то время как подсистема SWLaneFitandOverlay представляет программно основанный механизм полиномиальных фитингов. Перед блоком Frame to Pixels входной сигнал RGB преобразуется в цветовое пространство интенсивности.

Детектор полосы HDL

Детектор полосы HDL представляет собой аппаратно ускоренную часть конструкции. Эта подсистема принимает входной поток пикселей от источника фронтальной камеры, преобразует вид для получения вида «птица-глаз», определяет местоположение разметки полосы движения кандидатов из преобразованного вида и затем буферизирует их в вектор для передачи на программную сторону для подгонки кривой и наложения.

Вид на птиц

Блок «Birds-Eye View» преобразует вид камеры спереди в вид «birds-eye». Работа с изображениями в этом ракурсе упрощает требования к обработке алгоритмов обнаружения нисходящих полос. Вид спереди страдает от искажения перспективы, в результате чего полосы сходятся в точке исчезновения. Искажение перспективы корректируется путем применения обратного преобразования перспективы.

Обратное перспективное отображение (IPM) задается следующим выражением:

$$(\hat{x},\hat{y}) = round\left(\frac{h_{11}x + h_{12}y + h_{13}}{h_{31}x + h_{32}y + h_{33}}, \frac{h_{21}x + h_{22}y + h_{23}}{h_{31}x + h_{32}y + h_{33}}\right)$$

Матрица гомографии h получена из четырех собственных параметров настройки физической камеры, а именно фокусного расстояния, шага, высоты и основной точки (из модели камеры с точечным отверстием). Дополнительные сведения см. в документации по Toolbox™ компьютерного зрения.

Матрицу гомографии можно оценить с помощью компьютерного зрения Toolbox™ estimateGeometricTransform2D функции или Toolbox™ обработки изображений fitgeotrans для создания функции projective2d объект. Эти функции требуют набора согласованных точек между исходным кадром и кадром наблюдения птиц. Точки исходного кадра принимаются в качестве вершин интересующей трапециевидной области и могут выходить за пределы исходного кадра для захвата большей области. Для показанной трапеции отображение точек:

$$sourcePoints = [c_{x},c_{y};\ d_{x},d_{y};\ a_{x},a_{y};\ b_{x},b_{y}]$$

$$birdsEyePoints = [1,1;\ bAPPL,1;\ 1,bAVL;\ bAPPL,bAVL]$$

Где bAPPL и bAVL являются активными пикселями просмотра «птица-глаз» на строку и активными видеолиниями соответственно.

Прямая оценка отображения источника (лицевой стороны) на место назначения (птичий глаз) в реальном времени на аппаратном обеспечении FPGA/ASIC является сложной задачей. Требование к разделению наряду с потенциалом несистематического доступа к памяти из кадрового буфера означает, что вычислительные требования этой части конструкции являются существенными. Поэтому вместо непосредственной оценки вычисления IPM в реальном времени был выполнен автономный анализ отображения входных и выходных данных, который использовался для предварительного вычисления схемы отображения. Это возможно, так как матрица гомографии фиксируется после заводской калибровки/установки камеры из-за фиксированного положения камеры, высоты и шага.

В этом конкретном примере выходное изображение «птица-глаз» представляет собой кадр размером [700x640], тогда как переднее входное изображение имеет размеры [480x640]. Недостаточно гашения для вывода полного кадра «птичий глаз» перед тем, как следующий вход фронтальной камеры войдет в поток. Поэтому блок просмотра Birds-Eye не будет принимать какие-либо новые данные кадра, пока не завершит обработку текущего кадра birds-eye.

Буферизация строк и вычисление адресов

Полноразмерное проективное преобразование от входа к выходу приведет к выходному изображению [900x640]. Это требует, чтобы полное входное изображение [480x640] сохранялось в памяти, в то время как местоположение исходного пикселя вычислялось с использованием исходного местоположения и матрицы гомографии. В идеале для этой цели следует использовать встроенную память, устраняя необходимость в буфере кадров вне микросхемы.

Можно определить количество строк для буферизации на кристалле, выполнив обратное отображение строк с помощью матрицы гомографии. Следующий сценарий вычисляет матрицу гомографии из сопоставления точек, используя ее для обратного преобразования, чтобы отобразить строки исходного кадра на строки вида «птица-глаз».

% Source & Birds-Eye Frame Parameters
%   AVL:  Active Video Lines, APPL: Active Pixels Per Line
sAVL  = 480;
sAPPL = 640;
% Birds-Eye Frame
bAVL  = 700;
bAPPL = 640;
% Determine Homography Matrix
%   Point Mapping [NW; NE; SW; SE]
sourcePoints   = [218,196; 421,196; -629,405; 1276,405];
birdsEyePoints = [001,001; 640,001;  001,900;  640,900];
%   Estimate Transform
tf = estimateGeometricTransform2D(sourcePoints,birdsEyePoints,'projective');
%   Homography Matrix
h = tf.T;
% Visualize Birds-Eye ROI on Source Frame
vidObj   = VideoReader('visionhdl_caltech.avi');
vidFrame = readFrame(vidObj);
vidFrameAnnotated = insertShape(vidFrame,'Polygon',[sourcePoints(1,:) ...
    sourcePoints(2,:) sourcePoints(4,:) sourcePoints(3,:)],           ...
    'LineWidth',5,'Color','red');
vidFrameAnnotated = insertShape(vidFrameAnnotated,'FilledPolygon',    ...
    [sourcePoints(1,:) sourcePoints(2,:) sourcePoints(4,:)            ...
    sourcePoints(3,:)],'LineWidth',5,'Color','red','Opacity',0.2);
figure(1);
subplot(2,1,1);
imshow(vidFrameAnnotated)
title('Source Video Frame');
% Determine Required Birds-Eye Line Buffer Depth
%   Inverse Row Mapping at Frame Centre
x = round(sourcePoints(2,1)-((sourcePoints(2,1)-sourcePoints(1,1))/2));
Y = zeros(1,bAVL);
for ii = 1:1:bAVL
    [~,Y(ii)] = transformPointsInverse(tf,x,ii);
end
numRequiredRows = ceil(Y(0.98*bAVL) - Y(1));
% Visualize Inverse Row Mapping
subplot(2,1,2);
plot(Y,'HandleVisibility','off');   % Inverse Row Mapping
xline(0.98*bAVL,'r','98%','LabelHorizontalAlignment','left',          ...
    'HandleVisibility','off');      % Line Buffer Depth
yline(Y(1),'r--','HandleVisibility','off')
yline(Y(0.98*bAVL),'r')
title('Birds-Eye View Inverse Row Mapping');
xlabel('Output Row');
ylabel('Input Row');
legend(['Line Buffer Depth: ',num2str(numRequiredRows),' lines'],     ...
    'Location','northwest');
axis equal;
grid on;

График показывает отображение входной линии на выходную линию, показывая, что для генерации первых 700 строк выходного изображения сверху вниз глаза птиц требуется около 50 строк входного изображения. Это допустимое количество строк для хранения с использованием встроенной памяти.

Определение полосы движения

При получении изображения с видом на птицу может быть выполнено фактическое обнаружение полосы движения. Существует много методов, которые могут быть рассмотрены для этой цели. Для достижения реализации, которая является надежной, хорошо работает на потоковых данных изображения и которая может быть реализована в аппаратном обеспечении FPGA/ASIC при разумной стоимости ресурсов, в этом примере используется подход, описанный в [1]. Этот алгоритм выполняет полную свертку изображения с вертикально ориентированным ядром фильтра гауссовых производных первого порядка с последующей обработкой субрегионов.

Свёртка вертикально-ориентированного фильтра

Сразу после отображения входного изображения птицами-глазами выходной сигнал свернут с фильтром, предназначенным для обнаружения полос пикселей высокой интенсивности на темном фоне. Ширина ядра составляет 8 пикселей, что относится к ширине линий, которые появляются на изображении птичьего глаза. Высота устанавливается равной 16, которая относится к размеру штриховой разметки полосы, которая появляется на изображении. Поскольку изображение птичьего глаза физически связано с высотой, шагом и т.д. камеры, ширина, на которой появляются полосы на этом изображении, по существу связана с физическим измерением на дороге. Возможно, потребуется обновить ширину и высоту ядра при эксплуатации системы обнаружения полосы движения в различных странах.

Выходные данные ядра фильтра показаны ниже с использованием карты цветности струи для выделения различий в интенсивности. Поскольку ядро фильтра является общей, вертикально ориентированной гауссовой производной, существует некоторый отклик от множества различных областей. Однако для мест, где имеется разметка полосы движения, имеется сильный положительный отклик, расположенный рядом с сильным отрицательным откликом, который согласуется между колоннами. Эта характеристика выходного сигнала фильтра используется на следующем этапе алгоритма обнаружения для определения местоположения действительных кандидатов полосы движения.

Формирование кандидатов в полосы движения

После свертки с ядром гауссовой производной выполняют обработку подрегиона выхода для того, чтобы найти координаты, где присутствует разметка полосы движения. Каждая область состоит из 18 линий, с установленной схемой памяти ping-pong, чтобы гарантировать непрерывную потоковую передачу данных через подсистему.

Число столбцов гистограммы

Во-первых, HistingedColumnCount подсчитывает количество пороговых пикселей в каждом столбце в области 18 строк. Большое число столбцов указывает на то, что полоса движения, вероятно, присутствует в регионе. Этот подсчет выполняется как для положительного, так и для отрицательного пороговых изображений. Количество положительных гистограмм смещается с учетом ширины ядра. Кандидаты на дорожку появляются там, где положительное и отрицательное количество являются высокими. Это использует ранее отмеченное свойство вывода свертки, где положительные дорожки появляются рядом с отрицательными дорожками.

Внутри гистограмма подсчета столбцов генерирует управляющую сигнализацию, которая выбирает область 18 строк, вычисляет гистограмму столбцов и выводит результат, когда он готов. Существует схема буферизации ping-pong, которая позволяет считывать одну гистограмму во время следующей записи.

Перекрытие и умножение

Как отмечено, когда дорожка присутствует в изображении «птица-глаз», результат свертки будет давать полосы высокой интенсивности положительного выхода, расположенные рядом с полосами высокой интенсивности отрицательного выхода. Гистограмма числа положительных и отрицательных столбцов определяет местоположение таких областей. Для усиления этих местоположений выходной сигнал положительного счета задерживается на 8 тактовых циклов (внутренний параметр, связанный с шириной ядра), и положительный и отрицательный счетчики умножаются вместе. Это усиливает столбцы, где положительные и отрицательные счетчики согласуются, и минимизирует области, где есть разногласия между положительными и отрицательными счетчиками. Конструкция конвейерная для обеспечения высокой пропускной способности.

Фильтр пересечения нулей

На выходе подсистемы перекрытия и умножения появляются пики там, где имеется разметка полосы движения. Алгоритм обнаружения пиков определяет столбцы, в которых присутствует разметка полосы движения. Поскольку SNR является относительно высоким в данных, в этом примере используется простая операция фильтрации FIR с последующим обнаружением пересечения нуля. Фильтр пересечения нулей реализуется с использованием блока дискретного фильтра FIR от DSP System Toolbox™. Она конвейерная для высокопроизводительной работы.

Доминантные полосы магазинов

Выходной сигнал фильтра пересечения нулей затем передается в подсистему Store Dominate Lanes. Эта подсистема имеет максимальный объем памяти 7 записей и сбрасывается каждый раз при достижении нового пакета из 18 строк. Следовательно, для каждой подгруппы генерируется 7 потенциальных кандидатов полосы движения. В этой подсистеме осуществляется потоковая передача выходного сигнала фильтра пересечения нулей и проверка потенциальных пересечений нулей. Если пересечение нуля действительно происходит, то разность между адресом непосредственно перед пересечением нуля и адресом после пересечения нуля принимается для того, чтобы получить измерение размера пика. Подсистема сохраняет точки пересечения нулей с наибольшей величиной.

Вычислить Ego-полосы

Подсистема обнаружения полос выводит 7 наиболее жизнеспособных разметок полос. Во многих приложениях нас больше всего интересует разметка полосы, которая содержит полосу, по которой едет транспортное средство. Вычисляя так называемые «Ego-Lanes» на аппаратной стороне конструкции, мы можем уменьшить пропускную способность памяти между аппаратным и программным обеспечением, отправляя на процессор не 7, а 2 канала. Вычисление Ego-Lane разделено на две подсистемы. Подсистема FirstPassEgoLane предполагает, что центральная колонна изображения соответствует середине полосы, когда транспортное средство правильно работает в границах полосы. Таким образом, в качестве эго-полос принимаются кандидаты в полосы, которые находятся ближе всего к центру. Подсистема удаления отклонений поддерживает среднюю ширину расстояния от разметки полосы движения до центральной координаты. Маркеры полос движения, которые не находятся в пределах допуска текущей ширины, отклоняются. Выполнение раннего отклонения маркеров полос дает лучшие результаты при выполнении подгонки кривой позже в проекте.

Интерфейс управления

И, наконец, вычисленные ego-каналы отправляются в функциональную подсистему «MATLAB». Этот конечный автомат использует четыре входа управляющего сигнала - enable, hwStart, hwDone и swStart, чтобы определить, когда начать буферизацию, принять новую координату полосы в буфер 40x1 и, наконец, указать программному обеспечению, что все 40 координат полосы были буферизованы, и, таким образом, можно выполнить фитинг и наложение полосы. Сигнал dataReady гарантирует, что программное обеспечение не будет пытаться выполнить настройку полосы, пока все 40 координат не будут буферизованы, в то время как сигнал swStart гарантирует, что текущий набор 40 координат будет удерживаться до тех пор, пока настройка полосы не будет завершена.

Программная посадка и наложение полосы

Обнаруженные эго-полосы затем передаются в подсистему «SW Lane Fit and Overlay», где выполняется надежная посадка кривой и наложение. Напомним, что вывод птичьего глаза производится один раз в два кадра или около того, а не на каждом последовательном кадре. Поэтому фитинг и наложение кривой размещаются в включенной подсистеме, которая включается только при создании новых эго-полос.

Водитель

Подсистема функции драйвера MATLAB управляет синхронизацией между аппаратными средствами и программным обеспечением. Первоначально она находится в состоянии опроса, где она производит выборку входных данных dataReady с регулярными интервалами на кадр, чтобы определить, когда аппаратные средства буферизовали полный вектор [40x1] координат полосы. Как только это происходит, он переходит в состояние программной обработки, в котором выходы swStart и процесса поддерживаются высокими. Драйвер остается в состоянии обработки программного обеспечения до тех пор, пока входной сигнал swDone не станет высоким. Поскольку выходные данные процесса возвращаются на вход swDone с блоком перехода скорости между ними, для подсистемы FitLanesandOverlay фактически задается постоянный бюджет времени для выполнения фитинга и наложения. При высоком значении swDone драйвер переходит в состояние синхронизации, где swStart удерживается на низком уровне, указывая аппаратным средствам, что обработка завершена. Синхронизация между программным обеспечением и аппаратными средствами такова, что аппаратные средства удерживают вектор [40x1] координат полосы движения до тех пор, пока сигнал swStart не вернется на низкий уровень. В этом случае выходные данные dataReady аппаратных средств будут возвращены на низкий уровень.

Вписать полосы движения и наложение

Подсистема «Подогнать полосы движения и наложение» активируется драйвером. Он выполняет необходимую арифметику, необходимую для того, чтобы установить полином на данные координат полосы, полученные на входе, и затем рисует соответствующие координаты полосы и полосы на изображении Birds-Eye.

Подогнать полосы движения

Подсистема Fit Lanes выполняет процедуру подгонки линий на основе RANSAC для сгенерированных кандидатов полос. RANSAC - итеративный алгоритм, который строит таблицу inliers на основе измерения расстояния между предлагаемой кривой и входными данными. На выходе этой подсистемы имеется вектор [3x1], который задает полиномиальные коэффициенты, найденные подпрограммой RANSAC.

Разметка накладной полосы

Подсистема разметки накладных полос выполняет операции визуализации изображения. Он накладывается на полосы ego и кривые, найденные подпрограммой подгонки полос.

Результаты моделирования

Модель включает в себя два видеодисплея, показанных на выходе результатов моделирования. После наложения кандидатов на полосы, выполнения аппроксимации полинома и наложения полученного полинома на изображение на дисплее HusingEye отображаются выходные данные в искаженной перспективе. На дисплее OriginalOverlay отображаются выходные данные OtherEye, искаженные в исходную перспективу.

Из-за больших размеров кадра, используемых в этой модели, моделирование может занять относительно много времени. Если у вас есть лицензия HDL Verifier™, вы можете ускорить скорость моделирования, непосредственно запустив подсистему HDL Lane Detector в аппаратном обеспечении с помощью FPGA в петле (TM).

Создание кода HDL

Для проверки и генерации кода HDL, на который ссылается этот пример, необходимо иметь лицензию HDL Coder™.

Для создания кода HDL используется следующая команда.

makehdl('LaneDetectionHDL/HDLLaneDetector')

Для создания тестового стенда используется следующая команда. Следует отметить, что создание тестового стенда занимает много времени из-за большого размера данных. Перед созданием стенда можно сократить время моделирования.

makehdltb('LaneDetectionHDL/HDLLaneDetector')

Для ускорения моделирования испытательного стенда можно создать тестовый стенд SystemVerilog DPIC с помощью следующей команды.

makehdltb('LaneDetectionHDL/HDLLaneDetector','GenerateSVDPITestBench','ModelSim')

Заключение

Этот пример дает представление о проблемах проектирования систем ADAS в целом, с уделением особого внимания ускорению критических частей конструкции в аппаратном обеспечении.

Ссылки

[1] Р. К. Сацода и Мохан М. Триведи, «Анализ полос на основе зрения: исследование проблем и подходов для реализации встраиваемых систем», Конференция IEEE 2013 по компьютерному зрению и распознаванию образов.

[2] Видео из набора данных Caltech Lanes - Мохамед Али, «Обнаружение маркеров переулков в реальном времени на городских улицах», симпозиум IEEE Intelligent Vehicles 2008 - используется с разрешения.

Связанные темы