Определение социальной дистанции с помощью Raspberry Pi и OpenCV


В неутихающей сейчас пандемии коронавируса Covid-19 поддержание социальной дистанции между людьми является эффективной мерой сдерживания распространения этого вируса. За обеспечением социальной дистанции в настоящее время следят практически во всех общественных местах: банках, торговых центрах, промышленных предприятиях, центрах социальной помощи и т.д.

В данной статье мы рассмотрим автоматическое определение социальной дистанции между людьми с помощью платы Raspberry Pi и библиотеки OpenCV. Результаты этого процесса будут в наглядном виде отображаться на экране дисплея. Для решения задачи определения социальной дистанции мы будем использовать алгоритм обнаружения объектов (Object Detection Algorithm) YOLO v3 с модулем "продвинутой" нейронной сети (Deep Neural Network module).

Внешний вид проекта определения социальной дистанции с помощью Raspberry Pi и OpenCV

Плата Raspberry Pi является отличным выбором для решения сложных задач обработки изображений, поскольку она отличается от других популярных сейчас микроконтроллеров и плат на их основе (Arduino) наличием большого объема памяти и значительной вычислительной мощностью. Ранее мы использовали библиотеку OpenCV на Raspberry Pi для решения таких задач обработки изображений как распознавание лиц, оптическое распознавание текста и обнаружение движения на транслируемом видео.

Также на нашем сайте вы можете посмотреть другие проекты, связанные с текущей пандемией коронавируса:

Необходимые компоненты

Плата Raspberry Pi 4 (купить на AliExpress).

Для обработки изображений используется библиотека OpenCV. Ее необходимо предварительно установить на плату Raspberry Pi.

Алгоритм YOLO

YOLO (You Only Look Once) – это свёрточная нейронная сеть (Convolution neural network, CNN) для обнаружения объектов (Object Detection) в режиме реального времени. На момент написания оригинала данной статьи (сентябрь 2020 г., ссылка на оригинал приведена в конце статьи) ее самой последней версией являлась YOLOv3 (на момент прочтения вами этой статьи, возможно, есть уже более свежие версии этого алгоритма).

YOLO может распознавать до 80 различных объектов на изображениях и видео потоках, отличается высокой скоростью работы и превосходной точностью распознавания. Алгоритм использует одинарную (single) нейронную сеть для анализа целого изображения, затем разделяет изображение на части (области) и рассчитывает граничные условия и вероятности для каждой области. Базовая модель алгоритма YOLO может обрабатывать изображения в режиме реального времени, следующие с частотой 45 кадров в секунду. Алгоритм YOLO использует такие методы обнаружения объектов как SSD и R-CNN.

Модель алгоритма YOLOV3, которую мы будем использовать в данном проекте, можно скачать по следующей ссылке.

Установка OpenCV на Raspberry Pi

Перед тем как устанавливать OpenCV и необходимые ей приложения на Raspberry Pi необходимо обновить программное обеспечение платы до последней версии с помощью команды:

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

И, наконец, установим OpenCV на Raspberry Pi с помощью команды:

Если вам необходима более "глубокая" (с компиляцией) установка OpenCV на Raspberry Pi, то вы можете сделать это с помощью CMake – но в этом случае процесс ее установки займет несколько часов.

Установка других необходимых пакетов на Raspberry Pi

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

Объяснение программы для Raspberry Pi

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Первым делом нам необходимо подключить (импортировать) все используемые в проекте библиотеки.

Далее запрограммируем функцию Check() для расчета расстояния между двумя объектами или двумя точками на кадре видеопотока. В этой функции точки a и b обозначают два объекта в кадре. Эти две точки используются для расчета евклидова расстояния между объектами.

Функция Setup(yolo) используется для установки маршрутов для весов/весовых коэффициентов (weights) в алгоритме YOLO, файла cfg, файла COCO names. Модуль os.path используется для операций с путями к файлам. Модуль os.path.join() является под-модулем модуля os.path и предназначен для интеллектуального объединения одного или более компонентов пути. Метод cv2.dnn.readNetFromDarknet() используется для загрузки сохраненных весов в сеть. После загрузки весов мы будем извлекать список всех слоев, используемых в сети, с помощью модели net.getLayerNames.

Внутри функции обработки изображений мы будем захватывать одиночный кадр с видео потока и производить его анализ, а именно определение социальной дистанции между всеми людьми, присутствующими на изображении кадра. В первых двух строках этой функции мы устанавливаем размеры видео кадра (W, H), для начала равные (None, None). В следующей строке мы используем метод cv2.dnn.blobFromImage() для загрузки кадров в пакет и затем прогоняем этот пакет через нейронную сеть. Также внутри этой функции выполняется вычитание, масштабирование и обмен каналами в кадре.

Выход слоя в алгоритме YOLO состоит из набора значений. Эти значения помогают нам определить класс, к которому относится анализируемый объект. Когда мы на изображении будем обнаруживать людей, мы будем устанавливать класс метки как "person". Для каждого обнаруженного человека мы будем формировать ограничивающий его прямоугольник, для которого нам будут известны координаты его центра X center и Y center, ширина (Width) и высота (Height).

После этого мы будем рассчитывать расстояние между центром текущего анализируемого прямоугольника и центрами другим обнаруженных прямоугольников. Если эти прямоугольники будут слишком близко друг к другу, мы будем изменять status на true.

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

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

Далее мы будем использовать функцию cv2.VideoWriter() для хранения видео выхода в позиции, определенной переменной opname, которую мы определили ранее.

Тестирование работы проекта

После того, как код программы будет готов, откройте терминал платы Raspberry Pi и его помощью перейдите в каталог с вашим проектом. Код программы, модель Yolo и видео для теста (demo video) должны располагаться в одном и том же каталоге как показано на следующем рисунке.

Расположение всех компонентов проекта в одном каталоге

Каталог с YoloV3 мы можете скачать по этой ссылке, видео для тестирования работы проекта можно скачать с Pexels, код программы находится в конце данной статьи, его нужно просто поместить в файл с расширением .py и скопировать этот файл в каталог проекта.

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

Автор проекта тестировал программу на видео, полученном от Pexels. В процессе теста он обнаружил, что число кадров в секунду (FPS) было достаточно маленьким, а на обработку всего видео уходило от 10 до 11 минут. Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.

Пример работы проекта

Вместо использования готового видео вы можете использовать видеопоток, получаемый с камеры Raspberry Pi. В этом случае в 98-й строчке кода необходимо заменить cv2.VideoCapture(input) на cv2.VideoCapture(0).

Исходный код программы на Python

Видео, демонстрирующее работу проекта

Источник статьи

(Проголосуй первым!)
Загрузка...
295 просмотров

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *