Детектор выбоин на выбоину

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

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

Чтобы измерить эллиптическую форму, можно использовать алгоритм голосования, такой как круг Хафа, или алгоритм соответствия шаблона, или основанные на линейной алгебре методы, такие как аппроксимация методом наименьших квадратов. Измерение уровня яркости просто при обработке изображения путем выбора значения сегментации яркости. Текстура может быть оценена путем вычисления пространственной частоты в области с помощью таких методов, как БПФ.

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

Введение

Система PotHoleHDLDetector.slx представлена ниже. Подсистема PotHoleHDL содержит детектор выбоин и алгоритмы наложения и поддерживает генерацию HDL-кода. Существует четыре входных параметра, которые управляют алгоритмом. Подсистема ProcessorBehavioral записывает карты символов в ОЗУ для использования в качестве меток наложения.

modelname = 'PotHoleHDLDetector';
open_system(modelname);
set_param(modelname,'SampleTimeColors','on');
set_param(modelname,'SimulationCommand','Update');
set_param(modelname,'Open','on');
set(allchild(0),'Visible','off');

Обзор подсистемы FPGA

Подсистема PotHoleHDL преобразует видео с входом RGB в интенсивность, затем выполняет двустороннюю фильтрацию и обнаружение ребра. Подсистема TrapezoidalMask выбирает площадь дорожного полотна. Затем проект применяет морфологическое закрытие и вычисляет центроидные координаты для всех потенциальных выбоин. Детектор выбирает самую большую выбоину в каждой системе координат и сохраняет центральные координаты. Pixel Stream Aligner совпадает по времени с координатами с входом потоком. Наконец, Fiducial31x31 и Overlay32x32 подсистемы применяют наложения альфа-канала к системе координат, чтобы добавить маркер центра выбоины и текстовую метку.

open_system([modelname '/PotHoleHDL'],'force');

Входные значения параметров

Подсистема имеет четыре входных параметра, которые могут измениться во время работы системы.

Параметр интенсивности градиента, Gradient Threshold, управляет частью обнаружения ребра алгоритма.

Параметр Cartoon RGB изменяет цвет наложений, то есть реперного маркера и текста.

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

Итоговый параметр Show Raw позволяет легче отлаживать систему. Он переключает отображаемое изображение, на котором нарисованы наложения между входным видео RGB и бинарным изображением, которое видит детектор. Установите этот параметр равным 1, чтобы увидеть, как детектор работает.

Все эти параметры работают лучше всего, если изменения разрешены только на контурах видеокадра. Подсистема FrameBoundary регистрирует параметры только в допустимом начале системы координат.

open_system([modelname '/PotHoleHDL/FrameBoundary'],'force');

RGB - интенсивность

Модель разделяет входной поток пикселей RGB так, чтобы копия потока RGB продолжалась к блокам наложения. Первым шагом для детектора является преобразование RGB в интенсивность. Поскольку тип входных данных для RGB uint8блок RGB to Intensity автоматически выбирает uint8 как тип выходных данных.

Двусторонний фильтр

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

Блок Двустороннего Фильтра имеет параметры для размера окрестности и двух стандартных отклонений, один для пространственной части фильтра и один для части интенсивности фильтра. Для этого приложения хорошо работает относительно большой район 9х9. Эта модель использует 3 и 0,75 для стандартных отклонений. Экспериментировать с этими значениями можно позже.

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

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

Трапециевидная маска

Из двоичного изображения ребра необходимо удалить любые ребра, которые не имеют отношения к обнаружению выбоин на выбоине. Хорошей стратегией является использование маски, которая выбирает полигональную необходимую область и делает область вне черного. Модель не использует нормальный блок ROI, поскольку это удаляет контекст расположения, который вам нужен позже для вычисления и маркировки центроида.

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

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

Маска состоит из прямых линий между углами, соединяющих слева, справа и сверху, снизу.

     ltc---rtc
     /       \
    /         \
   /           \
lbc-------------rbc

