Последние статьи
- Твердотельный датчик направления и скорости ветра. Эксперимент
- iPhone на стене в качестве панели управления домом
- MegaD-16M-XT - подсветка выключателей и не только
- Переделка выключателей в кнопки и мини-обзор текущего рынка
- RadSens - модульный счетчик Гейгера с интерфейсом I2C
- "U" - значит универсальный. Обзор модуля MegaD-16U-XT
- SCD4x - современная альтернатива для измерения концентрации CO2
- HTU31D - новый датчик температуры и влажности с нагревательным элементом
- Измерение коэффициента пульсации ламп с помощью MegaD-2561
- Использование солнечных панелей в качестве датчика освещенности
- Согласование датчиков с выходом типа TTL со стандартными входами контроллера
- DPS368 - датчик атмосферного давления индустриального класса повышенной точности
- DS18B20 Waterpoof - импортзамещение
- TMP117 - высокоточный датчик температуры с интерфейсом I2C
- MegaD-16R-XT - расширитель на 16 релейных выходов
- MegaD-2561-RTC V3 - больше портов, зуммер и ИОН
Система распознавания лиц для сельской калитки
12/04/2019 20:57:28
После того, как была успешно собрана вторая версия колхозного SIP-домофона на основе Raspberry Pi, я решил вернуться к идее распознавания лиц для доступа на территорию участка. Почти 10 лет назад такая попытка уже предпринималась, но тогда в практическом плане остановило слишком высокое время распознавания. С тех пор и аппаратные и программные возможности для реализации подобной идеи ушли вперед. SIP-домофону 2.0 требовалась система распознавания лиц нового поколения.
Так работает система распознавания T800 CSM101
Идея заключалась в следующем. У вызывной панели моего гиковского SIP-домофона есть считыватель, кнопка и камера. Пользователь может открыть калитку с помощью брелка/карты системы Mifare или позвонить в дом, нажав на кнопку. Но что, если пользователь забыл ключ или ему просто лень его доставать? Было бы неплохо сделать так, чтобы при нажатии и удержании кнопки в течение секунды происходило фотографирование субъекта, распознавание его лица и отпирание калитки в том случае, если субъект будет признан своим. Звучит вроде несложно. Даже Сбербанк смог...
Работу с кнопкой я описывал в статье про домофон. В контексте данного материала останавливаться на этом нет смысла. Это простой скрипт на PHP, считывающий в цикле состояние GPIO. Пришлось только добавить обработку удержания. Логика простая. Сразу же в момент нажатия на кнопку камера делает фотографию. Неважно - для распознавания или для архива. Если кнопка отпущена ранее, чем через секунду, осуществляется SIP-звонок. Если кнопка удерживается в течение секунды происходит распознавание фотографии и принимается решение об открытии замка.
В статье про SIP-домофон я писал, что для доступа к камере (фото, видео) использую программное обеспечение RPi-Cam-Web-Interface. Но в процессе эксплуатации выяснился одна ужасно смешная вещь. Если это ПО запущено постоянно, а значит беспрерывно считываются данные с 8-мегапиксельной камеры, основной процессор "малинки" нагружается. Это приводит к его нагреву. Тепло передается металлической кнопке, которая находится прямо над чипом, но его при этом не касаясь. В итоге кнопка в теплый день разогревается градусов до 40-45! Зимой, разумеется, это не имело значения. Но как только потеплело, стало понятно, что нажимать на горячую кнопку как-то не совсем... привычно что ли. Тогда я решил, что следует включать камеру только по необходимости. Кнопка сразу простыла.
Улыбочку
Для одиночного снимка по нажатию кнопки на домофоне я буду использовать программу raspistill. Это намного проще, чем искать, как запустить RPi-Cam-Web-Interface внешним запросом (я, кстати, штатного средства не нашел, API отсутствует или не описано). К тому же у raspistill есть масса параметров, которые в данной ситуации могут пригодится.
Казалось бы, нет ничего проще, чем в нужный момент времени запустить программу так:
raspistill -o cam.jpg
Но, как это всегда случается, есть масса особенностей. Во-первых, мы получим снимок с диким разрешением в 8Мп, который будет занимать на флешка 4,5Мб - для распознавания лиц явно избыточно. Во-вторых, если писать по-многу раз в день на флешку такие файлы, это может снизить ее ресурс. В-третьих, и это главное, запись фотографии занимает ПЯТЬ секунд.
Но все поправимо и делать снимок нужно примерно так:
raspistill -o /dev/shm/cam.jpg -q 70 -w 640 -h 480 -t 500
- Изображение сохраняется не на флешку, а в память "/dev/shm" для последующей обработки или передачи на сервер
- Разрешение снимка 640х480, а качество 70, чего достаточно для архива и функционирования системы распознавания лиц
- Время, которое занимает процесс фотографирования снижено до 0,5 с - опция -t 500
Дело в том, что после включения, камере нужно время, чтобы корректно установить такие параметры как выдержка, баланс белого и т.д. Исходя из моих тестов 500 мс - минимальное значение, при котором получаются более-менее сносные фотографии. По умолчанию для автонастройки установлено время 5 секунд.
Я также решил, что распознавание лиц и хранение архива будет осуществляться на сервере. Но хочу сразу подчеркнуть, что нет никаких проблем делать все необходимые процедуры тут же, на уровне вызывной панели домофона. У RPi для этого достаточно ресурсов и производительности!
Для передачи файла на сервер я буду использовать программу scp. Ну, конечно же, шифрованный SSH внутри шифрованного WiFi - это то, что надо для таких систем. Да нет, просто это самый простой для реализации и надежный механизм. К тому же работает он довольно быстро.
scp /dev/shm/cam.jpg media@192.168.0.251:/home/media/images
А чтобы scp не спрашивал пароль, я сгенерировал на RPi ключи и скопировал публичный ключ на сервер.
Установка OpenCV 3
Для распознавания лиц я решил использовать уже настроенный и работающий набор скриптов, написанных на python, от Adrian Rosebrock. Полное описание и исходники в его статье "OpenCV Face Recognition" от 24 сентября 2018 года с забавными гифками. Но об этом чуть ниже. Чтобы скрипты Adrian'а работали, необходимо установить OpenCV версии не ниже 3.3. В репозитарии Debian, конечно же, лежит версия 40 летней давности. Нужно установить библиотеку OpenCV последней версии вручную.
# Устанавливаем пакеты, которые необходимы для компиляции и работы OpenCV apt-get install build-essential cmake pkg-config libjpeg-dev libatlas-base-dev python2.7-dev python-pip # Скачиваем исходники OpenCV 3.4 wget https://github.com/opencv/opencv/archive/3.4.zip # И так понятно... unzip 3.4.zip cd opencv-3.4; mkdir build; cd build # Компилируем OpenCV cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local .. make -j4 # Устанавливаем OpenCV make install; ldconfig
Распознавание лиц
Итак, для распознавания лиц я выбрал набор скриптов на python с сайта pyimagesearch.com.
Если вы не готовы оставлять на этом сайте свой емейл, автоматически подписываясь на спам, скачать архив можно здесь.
А вот краткое изложение той статьи, в которой много букав.
# Устанавливаем некоторые необходимые библиотеки pip install -U imutils pip install -U scikit-learn # Распаковываем архив unzip opencv-face-recognition.zip # Закидываем в папку dataset фотографии нужных лиц cd dataset; mkdir andrey Далее копируем в папку andrey заранее собранные фотографии Количество наборов данных (папок с лицами людей) должно быть 2 или более! # Запускаем обработку фотографии (извлечение лиц) python extract_embeddings.py --dataset dataset --embeddings output/embeddings.pickle --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 # Запускаем обучение модели распознавания лиц python train_model.py --embeddings output/embeddings.pickle --recognizer output/recognizer.pickle --le output/le.pickle
Все, теперь у нас есть готовое решение для распознавания лиц. Пользоваться так.
Через параметр "--image" передается путь к файлу, который нужно распознать.
python recognize.py --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 --recognizer output/recognizer.pickle --le output/le.pickle --image images/cam.jpg [INFO] loading face detector... [INFO] loading face recognizer... andrey: 95.93%
Время распознавания около 0,5 секунды. Работает!
Поскольку камера ранее фотографировала людей, я использовал уже существующий архив, отобрав для обучения системы более-менее приличные фотографии и отсортировав их по папкам.
В принципе для начала нормальной работы системы распознавания достаточно уже 15-20 фотографий на одного персонажа. Но чем больше будет фотографий в разное время суток, в разное время года, с разной одеждой и т.д., тем более точным и предсказуемым будет результат и тем меньше будет процент ошибок. Сказать, что система работает на 200%, конечно, нельзя. В очень редких случаях система неожиданно выдает противоречивый результат типа "putin: 45.48%" (да, я закинул в датасет фоточек вождя на всякий случай; "как сказал классик: вам везде!") или "unknown". Но корректность выдачи во-многом зависит от качества набора данных и от внешний объективных обстоятельств, как-то: смазанное изображение из-за движений человека, слишком сильная контрзасветка, темные очки на глазах или чулок на голове. В любом случае - это большой шаг вперед. И для отпирания сельской калитки применять вполне можно.
Автор: Andrey_B
Любое использование материалов сайта возможно только с разрешения автора и с обязательным указанием источника.
Добавить комментарий:
Сортировка комментариев: Последние сверху | Первые сверху
2019-04-13 00:53:01 | Ruslan
Спасибо! Очередная полезная статья. Интересно, какой в среднем процент распознавания получается?
2019-04-13 02:19:42 | Andrey_B
Ruslan, близко к 94-97% и даже выше. Точность распознавания высокая. Но все зависит от качества исходного материала. Если различных фотографий 50 на каждого "своего" человека, то и алгоритм работает хорошо.
2019-07-17 06:44:44 | Дмитрий
Отличный набор. Сейчас пытаюсь сделать аналогичное без использования python. На базе китайского набора скриптом на php https:/github.com/hihozhou/php-opencv
2019-12-22 22:34:11 | Denis
Спасибо!