Система распознавания лиц для сельской калитки

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 02:19:42 | Andrey_B
Ruslan, близко к 94-97% и даже выше. Точность распознавания высокая. Но все зависит от качества исходного материала. Если различных фотографий 50 на каждого "своего" человека, то и алгоритм работает хорошо.


2019-04-13 00:53:01 | Ruslan
Спасибо! Очередная полезная статья. Интересно, какой в среднем процент распознавания получается?