Алгоритм межкадровой разности на FPGA стереокамере

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

В этой статье я расскажу о продолжении работы над своим проектом стереокамеры на базе FPGA Gowin. В последней версии я добавил блок расчета попиксельной межкадровой разницы, используя встроенную в один корпус с ПЛИС SDR SDRAM память.

В предыдущей статье я рассказал о своем DIY проекте, стереокамере на базе FPGA, которая подключается к Arduino Portenta H7 и работает под управлением библиотеки машинного зрения OpenMV. FPGA в моем проекте управляет парой видео сенсоров, склеивает видео поток из двух источников и передает на Arduino. Поскольку в проекте оставались свободные ресурсы FPGA, я решил добавить аппаратную обработку видео в конвейер. В проекте используется чип GW2AR-LV18QN88 со встроенной SDRAM памятью, размера и быстродействия которой вполне хватит чтобы буферизировать кадры с камеры на максимальной скорости, это позволяет реализовать алгоритм межкадровой разности на стереоизображении. Чтож, начнем.

Для чего используется алгоритм

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

Рисунок 1 Пример OpenMV : Basic Frame Differencing
Рисунок 1 Пример OpenMV : Basic Frame Differencing

 

Рисунок 2 Запись результата работы примера Basic Frame Differencing с одним референсным кадром
Рисунок 2 Запись результата работы примера Basic Frame Differencing с одним референсным кадром

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

Рисунок 3 Запись результата работы алгоритма на FPGA. Каждый новый кадр сравнивается с предыдущим
Рисунок 3 Запись результата работы алгоритма на FPGA. Каждый новый кадр сравнивается с предыдущим

Реализация на FPGA

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

Рисунок 4 Структурная схема блока расчета разности кадров
Рисунок 4 Структурная схема блока расчета разности кадров

Никаких особых алгоритмических ухищрений тут не потребовалось, реализация довольно простая - копим во входном FIFO блок данных для записи, записываем в память, параллельно читаем из буфера предыдущий блок из такой же позиции в кадре, записываем результат разности в выходное FIFO. По достижению конца кадра меняем буфер чтения и записи местами.  Для меня интерес представляло изучение SDRAM памяти, которая расположена в едином корпусе с FPGA, до этих пор я никогда с подобными чипами не работал. Характеристики встроенной SDRAM памяти:

  • Разрядность - 32 бита

  • Емкость - 64Мб

  • Максимальная частота работы - 166Мгц

Теоретически память может обеспечить пропускную способность в 540 кадров в секунду на монохромном разрешении 1280x480 и максимальной частоте, запас многократный.

Для работы с памятью используется специальный IP блок : SDRAM Controller (With embedded SDRAM)

Рисунок 5 SDRAM Controller (With embedded SDRAM) IP
Рисунок 5 SDRAM Controller (With embedded SDRAM) IP

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

Порты с префиксом sdram прокидываются на верхний уровень проекта, и далее они автоматически подключаются к внутренней микросхеме памяти, порты с префиксом sdrc подключаются к управляющей логике и шинам данных – входной и выходной.  Диаграммы чтения и записи представлены ниже:

Рисунок 6 Запись данных в SDRAM
Рисунок 6 Запись данных в SDRAM
Рисунок 7 Чтение данных из SDRAM
Рисунок 7 Чтение данных из SDRAM

Чтобы начать процедуру чтения или записи, необходимо сформировать импульс на входе rd_n или wr_n соответственно. Процедура не может быть начата при неактивном сигнале init_done или активном сигнале busy_n. Длина данных указывается со смещением в 1 слово, таким образом, чтобы записать 64 слова данных на входе data_len, нужно подать значение 63. Как видно из диаграмм чтения и записи, модуль не содержит сигналов обратной связи, это означает что весь блок данных длиной data_len должен быть предварительно готов к непрерывной выдаче из промежуточного буфера в случае записи, и приемный буфер должен быть готов принять весь блок данных из контроллера в случае чтения. В противном случае данные будут потеряны.Чтобы этого не происходило, управляющий автомат перед стартом каждой транзакции проверят накоплено ли во входном FIFO необходимое количество данных и есть ли в выходном FIFO свободное место для приема. Только после соблюдения этих условия запускаются транзакции записи и чтения.

Тестирование

Для теста я написал скрипт, который с помощью методов OpenMV find_blobs находит изображения отдельно на левом и на правом полукадре, и рассчитывает их смещение друг относительно друга. В верхнем левом углу я вывел число и полоску с индикатором, по ним можно определить относительное расстояние до движущегося объекта. В данном тесте я столкнулся с проблемой "фрагментации" разностного изображения, т.к. за один кадр некоторые области внутри объекта не успевают достаточно измениться и на выходном изображении они не видны. Для достижения более стабильных результатов расчета расстояния я планирую добавить функции морфологического преобразования в конвейер, для того чтобы соединить отдельные изолированные области пикселей одного объекта в единую область.

Источник: https://habr.com/ru/articles/888408/


Интересные статьи

Интересные статьи

На сайте Госзакупок был размещен тендер на создание системы для электронного обмена данными между Минобороны и ФСБ о россиянах, которым были отправлены повестки из военкоматов. Тендер был опубликован ...
Практически в каждой компании есть корпоративная система поощрений. Но вот как прописать для неё правила, да ещё и на Битриксе, — вопрос. Делюсь личным опытом.Привет! Я full-stack веб-разработчик в IB...
У нас возникла задача добавить препроцессинг для параметров активити бизнес-процесса Битрикс24. Когда разбирались в задаче не смогли найти ни одного примера и решили выложить свой - может быть кто-ниб...
Недавно решил я в своем телеграм-канале поздравить подписчиков с Рождеством и написать фитозаметку о каком-нибудь растении. И к моему удивлению, с большим отрывом в этом голосовании победила греч...
Здравствуйте. Я уже давно не пишу на php, но то и дело натыкаюсь на интернет-магазины на системе управления сайтами Битрикс. И я вспоминаю о своих исследованиях. Битрикс не любят примерно так,...