В этом примере пример «Создание изображений мультфильмов с использованием двусторонней фильтрации» включает вычисление центроида и наложение маркера центроида и текстовой метки на обнаруженные выбоины.
Обнаружение дорожной опасности или выбоины является важной частью любой автоматизированной системы вождения. Предыдущая работа [1] по автоматизированному обнаружению выбоины определяла выбоину как эллиптическую область в дорожном покрытии, которая имеет более темный уровень яркости и другую текстуру, чем окружающее дорожное покрытие. Затем обнаружение выбоин с использованием обработки изображения становится задачей поиска областей в изображении дорожного покрытия, которые соответствуют выбранному критерию. Можно использовать любую или все эллиптическую форму, более темную яркость или критерий текстуры.
Чтобы измерить эллиптическую форму, можно использовать алгоритм голосования, такой как круг Хафа, или алгоритм сопоставления шаблонов, или методы на основе линейной алгебры, такие как аппроксимация методом наименьших квадратов. Измерение уровня яркости является простым в обработке изображения путем выбора значения сегментации яркости. Текстура может быть оценена путем вычисления пространственной частоты в области с использованием таких методов, как БПФ.
В этом примере используется сегментация яркости с метрикой площади, так что меньшие дефекты не обнаруживаются. Чтобы найти центр дефекта, эта конструкция вычисляет центроид. Модель накладывает маркер в центре дефекта и текстовую метку на изображении.
Ниже показана система PotHureHDLDetector.slx. Подсистема PotHureHDL содержит детектор выбоин и алгоритмы наложения и поддерживает генерацию кода 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');

Подсистема PotHureHDL преобразует входное видео RGB в интенсивность, затем выполняет двустороннюю фильтрацию и обнаружение границ. Подсистема TrapezedMask выбирает область дорожного полотна. Затем конструкция применяет морфологическое закрытие и вычисляет координаты центроидов для всех потенциальных выбоин. Детектор выбирает самую большую выбоину в каждом кадре и сохраняет координаты центра. Выравниватель пиксельного потока соответствует синхронизации координат с входным потоком. Наконец, подсистемы Fiducial31x31 и Overlay32x32 применяют наложение альфа-канала на кадр для добавления маркера центра выбоины и текстовой метки.
open_system([modelname '/PotHoleHDL'],'force');

Подсистема имеет четыре входных параметра, которые могут изменяться во время работы системы.
Параметр интенсивности градиента «Порог градиента» управляет частью алгоритма, связанной с обнаружением краев.
Параметр RGB мультфильма изменяет цвет наложений, то есть реперный маркер и текст.
Параметр Area Threshold задает минимальное количество отмеченных пикселей в окне обнаружения, чтобы его можно было классифицировать как выбоину. Если это значение слишком низкое, то будут обнаружены линейные трещины и другие дефекты, которые не представляют опасности для дорог. Если он слишком высок, то будут обнаружены только самые большие опасности.
Конечный параметр Show Raw позволяет упростить отладку системы. Он переключает отображаемое изображение, на котором отображаются наложения, между входным видео RGB и двоичным изображением, которое видит детектор. Установите для этого параметра значение 1, чтобы увидеть, как работает детектор.
Все эти параметры работают лучше всего, если изменения разрешены только на границах видеокадров. Подсистема FrameBoundary регистрирует параметры только в допустимом начале кадра.
open_system([modelname '/PotHoleHDL/FrameBoundary'],'force');

