Раскрывая потенциал GenICam и Harvester в системах компьютерного зрения
Опыт работы с крупнейшими производственными площадками позволяет сказать, что на сегодняшний день целый ряд производств считает современные цифровые технологии и, в частности технологии искусственного интеллекта, неотъемлемой частью производства. В ряде компаний создана экосистема цифровых продуктов, сформированы мощные команды поддержки и развития, создана культура разработки, внедрения и использования цифровых продуктов. Большинство крупных производственных компаний вступило в новую эру цифровизации производства в промышленных масштабах.
Введение
Одним из направлений искусственного интеллекта, широко внедряемым на производстве, являются системы компьютерного зрения. По прогнозам [1] динамика внедрения технологий компьютерного зрения в различных отраслях заметно растёт и составляет 36% в год. Наибольший объём внедрения технологий компьютерного зрения наблюдается в таких отраслях как: производство, здравоохранение, беспилотный транспорт и безопасность.
Ключевой задачей проектирования таких систем является эффективная интеграция и взаимодействие различных источников изображения (камер) в единой системе и их бесперебойная работа. При этом, чтобы уменьшить трудозатраты на масштабирование системы, упростить замену одних источников изображения другими и упростить поддержку реализованных решений желательно иметь какой-то универсальный подход работы с камерами и получению кадров.
Попробуем разобраться в том, возможно ли построить такую универсальную платформу для работы с промышленными камерами и что нам для этого нужно.
Всех объединяет GENCAM
Современные цифровые камеры обладают гораздо большей функциональностью, чем просто предоставление изображения, они также умеют, например, управлять настройками картинки в реальном времени, налету обрабатывать изображения и добавлять результаты в видеопоток, детектировать движение объектов в кадре и многое другое.
В начале 2000х ряд ведущих компаний производителей промышленных камер для систем компьютерного зрения, а также комитет Европейской ассоциации машинного зрения (EMVA) предпринял попытку создания единого стандарта работы с промышленными камерами, что привело к созданию стандарта GenICam [2].
GenICam реализует на низком уровне взаимодействие с устройствами, поддерживающими стандарт GenICam, при этом имеющими различные интерфейсы, такие, например, как: GigE Vision, USB3 Vision, CoaXPress, Camera Link HS, Camera Link, 1394 DCAM.
Получается, что GenICam является мостом между камерами с различными интерфейсами и пользовательским программным обеспечением, позволяя использовать со стороны программного обеспечения унифицированный API. На рисунке 1 представлена схема использования унифицированного API для управления камерами посредством стандарта GenICam.
Рисунок 1. Схема использования унифицированного API для управления камерами посредством стандарта GenICam.
Стандарт GenICam состоит из двух основных модулей GenApi и GenTL.
Generic Application Programming Interface (GenApi)
Назначение: GenApi отвечает за настройку и управление параметрами камеры, таких, например, как: разрешение кадра, экспозиция, насыщенность, частота кадров и другие.
Функция: Используя транспортный слой стандарта GenICam позволяет устанавливать настройки камеры, описанные в xml-файле, который предоставляется производителем.
Generic Transport Layer (GenTL)
Назначение: GenTL является транспортным слоем стандарта GenICam и абстрагирует взаимодействие между пользовательским ПО и камерой. Позволяет приложениям общаться с камерами, не зная деталей основного транспортного механизма.
Функция: GenTL обеспечивает взаимодействие с камерой на низком уровне и выполняет такие функции как обнаружение устройств, потоковая передача данных, установка параметров камеры и обработка событий.
Одной из реализаций стандарта GenICam в среде Python, включая его составные части GenApi и GenTL является python-библиотека Harvester. О том, что это за зверь поговорим ниже.
Собираем урожай кадров с Harvester
Pieter Bruegel the Elder, The Harvesters, 1565, © The Metropolitan Museum of Art
Harvester, или сборщик урожая кадров, именно так разработчики назвали python-библиотеку, представляющую собой API в среде Python, которая реализует протокол GenICam [3]. По сути, Harvester является мостом между камерами и нашим python-приложением.
Почему именно Harvester?
Данная библиотека как большинство python-библиотек является опенсорс, широко применяется, имеет хорошую поддержку со стороны разработчиков и что очень немаловажно — имеет значительный список производителей, с которыми протестирована.
В таблице 1 собраны производители промышленных камер, с которыми протестирована работа библиотеки Harvester.
Таблица 1. Производители промышленных камер, протестированные с Harvester
Для работы Harvester использует пакет GenTL Producer — это C-реализация модулей GenApi и GenTL, для доступа к которым Harvester использует динамическую библиотеку из пакета GenTL Producer. Пакет GenTL Producer предоставляется производителем камер при её покупке, так же пакет доступен для скачивания на сайте производителя. Ряд производителей предоставляют свой пакет GenTL Producer в свободном доступе.
В таблице 2 представлены производители промышленных камер пакета GenTL Producer, который протестирован с библиотекой Harvester.
Таблица 2. Производители GenTL Producer
Вообще говоря, GenTL Producer любого производителя должен работать с любой камерой, поддерживающей стандарт GenICam, так как это, по сути, различные реализации одного и того же стандарта. Так-то оно так, но не совсем! Особенность заключается в том, что некоторые производители делают GenTL Producer так, что он работает с камерами сторонних производителей с ограничениями — например через 200 взятых с камеры кадров на кадрах появляется предупреждающее сообщение от производителя (рисунок 2).
Рисунок 2. Предупреждающее сообщение на кадрах, при использовании GenTL Producer для камер сторонних производителей
Но есть производители GenTL Producer, которые работают без ограничений с камерами сторонних производителей.
Итак, вернёмся к схеме нашей универсальной платформы со знаниями о Harvester и GenTL Producer, теперь схема будет выглядеть так как на рисунке 3.
Рисунок 3. Схема универсальной платформы работы с камерами с реализацией GenICam на базе Harvester и GenTL Producer
В обновлённой схеме теперь стандарт GenICam представлен его реализацией: python-библиотекой Harvester и пакетом GenTL Producer с динамической библиотекой GenTLProducer.cti.
Вот, дошли до самого интересного — до реализации и как это будет работать. Пока рассмотрим на функциональном уровне реализацию простейшего типового пайплайна для работы с камерами и захвата кадров. Схема пайплайна представлена на рисунке 4.
Рисунок 4. Схема типового пайплайна работы с камерами и взятия кадров.
Давайте подробнее рассмотрим каждый этап представленной схемы, какие функции на него распространяются. В пайплайне можно выделить 5 основных этапов:
Инициализация Harvester: создаётся экземпляр Harvester, к нему подключается GenTL Producer (динамическая библиотека, реализующая стандарт GenTL), загружается xml-файл параметров камеры.
Поиск камер в сети: сканируется локально вычислительная сеть и обнаруживаются доступные камеры, сохраняется список найденных камер и их атрибуты (MAC / IP адрес, серийный номер, статус доступа и др.).
Подключение к камере: проверяется валидность статуса доступа к камере и устанавливается соединение с необходимой камерой по её серийному номеру или другим атрибутам.
Установка параметров камеры: в камеру передаются и устанавливаются параметры, определяющие режим её работы, такие как: экспозиция частота кадров, разрешение, цветовая схема, насыщенность и др.
Захват кадров: запрашиваются и принимаются кадры от камеры в виде стандартного python-массива, а также принимаются атрибуты кадра (разрешение, цветовая и др.).
Теперь, давайте посмотрим, как рабочий пайплайн выглядит на программном уровне. Опустим установку библиотеки Harvester, она выполняется стандартным для всех python-библиотек способом и описана тут [4].
Реализация рабочего пайплайна
Посмотрим на простейшую программу, реализующую рабочий пайплайн.
Инициализация Harvester
#Импортируем Harvester
from harvesters.core import Harvester
#Создаём экземпляр Harvester
h = Harvester()
#Загружаем динамическую библиотеку, реализующую GenTL Producer
h.add_file('path/to/GenTLProducer.cti')
Поиск камер в сети
#Запрашиваем список устройств, поддерживающих стандарт GenICam.
h.update()
#Можем посмотреть список устройств в сети
h.device_info_list
#Выглядит device_info_list примерно так:
[{'access_status': 1, 'display_name': 'Allied Vision Technologies Mako G-234C (6409)(00:0f:31:5d:37:00)', 'id_': 'Mako G-234C (6409)(00:0f:31:5d:37:00)', 'model': 'Mako G-234C (6409)', 'parent':
Подключение к камере
#Создаём объект захвата кадров ia.
#Подключаемся к камере по серийному номеру и проверяем статус доступа
ia = h.create({'access_status': 1, 'serial_number': '50-0536980096'})
Установка параметров камеры
#Устанавливаем частоту кадров
ia.remote_device.node_map.AcquisitionFrameRateAbs.value = 2
#Устанавливаем экспозицию кадра
ia.remote_device.node_map.ExposureTimeAbs.value = 400
#Устанавливаем цветовую насыщенность кадра
ia.remote_device.node_map.Saturation.value = 400
#Полный список параметров возможных к установке для данной камеры можно получить следующей командой:
dir(ia.remote_device.node_map)
Захват кадров
#Запускаем захват кадров
ia.start()
#Ловим кадры в буффер, здесь объект ia будет ждать от камеры буффер с кадром в течение 3х секунд
with ia.fetch(timeout=3) as buffer:
#Если буфер от камеры пришёл, кладём содержимое буфера в frame
frame = buffer.payload.components[0]
#Завершаем работу захвата кадров и освобождаем камеру
ia.stop()
ia.destroy()
#Теперь в структуре frame лежит наш долгожданный кадр в виде стандартного python массива (numpy array), а также его основные атрибуты.
Это довольно примитивный пайплайн для взятия всего одного кадра, однако, он хорошо показывает принцип работы с GenICam камерами через Harvester API. Не правда ли, довольно просто и лаконично! А если учесть, что представленный код будет работать для любой камеры стандарта GenICam, получается, что мы добились определённого универсализма в нашем подходе.
По сути, для нашей универсальной платформы работы с камерами осталось реализовать только одно недостающее звено — это программный модуль, оперирующий представленными выше простыми командами Harvester API по требуемому нам алгоритму. Назовём этот программный модуль к примеру FrameGrabber. Тогда окончательная схема нашей универсальной платформы работы с камерами будет выглядеть так как на рисунке 5.
Рисунок 5. Схема универсальной платформы работы с камерами.
В дополнение к предыдущей схеме (рисунок 3) на этой схеме показан программный модуль FrameGrabber, который является верхнеуровневым модулем работы с камерами и реализует базовые функции типового пайплайна, использует в своём ядре библиотеку Harvester. Так же на схему я добавил логотипы со стэком, используемых для реализации платформы технологий. Так, FrameGrabber и Harvester реализованы на python, GenTL Producer на C. Платформа может быть развёрнута как на операционной системе Linux, так и на Windows, что определяет выбор реализации пакета GenTL Producer.
Конфигурирование камер
Ещё один момент, на котором я бы хотел остановиться — это xml-файл параметров камеры. Ранее я упоминал, что данный файл предоставляется производителем. Кстати, данный файл также можно получить, сделав импорт текущих настроек камеры в файл из пользовательского интерфейса штатной (поставляемой в комплекте с камерой) программы управления камерой. На рисунке 5 показаны три xml-файла параметров, для трёх различных камер в нашей схеме, которые использует FrameGrabber для установки необходимых параметров в ходе работы.
Давайте коснёмся структуры xml-файла и разберём её. Как правило xml-файл выглядит примерно так, как на рисунке 6.
Рисунок 6. xml-файл описания параметров камеры
Секция CameraSettings содержит идентификатор камеры DEV_000F315D36FC и её модель Mako G-234C. Основная секция с параметрами камеры — это секция FeatureGroup. Каждая строка в этой группе соответствует отдельному параметру и содержит следующие поля для его описания:
— Name — Название параметра;
— Type — тип передаваемого значения;
— Access — вид доступа к параметру;
— value — передаваемый параметр.
Например, в нашем xml-файле параметр AcquisitionFrameRateAbs (частота кадров камеры) имеет тип данных float, вид доступа R/W (чтение / запись) и значение 2.0. (Рисунок 7).
Рисунок 7. Пример параметра AcquisitionFrameRateAbs
Кстати, данная камера имеет 70 основных параметров для установки — не мало! Это отражено в поле Count = 70, группы FeatureGroup.
Для взятия из xml-файла того или иного параметра и отправки его в камеру нам необходим парсер xml-файла, который в нашей схеме универсальной платформы реализован в модуле FrameGrabber.
Заключение
Представленное решение универсальной платформы реализовано и успешно апробировано в составе системы компьютерного зрения на крупной производственной площадке. Система компьютерного зрения включает 12 независимых GenICam камер от производителей Allied Vision и Hikrobot.
Данное решение на базе стандарта GenICam и библиотеки Harvester обеспечивает универсальную и эффективную платформу для работы с промышленными камерами в системах компьютерного зрения. Это решение не только облегчает интеграцию разнообразных камер, но и упрощает масштабирование систем, обеспечивает гибкость в поддержке и обновлении оборудования, а также повышает эффективность разработки и поддержки приложений компьютерного зрения.
Принимая во внимание широкое применение технологий компьютерного зрения, а также рост интеграций этих технологий в различных отраслях, от производства до беспилотного транспорта, предложенная платформа представляет собой значительный интерес при создании и индустриализации систем компьютерного зрения.
Источники
1. https://www.marketresearchfuture.com/reports/ai-in-computer-vision-market-6672
2. https://www.emva.org/wp-content/uploads/GenICam_Standard_v2_1_1.pdf
3. https://github.com/genicam/harvesters
4. https://harvesters.readthedocs.io/en/latest/INSTALL.html