Детектор движения на Raspberry Pi
На основе одноплатного микрокомпьютера можно собрать 3D-принтер, построить медиацентр и даже разработать настольную игру. Такие компьютеры можно применить и для построения систем безопасности, в частности, систем видеонаблюдения. Пользуясь возможностями микрокомпьютера Raspberry Pi и алгоритмами машинного зрения, разработаем простой детектор движения.
Для построения детектора движения будем использовать микрокомпьютер Raspberry Pi 3 Model B, оснащенный четырехъядерным процессором ARMv7 и оперативной памятью объемом 1 Гбайт. Ещё нам потребуется карта памяти MicroSD, блок питания с разъемом MicroUSB и веб-камера. Будем считать, что на компьютер уже установлена операционная система Raspberry Pi OS и настроено подключение к Интернет.
Перед написанием скрипта необходимо пройти несколько подготовительных шагов.
Обновляем программные пакеты и устанавливаем библиотеку opencv.
Переходим в домашний каталог, создаем папку проекта motion_detector, переходим в эту папку, в ней создаем папку images для сохранения кадров с обнаруженным движением.
Создаем пустой файл скрипта simple_detector.py и задаем права на его запуск.
Далее переходим к разработке скрипта для обнаружения движения.
Сначала задаем путь к интерпретатору Python и импортируем необходимые библиотеки.
Создаем экземпляр класса для отсечения фона.
Инициируем видеозахват с камеры и устанавливаем разрешение кадра.
Захват и обработку изображений будем выполнять в бесконечном цикле. Каждая итерация цикла начинается с захвата изображения с камеры.
Изображение frame — тензор размерности 720x1280x3.
Далее отсекаем фон.
Результатом этой операции является изображение с тремя градациями яркости, где черной области соответствует фон, белой — движущиеся объекты, а серой — тени.
Преобразуем это изображение в черно-белое таким образом, чтобы тени также были отнесены к движущимся объектам.
На изображении могут быть артефакты в виде мелких точек, вызванные изменениями освещенности, атмосферными осадками, отражениями разных источников света. Для исключения таких артефактов применим к изображению операцию размыкания (opening) с квадратным ядром 5×5. В результате изображение будет очищено от мелких артефактов.
Также применяем операцию замыкания (closing) с квадратным ядром 9×9. Операция замыкания позволяет объединить близко расположенные области белого цвета.
Результат двух последних действий приведен ниже.
Далее выполняем поиск контуров.
Поскольку часть контуров имеет очень малый размер, будем считать, что это также артефакты. Выполняем отбор найденных контуров по критерию минимальной площади. В качестве порога используем значение 100, что эквивалентно квадратному контуру размером 10×10 пикселей.
После этой операции контуры малой площади исключаются из процесса обработки.
Оцениваем отношение суммарной площади контуров к площади всего кадра.
В случае, если относительная площадь областей белого цвета превысит некоторое пороговое значение, будем считать, что в кадре есть движение. Для таких кадров обводим контуры прямоугольниками, добавляем текущую дату и время, а также сохраняем полученное изображение в папку images.
В результате получаем набор исходных кадров с обозначенными областями движения и метками времени.
На этом разработку простого детектора движения можно считать завершенной. По результатам опытной эксплуатации установлены следующие факты:
- быстродействие детектора составляет около 1,5 кадров в секунду;
- за одни сутки накапливается около 5 тысяч изображений объемом до 700 Мбайт, таким образом, карта памяти объемом 32 Гбайта позволит хранить кадры с признаками движения приблизительно за один месяц работы системы.
Пример работы детектора приведен на видеозаписи. Cкрипт детектора выложен в репозитории github.com/mporuchikov/motion_detector.
Прикольная идея.
Было бы интересно узнать какой объём ресурсов raspbery остаются доступными, чтоб прикрутить функционал.
Шестичасовой эксперимент показал, что при работе скрипта средняя загрузка процессора на Raspberry Pi 3 Model B составляет около 44%. Таким образом, более половины ресурсов процессора остаются свободными.
Благодарю!