Модель разделяет входной поток пикселей RGB так, что копия потока RGB продолжается в направлении блоков наложения. Первым шагом для детектора является преобразование из RGB в интенсивность. Поскольку типом входных данных для RGB является uint8, блок RGB to Intensity автоматически выбирает uint8 в качестве типа выходных данных.
Следующим шагом в алгоритме является уменьшение шума высокой визуальной частоты и меньших дорожных дефектов. Это может быть достигнуто многими способами, но использование двустороннего фильтра имеет преимущество, заключающееся в сохранении краев при уменьшении шума и меньших площадей.
Блок двустороннего фильтра имеет параметры для размера окрестности и два стандартных отклонения, одно для пространственной части фильтра и одно для части интенсивности фильтра. Для этого применения хорошо работает относительно большой район 9x9. В этой модели используются значения 3 и 0,75 для стандартных отклонений. С этими значениями можно поэкспериментировать позже.
Отфильтрованное изображение затем посылается в блок обнаружения краев Собеля, который находит края в изображении и возвращает те края, которые сильнее порогового параметра градиента. Выходные данные представляют собой двоичное изображение. В окончательном приложении этот порог может быть установлен на основе таких переменных, как дорожные условия, погода, яркость изображения и т.д. Для этой модели пороговое значение является входным параметром подсистемы PotHureHDL.
Из двоичного изображения кромки необходимо удалить все кромки, которые не относятся к обнаружению выбоин. Хорошей стратегией является использование маски, которая выбирает многоугольную область, представляющую интерес, и делает область вне этого черного. Модель не использует нормальный блок окупаемости инвестиций, так как это приведет к удалению контекста расположения, который потребуется позже для вычисления центроида и маркировки.
Порядок операций здесь также имеет значение, потому что если вы использовали маску до обнаружения края, края маски станут сильными линиями, что приведет к ложным срабатываниям на детекторе.
Во входном видео область, в которой транспортное средство может столкнуться с выбоиной, ограничена дорожным полотном непосредственно перед ним и трапециевидным участком дорожного полотна впереди. Точные координаты зависят от установки камеры и объектива. В этом примере используются фиксированные координаты для левого верхнего, правого верхнего, левого нижнего и правого нижнего углов области. Для этого видео верх и низ трапециевидной области не параллельны, поэтому это не истинная трапеция.
Маска состоит из прямых линий между углами, соединяющих левый, правый и верхний, нижний.
ltc---rtc
/ \
/ \
/ \
lbc-------------rbcВ этом примере используется polyfit для определения прямолинейной посадки из угла в угол. Для простоты реализации проект требует polyfit с вертикальным направлением в качестве независимой переменной. Это использование вычисляется x = f(y) вместо более обычного y = f(x). Используя polyfit этот способ позволяет использовать счетчик линии направления y в качестве входного адреса таблицы поиска координат x начала (слева) и конца (справа) интересующей области на каждой строке.
Таблица поиска обычно реализуется в BRAM в FPGA, поэтому она должна быть адресована адресацией на основе 0. Модель преобразует адресацию на основе MATLAB 1 в адресацию на основе 0 непосредственно перед LUT. Для дальнейшего уменьшения размера таблицы подстановки адрес смещается на начальную строку трапеции. Чтобы получить хорошие результаты синтеза, сопоставьте типичную блочную RAM, регистрирующуюся в FPGA, используя регистр после таблицы поиска. Этот регистр также добавляет некоторые скромные конвейеры в конструкцию.
Для изображения 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 пикселей. Он сохраняет координаты центра только тогда, когда обнаруженная площадь больше входного параметра. Это общее различие между аппаратными и программными системами: при проектировании аппаратных средств для FPGA часто проще вычислять непрерывно, но сохранять ответ только тогда, когда это необходимо, в отличие от вызова функций по мере необходимости в программном обеспечении.
Для вычисления центроида необходимо вычислить три вещи из области изображения: взвешенную сумму пикселей в горизонтальном направлении, взвешенную сумму в вертикальном направлении и общую сумму всех пикселей, которая соответствует области отмеченной части области. Буфер строк выбирает области размером 31x31 пикселей и возвращает их по одному столбцу за раз. Алгоритм использует столбец для вычисления вертикальных весов и общих весов. Для горизонтальных весов конструкция объединяет столбцы для получения ядра 31x31. Веса можно выбирать в зависимости от значения «центра». В этом примере используется -15:15 чтобы центр области 31x31 был (0,0) в вычисленном результате.
Блоки Vision HDL Toolbox приводят выходные данные к нулю, когда вывод недействителен, как указано на выходе шины пиксельного управления. Хотя это и не является строго обязательным, это делает тестирование и отладку намного проще. Чтобы выполнить это поведение для результатов центроида, модель использует блоки переключения с постоянным блоком, имеющим значение 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');

