Введение
В этой статье я покажу вам, как использовать 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.