Этот пример использует polyfit для определения прямолинейной подгонки от угла к углу. Для простоты реализации проект вызывает polyfit с вертикальным направлением как независимой переменной. Это использование вычисляет x = f(y) вместо более обычного y = f(x). Использование polyfit этот способ позволяет вам использовать счетчик линии y в качестве входного адреса интерполяционной таблицы координат x начальной (слева) и конечной (справа) области интереса на каждой линии.

Интерполяционная таблица обычно реализована в BRAM в FPGA, поэтому она должна быть адресована с помощью адресации на основе 0. Модель преобразует адресацию на основе MATLAB 1 в адресацию на основе 0 непосредственно перед LUT. Чтобы дополнительно уменьшить размер интерполяционной таблицы, адрес смещается начальной линией трапеции. В порядок получения хороших результатов синтеза совпадает с типичной блочной оперативной памятью, регистрирующейся в FPGAs при помощи регистра после интерполяционной таблицы. Этот регистр также добавляет в проект некоторую скромную конвейеризацию.

Для изображения 320x180:

raster = [320,180];
ltc = [155, 66];
lbc = [  1,140];
rtc = [155, 66];
rbc = [285,179];

% fit to x = f(y) for convenient LUT indexing
abl = polyfit([lbc(2),ltc(2)],[lbc(1),ltc(1)],1);  % left side
abr = polyfit([rbc(2),rtc(2)],[rbc(1),rtc(1)],1);  % right side
leftxstart = max(1,round((ltc(2):rbc(2))*abl(1)+abl(2)));
rightxend  = min(raster(1),round((ltc(2):rbc(2))*abr(1)+abr(2)));
startline  = min(ltc(2),rtc(2));
endline    = max(lbc(2),rbc(2));
% correct to zero-based addressing
leftxstart = leftxstart - 1;
rightxend = rightxend - 1;
startline = startline - 1;
endline = endline - 1;

open_system([modelname '/PotHoleHDL/TrapezoidalMask'],'force');

Морфологическое закрытие

Далее проект использует блок Морфологическое Закрытие, чтобы удалить или закрыть небольшие функции. Закрытие работает, вначале делая расширение, а затем эрозию, и помогает удалить небольшие функции, которые вряд ли являются выбоинами. Задайте район на маске блока, который определяет, какую маленькую или большую функцию вы хотите удалить. Эта модель использует район 5x5, подобный диску, так что небольшие функции закрыты.

Средняя точка

Вычисление центроида находит центр активной области. Этот проект постоянно вычисляет центроид отмеченной области в каждой области 31x31 пикселя. Он хранит координаты центра только, когда обнаруженная площадь больше, чем параметр входа. Это общее различие между оборудованием и программными системами: при разработке оборудования для ПЛИС часто легче вычислять постоянно, но только хранить ответ, когда он вам нужен, в отличие от вызова функций по мере необходимости в программном обеспечении.

Для вычисления центроида необходимо вычислить три вещи из области изображения: взвешенную сумму пикселей в горизонтальном направлении, взвешенную сумму в вертикальном направлении и общую сумму всех пикселей, которая соответствует области отмеченного фрагмента области. Буфер Линии выбирает области 31x31 пикселей и возвращает их по одному столбцу за раз. Алгоритм использует столбец, чтобы вычислить вертикальные веса и общие веса. Для горизонтальных весов проект объединяет столбцы, чтобы получить ядро 31x31. Можно выбрать веса в зависимости от того, что вы хотите означать «центр». Этот пример использует -15:15 так, чтобы центр области 31x31 был (0,0) в вычисленном результате.

Блоки Vision HDL Toolbox заставляют выходные данные нуля, когда вывод недействителен, как показано на выходе шины pixelcontrol. Хотя это строго не требуется, такое поведение значительно облегчает проверку и отладку. Чтобы выполнить это поведение для результатов centroid, модель использует блоки Switch с набором блоков Constant, равным 0.

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

open_system([modelname '/PotHoleHDL/Centroid31'],'force');

