Этот пример показывает, как реализовать алгоритм обнаружения разметки маршрута для FPGA.
Обнаружение маршрута является критической стадией обработки в Advanced Driving Assistance Systems (ADAS). Автоматическое обнаружение контуров маршрута из видеопотока является вычислительно сложным, и поэтому для достижения эффективности в реальном времени часто требуются аппаратные ускорители, такие как FPGA и GPU.
В этой модели примера, основанный на FPGA генератор кандидата маршрута связан с программным полиномиальным механизмом аппроксимации, чтобы определить контуры маршрута.
Система LaneDetectionHDL.slx показана ниже. Подсистема HDLLaneDetector представляет аппаратную ускоренную часть проекта, в то время как подсистема SWLaneFitandOverlay представляет программный полином аппроксимации. Перед блоком Frame to Pixels вход RGB преобразуется в цветовое пространство интенсивности.
HDL Lane Detector представляет аппаратно ускоренную часть проекта. Эта подсистема получает входной поток пикселей от источника фронтальной камеры, преобразует вид, чтобы получить вид «птица-глаз», находит кандидатов на разметку маршрута от преобразованного вида и затем буферизует их в вектор, чтобы отправить на программную сторону для аппроксимирования кривыми и наложения.
Блок Birds-Eye View преобразует лицевое поле зрения камеры в перспективу птиц-глаз. Работа с изображениями в этом представлении упрощает требования к обработке нижестоящих алгоритмов обнаружения маршрута. Вид спереди страдает от перспективных искажений, вызывая сходимость полос в точке исчезновения. Перспективное искажение корректируется путем применения обратного перспективного преобразования.
Обратное перспективное отображение (IPM) определяется следующим выражением:
Матрица гомографии h определяется четырьмя собственными параметрами настройки физического фотоаппарата, а именно фокусным расстоянием, тангажом, высотой и основной точкой (из модели камеры pinhole). Для получения дополнительной информации см. документацию Computer Vision Toolbox™.
Можно оценить матрицу гомографии с помощью Computer Vision Toolbox™ estimateGeometricTransform2D
функцию или Image Processing Toolbox™ fitgeotrans
функция для создания projective2d
объект. Эти функции требуют набора совпадающих точек между исходной системой координат и системой координат птиц. Точки системы координат источника приняты как вершины трапеций необходимой области и могут простираться за пределы системы координат источника, чтобы захватить большую область. Для трапеции, показанной, отображение точек является:
Где bAPPL и bAVL являются активными пикселями для просмотра птиц-глаз на линию и активными линиями видео соответственно.
Прямая оценка отображения источника (лицевой стороны) в пункт назначения (птицы-глаза) в режиме реального времени на оборудовании FPGA/ASIC является сложной задачей. Требование деления вместе с потенциалом для непоследовательного доступа к памяти из буфера системы координат означают, что вычислительные требования этой части проекта являются существенными. Поэтому вместо непосредственной оценки вычисления IPM в реальном времени был выполнен и использован оффлайн-анализ входа параметров в выход для предварительного вычисления схемы отображения. Это возможно, так как матрица гомографии фиксируется после заводской калибровки/установки камеры, из-за фиксированного положения камеры, высоты и тангажа.
В этом конкретном примере выходное изображение для птичьего глаза является системой координат размерностей [700x640], тогда как вход изображение для лицевой стороны имеет размерности [480x640]. Нет достаточного гашения, доступного в порядок, чтобы вывести полную систему координат птиц-глаз до того, как следующий вход фронтальной камеры будет транслироваться. Поэтому блок Birds-Eye view не примет никаких новых данных кадра, пока не завершит обработку текущей системы координат птиц-глаз.
Полноразмерное проективное преобразование из входного в выходное приведет к выходному изображению [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, что относится к размеру штриховой разметки маршрута, которая появляется на изображении. Поскольку изображение птичьего глаза физически связано с высотой, тангажом и т.д. камеры, ширина, при которой на этом изображении появляются полосы, неразрывно связана с физическим измерением на дороге. Ширина и высота ядра могут потребоваться для обновления при работе с системой обнаружения маршрута в разных странах.
Выход ядра фильтра показан ниже, с помощью jet colormap, чтобы выделить различия в интенсивности. Поскольку ядро фильтра является общей, вертикально ориентированной производной Гауссова, существует некоторая реакция от многих различных областей. Однако для мест, где присутствует разметка маршрута, существует сильная положительная реакция, расположенная рядом с сильной отрицательной характеристикой, которая согласуется между столбцами. Эта характеристика выходного сигнала фильтра используется на следующем этапе алгоритма обнаружения, чтобы найти действительных кандидатов маршрута.
После свертки с ядерным производным Гауссова обработка подрегиона выхода выполняется в порядок, чтобы найти координаты, где присутствует разметка маршрута. Каждая область состоит из 18 линий со схемой памяти ping-pong, чтобы гарантировать, что данные могут постоянно передаваться через подсистему.
Во-первых, HistogramColumnCount отсчитывает количество пороговых пикселей в каждом столбце по 18 линейной области. Высокое количество столбцов указывает, что в области, вероятно, присутствует канал. Это количество выполняется как для положительных, так и для отрицательных пороговых изображений. Положительные счетчики гистограммы смещены для расчета ширины ядра. Кандидаты в маршруты происходят, где положительное и отрицательное количество являются высокими. Это использует ранее отмеченное свойство выхода свертки, где положительные дорожки появляются рядом с отрицательными дорожками.
Внутренне гистограмма подсчета столбцов генерирует управляющую сигнализацию, которая выбирает 18- линии область, вычисляет гистограмму столбца и выводит результат, когда готов. На месте схема буферизации пинг-понга, которая позволяет считать одну гистограмму во время записи следующей.
Как отмечалось, когда в изображении птичьего глаза присутствует дорожка, результат свертки будет создавать полоски высокой интенсивности положительного выхода, расположенные рядом с полосками высокой интенсивности отрицательного выхода. Положительные и отрицательные гистограммы счетчика столбцов определяют местоположение таких областей. В порядок для усиления этих местоположений выход положительного отсчета задерживается на 8 тактов (внутренний параметр, относящийся к ширине ядра), и положительный и отрицательный отсчеты умножаются вместе. Это усиливает столбцы, где положительное и отрицательное счетчики согласованы, и минимизирует области, где существует несогласие между положительным и отрицательным счетчиками. Проект выполнен в порядок для обеспечения высокой производительности операции.
На выходе Подсистемы Перекрытия и Умножения, peaks появляются там, где есть маркировка маршрута. Алгоритм пикового обнаружения определяет столбцы, в которых присутствует разметка маршрута. Поскольку ОСШ относительно высок в данных, этот пример использует простую операцию фильтрации конечной импульсной характеристики с последующим обнаружением пересечения нуля. Фильтр пересечения нуля реализован с помощью блока дискретной конечной импульсной характеристики из DSP System Toolbox™. Он конвейеризован для высокопроизводительной операции.
Фильтр пересечения нуля выхода затем передается в подсистему Доминирующих Полос Хранения. Эта подсистема имеет максимальную память 7 записей и сбрасывается каждый раз, когда достигается новый пакет из 18 линий. Поэтому для каждого субрегиона генерируются 7 потенциальных кандидатов маршрута. В этой подсистеме выход фильтра пересечения нуля передается по потоку и исследуется на потенциальные пересечения нуля. Если пересечение нуля происходит, то различие между адресом непосредственно перед пересечением нуля и адресом после пересечения нуля принимается в порядок, чтобы получить измерение размера пика. Подсистема сохраняет положения пересечения нуля с наибольшей величиной.
Подсистема обнаружения маршрута выводит 7 наиболее жизнеспособных разметок маршрута. Во многих приложениях нас больше всего интересует разметка маршрута, которая содержит полосу движения транспортного средства. Вычисляя так называемые «Ego-Lanes» на аппаратной стороне проекта, мы можем уменьшить пропускную способность памяти между оборудованием и программным обеспечением, отправив процессору 2 линии, а не 7. Расчет Ego-Lane разделён на две подсистемы. Подсистема FirstPassEgoLane принимает, что центральный столбец изображения соответствует середине полосы, когда транспортное средство правильно работает в контурах полосы. Поэтому кандидаты маршрута, которые находятся ближе всего к центру, приняты как эго-полосы. Подсистема удаления выбросов поддерживает среднюю ширину расстояния от разметки маршрута до координат центра. Маркеры маршрута, которые не находятся в допусках значения текущей ширины, отклоняются. Выполнение раннего отказа от маркеров маршрута дает лучшие результаты при выполнении аппроксимирования кривыми позже в проекте.
Наконец, вычисленные ego-полосы передаются в функциональную подсистему CtrlInterface MATLAB. Этот конечный автомат использует четыре входов сигнала управления - enable, hwStart, hwDone и swStart, чтобы определить, когда начать буферизацию, принять новую координату маршрута в буфер 40x1 и, наконец, указать программному обеспечению, что все 40 координат маршрута были буферизованы, и поэтому подборы кривой маршрута и наложение могут быть выполнены. Сигнал dataReady гарантирует, что программное обеспечение не будет пытаться подогнать канал до тех пор, пока все 40 координат не будут буферизованы, в то время как сигнал swStart гарантирует, что текущий набор из 40 координат будет сохранен до завершения подбора кривой канала.
Обнаруженные ego-полосы затем передаются в подсистемы SW Подгонки и Overlay, где выполняются устойчивые аппроксимирования кривыми и наложение. Напомним, что выход «птичий глаз» производится один раз в две системы координат или так, а не на каждой последующей системе координат. Поэтому аппроксимирования кривыми и наложение помещаются в активированную подсистему, которая активируется только при создании новых ego-полос.
Подсистема Driver MATLAB Function управляет синхронизацией между оборудованием и программным обеспечением. Первоначально он находится в состоянии опроса, где он дискретизирует вход dataReady с регулярными интервалами на систему координат, чтобы определить, когда оборудование буферизует полный вектор координат маршрута [40x1]. Как только это происходит, он переходит в состояние обработки программного обеспечения, где swStart и выходы процесса поддерживаются высокими. Драйвер остается в состоянии обработки программного обеспечения, пока вход swDone не станет высоким. Когда выход процесса возвращается к входу swDone с промежуточным блоком перехода скорости, фактически существует постоянный бюджет времени, заданный для подсистемы FitLanesandOverlay, чтобы выполнить подбор кривой и наложение. Когда swDone является высоким, драйвер переходит в состояние синхронизации, где swStart удерживается низким, чтобы указать оборудованию, что обработка завершена. Синхронизация между программным и оборудованием такова, что оборудование будут удерживать вектор [40x1] координат маршрута, пока сигнал swStart не перейдет назад на низкий уровень. Когда это происходит, выход оборудования dataReady переходит к низкому значению.
Подсистема Fit Lanes и Overlay активируется драйвером. Он выполняет необходимую арифметику, необходимую в порядок для аппроксимации полинома на координатных данных маршрута, полученных на входе, а затем рисует установленные координаты маршрута и маршрута на изображение Birds-Eye.
Подсистема Fit Lanes запускает стандартную программу линейной подгонки на основе RANSAC на сгенерированных кандидатах маршрута. RANSAC является итеративным алгоритмом, который формирует таблицу инлиеров на основе меры расстояния между предлагаемой кривой и входными данными. На выходе этой подсистемы существует вектор [3x1], который задает полиномиальные коэффициенты, найденные стандартной программой RANSAC.
Подсистема Overlay Lane Markings выполняет операции визуализации изображений. Он накладывает эго-полосы и кривые, найденные в стандартной программе подгонки маршрута.
Модель включает два отображений видео, показанных на выходе результатов симуляции. На дисплее BirdsEye показан вывод в изогнутой перспективе после наложения кандидатов маршрута, выполнения полинома и наложения полученного полинома на изображение. На отображении OriginalOverlay показан выход BirdsEye, деформированный в исходной перспективе.
Из-за больших форматов кадра, используемых в этой модели, симуляция может занять относительно много времени. Если у вас есть HDL Verifier™ лицензия, можно ускорить скорость симуляции, непосредственно запустив подсистему HDL Lane Detector в оборудование с использованием FPGA в цикле (TM).
Чтобы проверить и сгенерировать HDL-код, на который ссылаются в этом примере, необходимо иметь лицензию HDL- Coder™.
Чтобы сгенерировать HDL-код, используйте следующую команду.
makehdl('LaneDetectionHDL/HDLLaneDetector')
Чтобы сгенерировать испытательный стенд, используйте следующую команду. Обратите внимание, что генерация испытательного стенда занимает много времени из-за большого размера данных. Можно хотеть уменьшить время симуляции перед генерацией испытательного стенда.
makehdltb('LaneDetectionHDL/HDLLaneDetector')
Для более быстрой симуляции испытательного стенда можно сгенерировать испытательный стенд SystemVerilog DPIC с помощью следующей команды.
makehdltb('LaneDetectionHDL/HDLLaneDetector','GenerateSVDPITestBench','ModelSim')
Этот пример дал представление о проблемах разработки систем ADAS в целом с особым акцентом на ускорение критических частей проекта в оборудовании.
[1] R. K. Satzoda and Mohan M. Trivedi, «Vision Based Lane Analysis: Exploration of Probles and Appleases for Embedded Realization», 2013 IEEE Conference on Компьютерное Зрение and PatTurnate Recognition.
[2] Видео с Caltech Lanes Dataset - Mohamed Aly, «Обнаружение маркеров маршрута в реальном времени на городских улицах», Симпозиум интеллектуальных транспортных средств IEEE 2008 - используется с разрешения.