Введение

В этой статье я покажу вам, как использовать OpenVINO для обнаружения объектов. Я буду использовать дистрибутив Intel OpenVINO с Python API и PIP для установки необходимых пакетов Python.

Весь код в этой статье доступен на GitHub, если вы хотите поиграть с ним самостоятельно.

Требования

Если у вас еще не установлен OpenVINO, вы можете перейти на сайт официальной документации и получить руководство по установке.

NumPy необходим для работы с массивами и может быть установлен с помощью команды:

pip install numpy

OpenCV требуется для обработки изображений и может быть установлен с помощью команды:

pip install opencv-python

Модель

Модель, используемая для обнаружения объектов, — SSD MobileNet V2, доступная в зоопарке моделей OpenVINO, которая была обучена на наборе данных COCO.

Скачать модель можно с помощью загрузчика OpenVINO командой:

python3 <omz_dir>/tools/downloader/downloader.py --name ssd_mobilenet_v2_coco

Где <omz_dir> — это каталог open_model_zoo, в моем случае это:

/opt/intel/openvino_2021/deployment_tools/open_model_zoo

После загрузки модели ее необходимо преобразовать в промежуточное представление. Это можно сделать с помощью конвертера OpenVINO:

python3 <omz_dir>/tools/downloader/converter.py --name ssd_mobilenet_v2_coco --mo=<mo_path> --output_dir=<out_dir>

Где <mo_path> это путь к оптимизатору модели OpenVINO, который у меня такой:

/opt/intel/openvino_2021/deployment_tools/model_optimizer/mo.py

И <out_dir> - это каталог, в который вы хотите поместить файлы сконвертированной модели. Файлы будут помещены в <out_dir>/public/<model_name>.

Помимо самой модели, вам понадобится сопоставление между идентификаторами классов и именами классов. Вы можете скачать файл .json, содержащий пары ключ-значение идентификаторов и имен классов здесь.

Выполнение

Сначала сеть читается с использованием модели .xml и .bin:

После чтения сети извлекается информация о форме, расположении и размере ввода:

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

После чтения сети и извлечения информации сеть можно загрузить на устройство:

Где device — строка, указывающая имя устройства, на которое должна быть загружена модель. «CPU» указывает, что модель должна быть загружена в CPU, а «MYRIAD» указывает, что устройство должно быть загружено в Neural Compute Stick. Для простоты параметру num_requests присвоено значение 1, что означает, что одновременно обрабатывается только один запрос на вывод.

Затем сопоставление между идентификаторами классов и именами классов загружается в виде словаря из файла .json:

Прежде чем данные могут быть переданы в сеть, их необходимо подготовить, чтобы они имели правильную форму и расположение. Это можно сделать с помощью функции prepare_image():

После подготовки данных их можно передать в сеть, чтобы сделать вывод:

Результатом работы сети является большой двоичный объект формы [1, 1, N, 7], где N — количество обнаруженных ограничивающих рамок. Каждое обнаружение имеет формат: [image_id, label, conf, x_min, y_min, x_max, y_max]

Где label — идентификатор прогнозируемого класса, conf — достоверность прогнозируемого класса, (x_min, y_min) — координаты верхнего левого угла ограничивающей рамки, а (x_max, y_max) — координаты нижнего правого угла ограничивающей рамки. Обратите внимание, что координаты хранятся в нормализованном формате в диапазоне 0–1.

Чтобы визуализировать обнаружения, ограничивающую рамку и имя класса каждого обнаружения можно нарисовать на изображении с помощью функции draw_bounding_boxes():

Параметр threshold используется для фильтрации обнаружений на основе достоверности обнаружения.

Результаты

Ниже приведены несколько примеров обнаружений. Изображения были выбраны из набора данных COCO.

Источники