Этот пример расширяет cartooning пример, чтобы включать вычисление центроида и накладывание центроидного маркера и текстовой метки на обнаруженных выбоинах.
Дорожное обнаружение опасности или выбоины является важной частью любой автоматизированной системы вождения. Предыдущая работа [1] на автоматизированном обнаружении выбоины задала выбоину как эллиптическую область в дорожном покрытии, которое имеет более темный уровень яркости и различную структуру, чем окружающее дорожное покрытие. Обнаружение выбоин с помощью обработки изображений затем становится задачей нахождения областей в изображении дорожного покрытия, которые соответствуют выбранному критерию. Можно использовать любую из эллиптической формы, более темной яркости или текстурировать критерий.
Чтобы измерить эллиптическую форму, можно использовать голосующий алгоритм, такой как круг Хью, или алгоритм сравнения с шаблонами или основанные на линейной алгебре методы, такие как метод наименьших квадратов. Измерение уровня яркости просто в обработке изображений путем выбора значения сегментации яркости. Структура может быть оценена путем вычисления пространственной частоты в области с помощью методов, таких как БПФ.
Этот пример использует сегментацию яркости с метрикой области так, чтобы меньшие дефекты не были обнаружены. Чтобы найти центр дефекта, этот проект вычисляет центроид. Модель накладывает маркер на центре дефекта и накладывает текстовую метку на изображении.
Систему PotHoleHDLDetector.slx показывают ниже. Подсистема PotHoleHDL содержит детектор выбоины и алгоритмы наложения и поддерживает генерацию HDL-кода. Существует четыре входных параметра, которые управляют алгоритмом. Подсистема ProcessorBehavioral пишет карты символов в RAM для использования в качестве меток наложения.
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');
Подсистема PotHoleHDL преобразует видео входа RGB в интенсивность, затем выполняет двустороннюю фильтрацию и обнаружение ребра. Подсистема TrapezoidalMask выбирает область шоссе. Затем проект применяет морфологическое завершение и вычисляет центроидные координаты для всех потенциальных выбоин. Детектор выбирает самую большую выбоину в каждой системе координат и сохраняет центральные координаты. Пиксельный Потоковый Выравниватель совпадает с синхронизацией координат с входным потоком. Наконец, Fiducial31x31 и подсистемы Overlay32x32 применяют оверлейные программы альфа-канала на систему координат, чтобы добавить маркер центра выбоины и текстовую метку.
open_system([modelname '/PotHoleHDL'],'force');
Подсистема имеет четыре входных параметра, которые могут измениться, в то время как система запускается.
Параметр интенсивности градиента, Порог Градиента, управляет частью обнаружения ребра алгоритма.
Мультипликационный параметр RGB изменяет цвет оверлейных программ, то есть, основанного на вере маркера и текста.
Пороговый параметр области определяет минимальный номер отмеченных пикселей в окне обнаружения для него, чтобы быть классифицированным как выбоина. Если это значение будет слишком низким, то линейные трещины и другие дефекты, которые не являются дорожными опасностями, будут обнаружены. Если это будет слишком высоко затем, то только самые большие опасности будут обнаружены.
Итоговый параметр, Покажите Сырые данные, позволяет вам отлаживать систему более легко. Это переключает отображенное изображение, на котором оверлейные программы являются соединяющими видео входа RGB и двухуровневое изображение, которое видит детектор. Установите этот параметр на 1, чтобы видеть, как детектор работает.
Все эти параметры работают лучше всего, если изменения только позволены на контурах видеокадра. Подсистема FrameBoundary указывает параметры только на допустимом запуске системы координат.
open_system([modelname '/PotHoleHDL/FrameBoundary'],'force');
Модель разделяет пиксельный поток входа RGB так, чтобы копия потока RGB продолжилась к блокам наложения. Первый шаг для детектора должен преобразовать от RGB до интенсивности. Поскольку типом входных данных для RGB является uint8
, RGB с блоком Intensity автоматически выбирает uint8
как тип выходных данных.
Следующий шаг в алгоритме должен уменьшить высокую визуальную частоту шумовые и меньшие дорожные дефекты. Существует много способов, которыми это может быть выполнено, но использование двустороннего фильтра имеет преимущество сохранения ребер при сокращении шумовых и меньших областей.
Блок Bilateral Filter имеет параметры для размера окружения и двух стандартных отклонений, один для пространственной части фильтра и один для части интенсивности фильтра. Для этого приложения относительно большое окружение 9x9 работает хорошо. Эта модель использует 3 и 0.75 для стандартных отклонений. Можно экспериментировать с этими значениями позже.
Отфильтрованное изображение затем отправляется в блок обнаружения ребра Sobel, который находит ребра в изображении и возвращает те ребра, которые более сильны, чем пороговый параметр градиента. Выход является двухуровневым изображением. В вашем итоговом приложении этот порог может быть установлен на основе переменных, таких как дорожные условия, погода, яркость изображения, и т.д. Для этой модели порог является входным параметром к подсистеме PotHoleHDL.
Из двоичного изображения краев необходимо удалить любые ребра, которые не относятся к обнаружению выбоины. Хорошая стратегия состоит в том, чтобы использовать маску, которая выбирает многоугольную необходимую область и делает область за пределами того черного цвета. Модель не использует нормальный блок ROI, поскольку это удалило бы контекст местоположения, в котором вы нуждаетесь позже для центроидного вычисления и маркировки.
Порядок операций также имеет значение здесь, потому что, если бы вы использовали маску перед обнаружением ребра, ребра маски стали бы сильными линиями, которые привели бы к ложным положительным сторонам в детекторе.
Во входном видео область, в которой транспортное средство может столкнуться с выбоиной, сразу ограничивается шоссе перед ним и трапециевидным разделом шоссе вперед. Точные координаты зависят от монтирования камеры и линзы. Этот пример использование зафиксировал координаты для верхней части левой стороны, верхней части правой стороны, нижней части левой стороны и нижних углов правой стороны области. Для этого видео верх и низ трапециевидной области не параллелен, таким образом, это не истинный трапецоид.
Маска состоит из прямых линий между углами, соединяясь оставленный, право и верхняя часть, нижняя часть.
ltc---rtc / \ / \ / \ lbc-------------rbc
Этот пример использует polyfit
определить прямолинейную подгонку от угла до угла. Для простоты реализации проект вызывает polyfit
с вертикальным направлением как независимая переменная. Это использование вычисляет x = f(y)
вместо более обычного y = f(x)
. Используя polyfit
этот путь позволяет вам использовать счетчик линии направления Y в качестве входного адреса интерполяционной таблицы x-координат запуска (слева) и конца (справа) сферы интересов на каждой линии.
Интерполяционная таблица обычно реализуется в BRAM в FPGA, таким образом, она должна быть обращена с обращением на основе 0. Модель преобразует из обращение на основе MATLAB 1 к обращению на основе 0 незадолго до LUTs. Чтобы далее уменьшать размер интерполяционной таблицы, адрес возмещен стартовой линией трапецоида. Для получения хорошие результаты синтеза, совпадайте с типичной регистрацией блока RAM в 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');
Затем проект использует блок Morphological Closing, чтобы удалить или закрыться в маленьких функциях. Закрытие работает первым расширением выполнения и затем эрозией, и помогает удалить маленькие функции, которые вряд ли будут выбоинами. Задайте окружение на маске блока, которая определяет, как маленький или большой функция вы хотите удалить. Эта модель использует 5x5 окружение, похожее на диск, так, чтобы были окружены маленькие функции.
Центроидное вычисление находит центр активной области. Проект постоянно вычисляет центроид отмеченной области в каждой области на 31x31 пиксель. Это только хранит центральные координаты, когда обнаруженная область больше, чем входной параметр. Это - общее различие между аппаратными и программными системами: при разработке оборудования для FPGAs часто легче вычислить постоянно, но только сохранить ответ, когда вам нужен он, в противоположность вызыванию функций по мере необходимости в программном обеспечении.
Для центроидного вычисления необходимо вычислить три вещи из области изображения: взвешенная сумма пикселей в горизонтальном направлении, взвешенная сумма в вертикальном направлении и полная сумма всех пикселей, которая соответствует области отмеченного фрагмента области. Буфер Линии выбирает области 31x31 пикселя и возвращает их один столбец за один раз. Алгоритм использует столбец, чтобы вычислить вертикальные веса и общие массы. Для горизонтальных весов проект комбинирует столбцы, чтобы получить 31x31 ядро. Можно выбрать веса в зависимости от того, что вы хотите, чтобы "центр" имел в виду. Этот пример использует -15:15
так, чтобы центром 31x31 область был (0,0)
в вычисленном результате.
Блоки Vision HDL Toolbox обеспечивают выходные данные, чтобы обнулить, когда выход не допустим, как обозначено в шине pixelcontrol выход. В то время как не строго требуемый, это поведение делает тестирование и отладку намного легче. Чтобы выполнить это поведение для центроидных результатов, модель использует блоки 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 к подсистемам наложения. Выравниватель компенсирует задержку обработки, добавленную всеми предыдущими частями алгоритма обнаружения, не имея необходимость знать что-либо о задержке тех блоков. Если вы позже изменяете размер окружения или добавляете больше обработки, выравниватель может компенсировать. Если общая задержка превышает Максимальное количество параметра линий блока 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 '
Основанная на вере подсистема наложения имеет горизонтальный и вертикальный счетчик с набором четырех компараторов, который использует центр обнаруженной области как центр области для маркера. Данные о маркере используются в качестве двоичного переключателя, который включает наложение альфа-канала. Альфа-значение является фиксированным параметром прозрачности, примененным, когда усиление на двоичном файле Обнаруживает сигнал, когда это распаковано в подсистеме ExpandData.
open_system([modelname '/PotHoleHDL/Fiducial31x31'],'force');
Символьный шрифт ROM для экранного отображения хранит данные способом, похожим на основанный на вере ROM, описанный выше. Каждый 16-битный номер фиксированной точки представляет 16 последовательных горизонтальных пикселей. Карты символов 16x16.
Поскольку символьные данные обычно писались бы центральным процессором в ASCII, самый простой путь состоит в том, чтобы хранить символьные данные под 8-битными адресами ASCII в двухпортовом RAM. Шрифт ROM хранит символы ASCII 33 ("!") к 122 ("z"). Проект возмещает адрес 33.
Шрифт ROM был создан из шрифта фиксированной ширины общественного достояния с несколькими редактированиями, чтобы улучшить удобочитаемость. Как в основанном на вере маркере, символьные данные ROM используются в качестве двоичного переключателя, который включает наложение альфа-канала. Символьное альфа-значение является фиксированным параметром прозрачности, примененным как усиление на Обнаружить сигнал, когда это распаковано в подсистеме ExpandData.
Визуализировать символьный B
в шрифте ROM отобразите его в двоичном файле.
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 Coder™.
Чтобы сгенерировать HDL-код, используйте следующую команду.
makehdl('PotHoleHDLDetector/PotHoleHDL')
Чтобы сгенерировать испытательный стенд, используйте следующую команду. Обратите внимание на то, что генерация испытательного стенда занимает много времени из-за большого размера данных. Можно хотеть уменьшать время симуляции прежде, чем сгенерировать испытательный стенд.
makehdltb('PotHoleHDLDetector/PotHoleHDL')
Часть этой модели, которую можно реализовать на FPGA, является частью между Системой координат К Пикселям и Пикселями, Чтобы Структурировать блоки. Это - подсистема под названием PotHoleHDL, который включает все элементы детектора.
Теперь, когда у вас есть HDL-код, можно симулировать его в симуляторе HDL. Автоматически сгенерированный испытательный стенд позволяет вам доказывать, что симуляция Simulink и симуляция HDL соответствуют.
Можно также синтезировать сгенерированный HDL-код в инструменте синтеза FPGA, таком как Xilinx Vivado. В FPGA Virtex-7 (xc7v585tffg1157-1), проект достигает тактовой частоты более чем 150 МГц.
Отчет использования показывает, что двусторонний фильтр, пиксельный потоковый выравниватель и центроидные функции используют большинство ресурсов в этом проекте. Двусторонний фильтр требует большей части DSPS. Центроидная реализация довольно эффективна и использует только два DSPS. Центроидное вычисление также требует взаимной интерполяционной таблицы и так использует большое количество LUTs как память.
Этот пример показывает одну возможную реализацию алгоритма для обнаружения выбоин. Этот проект мог быть расширен следующими способами:
Порог градиента мог быть вычислен из средней яркости с помощью серо-мировой модели.
Трапециевидный блок маски мог быть сделан "управляемым" путем рассмотрения положения колеса транспортного средства и корректировки линейного пригодного для скошенных сторон маски.
Детектор мог быть сделан более устойчивым путем рассмотрения средней яркости RGB или изображения интенсивности относительно окружающего тротуара, поскольку выбоины являются обычно более темными в интенсивности, чем окружающее пространство.
Визуальная спектрограмма частоты выбоины могла также использоваться, чтобы искать определенные типы поверхностей в выбоинах.
Пороговое значение области обнаружения могло быть вычислено с помощью средней интенсивности в трапециевидной области шоссе.
Несколько выбоин могли быть обнаружены в одной системе координат путем хранения верхней части N ответы, а не только максимальный обнаруженный ответ. Основанная на вере подсистема маркера должна была бы быть перепроектирована немного, чтобы допускать перекрывающиеся маркеры.
Эта модель показывает, как алгоритм обнаружения выбоины может быть реализован в FPGA. Много полезных частей этого детектора могут быть снова использованы в других приложениях, таких как центроидный блок и основанные на вере и символьные блоки наложения.
[1] Кох, Кристиан и Яннис Брилакис. "Обнаружение выбоины в изображениях тротуара асфальта". Усовершенствованная Техническая Информатика 25, № 3 (2011): 507-15. doi:10.1016/j.aei.2011.01.002.
[2] Оманович, Самир, эмир Буза и Элвин Хусейнович. "Обнаружение выбоины с обработкой изображений и спектральной кластеризацией". 2-я международная конференция по вопросам сетей информационных технологий и компьютера (ICTN '13), Анталья, Турция. Октябрь 2013.