Последние несколько лет я проектировал и создавал машину, которая распознает и сортирует детали LEGO. Наиболее важной частью машины является Блок захвата , небольшой, почти полностью закрытый отсек, в котором находится конвейерная лента, освещение и камера.
Вы увидите освещение чуть ниже.
Камера фотографирует детали LEGO, сходящие с конвейера, а затем передает изображения по беспроводной сети на сервер, который запускает алгоритм искусственного интеллекта для распознавания детали среди тысяч возможных элементов LEGO. Подробнее об алгоритме ИИ я расскажу в будущих статьях, но в этой статье основное внимание будет уделено обработке, которая выполняется между «сырым» видеовыходом камеры и входом в нейронную сеть.
Основная проблема, которую мне нужно было решить, — преобразование видеопотока с конвейера в отдельные изображения деталей, которые могла бы использовать нейросеть.
Конечная цель: перейти от необработанного видео (слева) к набору изображений одинакового размера (справа) для передачи в нейронную сеть.
(по сравнению с реальной работой, гифка замедлена примерно в два раза) Это отличный пример проблемы, которая на первый взгляд кажется простой, но на самом деле создает множество уникальных и интересных препятствий, многие из которых уникальны для платформ машинного зрения.
Извлечение нужных частей изображения таким способом часто называют обнаружением объектов.
Это именно то, что мне нужно сделать: распознать наличие объектов, их расположение и размер, чтобы я мог генерировать ограничивающие рамки для каждой детали в каждом кадре.
Самое главное — найти хорошие ограничивающие рамки (показаны выше зеленым цветом).
Я рассмотрю три аспекта решения проблемы:
- Подготовка путем исключения ненужных переменных
- Создание процесса из простых операций машинного зрения
- Поддержание адекватной производительности на платформе Raspberry Pi с ограниченными ресурсами.
Устранение ненужных переменных
Для решения подобных проблем лучше всего исключить как можно больше переменных, прежде чем применять методы компьютерного зрения.Например, мне не следует беспокоиться об условиях окружающей среды, разном положении камеры или потере информации из-за перекрытия одних частей другими.
Конечно, можно (хотя и очень сложно) разрешить все эти переменные программно, но, к счастью для меня, эта машина строится с нуля.
Я сам могу подготовиться к успешному решению, устранив все препятствия еще до того, как начну писать код. Первый шаг — твердо зафиксировать положение, угол и фокус камеры.
С этим все просто – в системе камера закреплена над конвейером.
Мне также не нужно беспокоиться о помехах со стороны других частей; нежелательные объекты практически не имеют шансов попасть в блок захвата.
Немного сложнее, но очень важно обеспечить постоянные условия освещения .
Я не хочу, чтобы распознаватель объектов ошибочно интерпретировал тень движущейся по ленте детали как физический объект. К счастью, блок захвата очень маленький (все поле зрения камеры меньше буханки хлеба), поэтому контроля над окружающей средой у меня было более чем достаточно.
Блок захвата, вид изнутри.
Камера находится в верхней трети кадра.
Одним из решений является сделать отсек полностью закрытым, чтобы свет снаружи не проникал.
Я попробовал этот подход, используя светодиодные ленты в качестве источника света.
К сожалению, система оказалась очень капризной — достаточно одной маленькой дырочки в корпусе и в отсек проникает свет, делающий невозможным распознавание предметов.
В конечном итоге лучшим решением оказалось «забить» все остальные источники света, затопив небольшой отсек сильным освещением.
Оказалось, что источники света, которые можно использовать для освещения жилых помещений, очень дешевы и просты в использовании.
Возьмите это, тени!
Направляя источник в крошечный отсек, он полностью блокирует все потенциальные внешние световые помехи.
Есть у этой системы и удобный побочный эффект: благодаря большому количеству света в камере можно использовать очень высокие выдержки, получая идеально четкие изображения деталей даже при быстром движении по конвейеру.
Распознаватель объектов
Так как же мне превратить это красивое, равномерно освещенное видео в нужные мне ограничивающие рамки? Если вы работаете с ИИ, вы могли бы предложить мне реализовать нейронную сеть для распознавания таких объектов, как ЙОЛО или Быстрее R-CNN .Эти нейронные сети легко справятся с поставленной задачей.
К сожалению, я запускаю код распознавания объектов на Raspberry Pi .
Даже у мощного компьютера возникли бы проблемы с запуском этих сверточных нейронных сетей с необходимой мне скоростью, около 90 кадров в секунду.
А Raspberry Pi, у которого нет AI-совместимого графического процессора, не сможет справиться с очень урезанной версией одного из этих алгоритмов AI. Я могу транслировать видео с Pi на другой компьютер, но передача видео в реальном времени — очень привередливый процесс, а ограничения задержки и пропускной способности вызывают серьезные проблемы, особенно когда необходимы высокие скорости передачи данных.
ЙОЛО очень крутой! Но мне не нужны все его функции.
К счастью, мне удалось избежать сложного решения искусственного интеллекта, используя методы компьютерного зрения «старой школы».
Первая техника – это вычитание фона , который пытается выделить все измененные части изображения.
В моем случае единственное, что движется в поле зрения камеры, — это детали LEGO. (Конечно, лента тоже движется, но, поскольку она однородного цвета, камере кажется неподвижной.
) Давайте отделим эти детали LEGO от фона, и половина проблемы будет решена.
Чтобы вычитание фона работало, объекты переднего плана должны значительно отличаться от фона.
Детали LEGO представлены в широком диапазоне цветов, поэтому мне пришлось быть очень осторожным при выборе цвета фона, чтобы он был как можно дальше от цветов LEGO. Именно поэтому лента под камерой сделана из бумаги - она не только должна быть очень однородной, но и не может быть сделана из LEGO, иначе это будет цвет одной из деталей, которую мне нужно распознать! Я выбрал бледно-розовый, но подойдет любой пастельный цвет, кроме обычных цветов LEGO. В замечательной библиотеке OpenCV уже есть несколько алгоритмов вычитания фона.
Вычитатель фона MOG2 — самый сложный из всех, но при этом он работает невероятно быстро даже на Raspberry Pi. Однако подача видеокадров непосредственно в MOG2 работает не очень хорошо.
Светло-серые и белые фигуры слишком близки к яркости бледного фона и теряются на нем.
Мне нужно было придумать способ более четко отделить ленту от деталей на ней, приказав вычитателю фона присмотреться к ним повнимательнее.
цвет , не на яркость .
Для этого мне просто нужно было увеличить насыщенность изображений, прежде чем передать их в функцию вычитания фона.
Результаты значительно улучшились.
После вычитания фона мне нужно было использовать морфологические операции, чтобы избавиться от как можно большего количества шума.
Чтобы найти контуры белых областей, вы можете использовать функцию findContours() библиотеки OpenCV. Применяя различные эвристики для отклонения ребер, содержащих шум, можно легко преобразовать эти ребра в готовые ограничивающие рамки.
Производительность
Нейронная сеть — существо прожорливое.Для достижения наилучших результатов классификации требуются изображения максимального разрешения и в как можно большем количестве.
Это означает, что мне нужно снимать их с очень высокой частотой кадров, сохраняя при этом качество и разрешение изображения.
Мне нужно максимально эффективно использовать камеру и графический процессор Raspberry PI. Очень подробно документация по пикамере Написано, что чип камеры V2 может выдавать изображения размером 1280х720 пикселей с максимальной частотой кадров 90 кадров в секунду.
Это невероятный объем данных, и хотя камера может их генерировать, это не значит, что компьютер может их обработать.
Если бы я обрабатывал необработанные 24-битные изображения RGB, я бы передавал данные со скоростью около 237 МБ/с, что слишком много как для плохого графического процессора Pi, так и для SDRAM. Даже при сжатии JPEG с ускорением графического процессора невозможно достичь скорости 90 кадров в секунду.
Камера Raspberry Pi способна выводить необработанное, нефильтрованное изображение YUV. Хотя работать с YUV сложнее, чем с RGB, на самом деле он обладает множеством полезных свойств.
Самым важным из них является то, что он хранит только 12 бит на пиксель (у RGB — 24 бита).
Каждые четыре байта Y содержат один байт U и один байт V, то есть на пиксель приходится 1,5 байта.
Это означает, что по сравнению с кадрами RGB я могу обрабатывать в два раза больше YUV-кадры, и это даже не считая дополнительного времени, которое графический процессор экономит на преобразовании в RGB-изображение.
Однако этот подход накладывает уникальные ограничения на процесс обработки.
Большинство операций с полнокадровым видео потребляют огромное количество памяти и ресурсов ЦП.
Даже невозможно декодировать полноэкранный кадр YUV в рамках моих строгих ограничений по времени.
К счастью, мне не нужно обрабатывать весь кадр! Для распознавания объектов ограничивающие рамки не обязательно должны быть точными, достаточно приблизительной точности, поэтому весь процесс распознавания объектов можно выполнить в гораздо меньшем кадре.
Операция уменьшения масштаба не обязательно должна учитывать все пиксели полноразмерного кадра, поэтому размер кадра можно уменьшить очень быстро и с минимальными затратами.
Полученные ограничивающие рамки затем снова масштабируются и используются для обрезки объектов из полноразмерного кадра YUV. Таким образом, мне не придется декодировать или иным образом обрабатывать весь кадр высокого разрешения.
К счастью, благодаря тому, как хранится этот формат YUV (см.
выше), очень легко реализовать операции быстрой обрезки и уменьшения масштаба, которые работают непосредственно с форматом YUV. Кроме того, весь процесс можно без проблем распараллелить на четырех ядрах Pi. Однако я обнаружил, что не все ядра используются в полную силу, что говорит нам о том, что узким местом по-прежнему остается пропускная способность памяти.
Но даже при этом мне на практике удалось добиться 70-80FPS. Более глубокий анализ использования памяти, возможно, поможет еще больше ускорить процесс.
Если вы хотите узнать больше о проекте, то прочитайте мою предыдущую статью.
«Как я создал более 100 000 размеченных изображений LEGO для преподавания» .
Видео всей сортировочной машины в работе: Теги: #Машинное обучение #Raspberry Pi #Разработка Raspberry Pi #искусственный интеллект #распознавание изображений #машинное зрение #lego
-
Избавление От Шпионского И Рекламного По
19 Oct, 24 -
Готовы К Ddos-Атаке!
19 Oct, 24 -
It-Девушка, Где Твое Золото?
19 Oct, 24 -
Создание Собственной Прошивки Openwrt
19 Oct, 24 -
Простая Реализация Небольших Cam На Fpga
19 Oct, 24