Обнаружение движения на видео с помощью Raspberry Pi и OpenCV


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

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

Мы напишем программу на python, которая будет одновременно мониторить 4 камеры системы видеонаблюдения (CCTV cameras) и обнаруживать на них движения. Если на изображении с какой либо из этих камер будет обнаруживаться движение, то Raspberry Pi будет автоматически переключаться на экран этой камеры и подсвечивать (выделять) место на изображении, на котором было зафиксировано движение. Это будет происходить в режиме реального времени, с задержкой 1,5 секунды. Также мы добавили звуковой сигнал тревоги, который будет подаваться с помощью зуммера при обнаружении движения. Но вы можете усовершенствовать данный проект, например, при обнаружении движения будет передаваться SMS на ваш телефон или отправляться E-mail на вашу электронную почту (похожий проект описан в этой статье).

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

Автор данного проекта (ссылка на оригинал приведена в конце статьи) использовал плату Raspberry Pi 3 B+ с установленной на нее Buster OS, но можно использовать и другие типы плат Raspberry Pi с другими операционными системами. Также автор проекта использовал OpenCV версии 4.1 – можно использовать и другие версии данной библиотеки, но не ниже 4.1.

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

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

Также вы можете посмотреть все проекты на нашем сайте, в которых использовалась OpenCV.

Установка зуммера на 5-дюймовый дисплей

После подключения 5-дюймового сенсорного дисплея к плате Raspberry Pi, мы можем непосредственно подключить зуммер к задней стороне дисплея, к его неиспользуемым для подключения к плате Raspberry Pi контактам. Мы закрепили зуммер на тыльной стороне 5-дюймового дисплея следующим образом:

Установка зуммера на 5-дюймовый сенсорный дисплей

В таблице ниже представлено назначение контактов (распиновка) 5-дюймового дисплея. Как вы можете видеть из этой таблицы, большинство контактов используется самим же дисплеем для реализации в нем функций сенсорного экрана (реагирующего на прикосновения), но, несмотря на это, свободными остаются контакты 3, 5, 7, 8, 10, 11, 12, 13, 15, 16 и 24, которые мы можем использовать для подключения зуммера (buzzer). В нашем случае мы подключили зуммер к контакту GPIO 3.

Назначение контактов (распиновка) 5-дюймового сенсорного дисплея

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

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

Мониторинг нескольких камер на Raspberry Pi с помощью протокола RTSP

Основной задачей при написании этого фрагмента программы является уменьшение нагрузки на Raspberry Pi чтобы предотвратить задержки при трансляции видеопотока (streaming). Изначально автор проекта пытался переключаться между всеми 4 камерами и отслеживать на них движение, но этот процесс происходил с большими задержками (около 10 секунд). Поэтому он объединил видеопотоки со всех 4 камер в одно изображение и производил обнаружение движения на этом объединенном изображении. Для этого он запрограммировал две функции, с названиями create_camera и read_camera.

Функция create_camera используется для открытия камеры с соответствующим номером канала. Заметьте, что в этой функции RTSP URL заканчивается на “02” – это означает что мы использовали трансляцию видео с под-потоков (sub-stream). Видео в этих под-потоках имеет меньшее разрешение чем в основном канале и поэтому быстрее обрабатывается. Также существенное влияние на скорость обработки видео оказывает тип используемого видеокодека. Автор проекта экспериментировал с различными видеокодеками и обнаружил, что наилучшие показатели производительности обеспечивает кодек FFMPEG.

В функции read_camera мы будем считывать видео со всех 4 камер с именами cam1, cam2, cam3 и cam4 и затем объединять их в единое изображение с названием Main_screen. Как только это изображение будет готово, мы можем "запускать" на него OpenCV.

Внешний вид получившегося у нас подобного объединенного изображения показан на следующем рисунке.

Внешний вид объединенного изображения для нашего проекта

Обнаружение движения с помощью OpenCV и Raspberry Pi

Когда наше объединенное изображение будет готово, мы можем начинать на нем обнаружение движения. Внутри цикла while мы начнем считывание двух различных кадров с именами frame1 и frame2, после чего будем конвертировать их в черно-белое изображение с оттенками серого (grayscale).

Затем мы будем анализировать различия (с определенной границей (threshold) между этими двумя изображениями чтобы определить что изменилось. Затем мы будем помечать "пятнами" все места, в которых зафиксированы изменения и растягивать изображение чтобы предотвратить появление острых краев.

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

Функция find_screen() используется для определения того, на какой из 4-х камер зафиксировано движение. Мы можем определить это поскольку знаем координаты x и y, на которых зафиксировано движение. Мы сравниваем эти значения x и y с местоположением экрана каждой из камер (на объединенном изображении) и, таким образом, определяем на каком экране зафиксировано движение. Затем мы вырезаем с объединенного изображения картинку этого экрана и выводим ее на весь экран Raspberry Pi.

Установка срабатывания сигнала тревоги при обнаружении движения

Поскольку теперь мы знаем на каком экране обнаружено движение, мы можем добавить любой тип сигнала тревоги (alarm) какой нам необходим. В этом проекте мы для этой цели использовали зуммер, подключенный к контакту GPIO 3. Мы проверяем с помощью условия if обнаружено ли движение на 3-м экране – если это так, то мы инкрементируем значение переменной trig_alarm. Вы можете изменить срабатывание этого условия на любой экран или даже на несколько экранов.

Если значение переменной trig_alarm станет больше или равно 3, то зуммер сработает один раз (кратковременно). Введение этого условия необходимо для предотвращения ложных срабатываний системы. Если его не вводить, то, к примеру, ложные срабатывания системы могут происходить из-за теней пролетающих птиц. То есть мы подаем сигнал тревоги только тогда, когда движение будет зафиксировано не менее чем в 3-х кадрах.

Мониторинг температуры системы

Поскольку предполагается что наша система обнаружения движения в видеопотоке с камер должна работать в режиме 24x7, то вследствие этого плата Raspberry Pi может достаточно сильно нагреваться. Вследствие этого мы решили выводить на экран дисплея температуру платы и интенсивность использования процессора (CPU) платы. Мы будем получать эту информацию с помощью библиотеки gpiozero.

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

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

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

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

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

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

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

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

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

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