open_system([modelname '/PotHoleHDL/Centroid31/CentroidKernel'],'force');

Обнаружение и удержание

Детектор действует на общую сумму площади от центроида. Сам детектор очень прост: сравните значение площади центроида с пороговым параметром и найдите самую большую площадь, которая больше порога. Логика модели сравнивает значение сохраненной области со значением текущей области и сохраняет новую область, когда вход больше, чем текущее значение. При помощи > или >= можно выбрать самое раннее значение порога или самое последнее значение порога. Модель хранит последнее значение, потому что более поздние значения ближе к камере и транспортному средству. Когда детектор хранит новое значение выигрышной области, он также обновляет значения X и Y центроидов, которые соответствуют этой области. Затем эти координаты передаются в части подсистемы выравнивания и наложения.

Чтобы передать X, Y и действительное указание алгоритму выравнивания, упакуйте значения в одно 23-битное слово. Модель распаковывает их, как только они выравниваются во времени с входными кадрами для наложения.

open_system([modelname '/PotHoleHDL/DetectAndHold'],'force');

Пиксельный выравниватель потока

Блок Pixel Stream Aligner забирает потоковую информацию с детектора и отправляет ее и исходный поток пикселей RGB в подсистемы наложения. Выравниватель компенсирует задержку обработки, добавленную всеми предыдущими частями алгоритма обнаружения, не зная ничего о задержке этих блоков. Если позже вы измените размер окрестности или добавите больше обработки, aligner может компенсировать. Если общая задержка превышает параметр Maximum number of lines блока Pixel Stream Aligner, настройте параметр.

Реперное наложение

Реперный маркер является квадратной сеткой, представленной как 31-элементный массив 31-битных чисел с фиксированной точкой. Это представление удобно, потому что одно чтение возвращает целое слово пикселей наложения для каждой линии.

Схема показывает шаблон наложения путем преобразования данных с фиксированной точкой в двоичные. Этот шаблон может быть любым, что вы хотите в пределах размера 31x31 в этом проекте.

load fiducialROM31x31.mat
crosshair = bin(fiducialROM);
crosshair(crosshair=='0') = ' ' %change '0' to space for better display
crosshair =

  31x31 char array

    '               1               '
    '               1               '
    '               1               '
    '               1               '
    '    11111111111111111111111    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1                     1    '
    '    1                     1    '
    '    1                     1    '
    '111111111111       111111111111'
    '    1                     1    '
    '    1                     1    '
    '    1                     1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    1          1          1    '
    '    11111111111111111111111    '
    '               1               '
    '               1               '
    '               1               '
    '               1               '

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

open_system([modelname '/PotHoleHDL/Fiducial31x31'],'force');

Наложение символов

Символ символьного шрифта для экранного отображения сохраняет данные способом, подобным описанному выше реперному ПЗУ. Каждый 16-битовый номер с фиксированной точкой представляет 16 последовательных горизонтальных пикселей. Карты символов 16x16.

Поскольку символьные данные обычно записываются центральным процессором в ASCII, самым простым способом является хранение символьных данных под 8-битными адресами ASCII в двухпортовой ОЗУ. В ПЗУ шрифта сохраняются символы ASCII с 33 («!») по 122 («z»). Проект смещает адрес на 33.

Шрифт ROM был построен из шрифта фиксированной ширины в открытой области с несколькими изменениями для улучшения читаемости. Как и в реперном маркере, данные ПЗУ символов используются как двоичный переключатель, который включает наложение альфа-канала. Значение символа alpha является фиксированным параметром прозрачности, применяемым в качестве усиления на сигнале Detect, когда он распакован, в подсистеме ExpandData.

Чтобы визуализировать символ B в ПЗУ шрифта отобразите его в двоичном формате.

load charROM16x16.mat
letterB = bin(charROM16x16(529:544)); % character array
letterB(letterB=='0')=' ' % remove '0' chars for better display
letterB =

  16x16 char array

    '                '
    '  111111111     '
    '  11111111111   '
    '   111    111   '
    '   111     111  '
    '   111     111  '
    '   111    111   '
    '   1111111111   '
    '   111111111    '
    '   111    111   '
    '   111     111  '
    '   111     111  '
    '   111     111  '
    '   111    1111  '
    '  11111111111   '
    '  111111111     '

open_system([modelname '/PotHoleHDL/Overlay32x32'],'force');

Просмотр необработанного изображения детектора

Когда вы работаете со сложным алгоритмом, просмотр промежуточных шагов в обработке может быть очень полезным для отладки и исследования. В этой модели можно задать логическое Show Raw значение параметра 1 (true) для отображения результата морфологического закрытия бинарного изображения с наложением обнаруженных результатов. Чтобы преобразовать бинарное изображение для использования с 8-битным наложением RGB, модель умножает двоичное значение на 255 и использует это значение на всех трех цветовых каналах.

Генерация HDL-кода

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

Чтобы сгенерировать HDL-код, используйте следующую команду.

makehdl('PotHoleHDLDetector/PotHoleHDL')

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

makehdltb('PotHoleHDLDetector/PotHoleHDL')

Часть этой модели, которую можно реализовать на FPGA, является частью между блоками Frame To Pixels и Pixels To Frame. Это подсистема под названием PotHoleHDL, которая включает все элементы детектора.

Симуляция в Симулятор HDL

Теперь, когда у вас есть HDL-код, вы можете симулировать его в своем Симуляторе HDL. Автоматически сгенерированный испытательный стенд позволяет вам доказать, что симуляция Simulink и симуляция HDL совпадают.

Синтез для FPGA

Можно также синтезировать сгенерированный HDL-код в инструменте синтеза FPGA, таком как Xilinx Vivado. В Virtex-7 FPGA (xc7v585tffg1157-1) проект достигает тактовой частоты более 150 МГц.

Отчет об использовании показывает, что двусторонний фильтр, выравниватель пиксельных потоков и функции centroid потребляют большую часть ресурсов в этом проекте. Для двустороннего фильтра требуется больше всего ЦСП. Реализация centroid достаточно эффективна и использует только два DSP. Для вычисления Centroid также требуется обратная интерполяционная таблица, поэтому в качестве памяти используется большое количество LUT.

Дальнейший переход

Этот пример показывает одну возможную реализацию алгоритма для обнаружения выбоин. Этот проект может быть расширена следующими способами:

  • Порог градиента можно было вычислить из средней яркости с помощью модели серого мира.

  • Блок трапециевидной маски может быть выполнен «управляемым» путем взгляда на положение колеса транспортного средства и регулировки линейной подгонки наклонных сторон маски.

  • Детектор может быть сделан более устойчивым при рассмотрении средней яркости изображения RGB или интенсивности относительно окружающего покрытия, поскольку выбоины обычно темнее по интенсивности, чем окружающая область.

  • Визуальная частотная спектрограмма выбоины также может использоваться для поиска конкретных типов поверхностей в выбоинах.

  • Пороговое значение площади обнаружения может быть вычислено с помощью средней интенсивности в области трапеций дорожного полотна.

  • Несколько выбоин можно обнаружить в одной системе координат путем хранения верхних N откликов, а не только максимального обнаруженного отклика. Подсистема реперных маркеров должна быть слегка переработана, чтобы допускать перекрытие маркеров.

Заключение

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

Ссылки

[1] Кох, Кристиан и Иоаннис Брилакис. Обнаружение выбоин в изображениях асфальтового покрытия. Передовая инженерная информатика 25, № 3 (2011): 507-15. doi: 10.1016/j.aei.2011.01.002.

[2] Оманович, Самир, Эмир Буза, и Элвин Гусейнович. «Обнаружение выбоины с обработкой изображения и спектральным объединением в кластеры». 2-я международная конференция по вопросам сетей информационных технологий и компьютера (ICTN '13), Анталья, Турция. Октябрь 2013.