Блок выравнивания пиксельного потока принимает потоковую информацию от детектора и отправляет ее и исходный поток пикселя RGB подсистемам наложения. Выравниватель компенсирует задержку обработки, добавленную всеми предыдущими частями алгоритма обнаружения, не зная ничего о задержке этих блоков. Если позже изменить размер окрестности или добавить дополнительную обработку, выравниватель может компенсировать. Если общая задержка превышает параметр «Максимальное число строк» блока «Выравнивание пиксельного потока», настройте параметр.
Реперный маркер представляет собой квадратную сетку, представляемую в виде 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.
Поскольку символьные данные обычно записываются CPU в ASCII, самым простым способом является сохранение символьных данных под 8-битными адресами ASCII в двухпортовой оперативной памяти. В ПЗУ шрифта хранятся символы ASCII от 33 («!») до 122 («z»). Проект смещает адрес на 33.
ПЗУ шрифта было построено из общедоступного шрифта фиксированной ширины с несколькими изменениями для улучшения читаемости. Как и в реперном маркере, символьные данные ПЗУ используются в качестве двоичного переключателя, который включает наложение альфа-канала. Буквенное значение является фиксированным параметром прозрачности, применяемым в качестве коэффициента усиления к сигналу 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 Coder™.
Для создания кода HDL используется следующая команда.
makehdl('PotHoleHDLDetector/PotHoleHDL')
Для создания тестового стенда используется следующая команда. Следует отметить, что создание тестового стенда занимает много времени из-за большого размера данных. Перед созданием стенда можно сократить время моделирования.
makehdltb('PotHoleHDLDetector/PotHoleHDL')
Часть этой модели, которую можно реализовать в FPGA, является частью между блоками «От кадра до пикселей» и «От пикселей до кадра». Это подсистема, называемая PotHureHDL, которая включает в себя все элементы детектора.
Теперь, когда у вас есть код ЛПВП, вы можете смоделировать его в вашем симуляторе ЛПВП. Автоматически созданный стенд позволяет доказать, что моделирование Simulink и моделирование HDL совпадают.
Сгенерированный HDL-код также можно синтезировать в инструменте синтеза FPGA, таком как Xilinx Vivado. В Virtex-7 FPGA (xc7v585tffg1157-1) конструкция обеспечивает тактовую частоту более 150 МГц.
Отчет об использовании показывает, что функции двустороннего фильтра, выравнивания потока пикселей и центроида потребляют большую часть ресурсов в этой конструкции. Двусторонний фильтр требует наибольшего количества DSP. Реализация центроида достаточно эффективна и использует только два DSP. Расчет Centroid также требует ответной таблицы поиска и поэтому использует большое количество LUT в качестве памяти.

В этом примере показана одна возможная реализация алгоритма обнаружения выбоин. Эту конструкцию можно было бы расширить следующими способами:
Порог градиента может быть вычислен из средней яркости с использованием модели серого мира.
Трапециевидный маскирующий блок можно сделать «управляемым» путем просмотра положения колеса транспортного средства и регулировки линейной посадки для наклонных сторон маски.
Детектор может быть сделан более устойчивым путем просмотра средней яркости изображения RGB или интенсивности относительно окружающего дорожного покрытия, поскольку выбоины обычно темнее по интенсивности, чем окружающая область.
Визуальная частотная спектрограмма выбоины может также использоваться для поиска конкретных типов поверхностей в выбоинах.
Пороговое значение области обнаружения может быть вычислено с использованием средней интенсивности в трапециевидной области дорожного полотна.
Множество выбоин может быть обнаружено в одном кадре путем сохранения N верхних ответов, а не только максимального обнаруженного ответа. Необходимо немного изменить конструкцию подсистемы реперных обозначений, чтобы обеспечить перекрывающиеся маркеры.
Эта модель показывает, как алгоритм обнаружения выбоин может быть реализован в FPGA. Многие полезные части этого детектора могут быть повторно использованы в других применениях, таких как блок центроида и блоки наложения реперных знаков и символов.
[1] Кох, Кристиан и Иоаннис Брилакис. «Обнаружение выбоин на изображениях асфальтового покрытия». Усовершенствованная инженерная информатика 25, № 3 (2011): 507-15. doi: 10.1016/j.aei.2011.01.002.
[2] Оманович, Самир, Эмир Буза и Алвин Гусейнович. Вторая Международная конференция по информационным технологиям и компьютерным сетям (ICTN '13), Анталья, Турция. Октябрь 2013 года.