«Сезам откройся» Или Intel RealSense и ResNet на страже фруктов
Не секрет, что в современном высокотехнологичном мире от нас требуется постоянно подтверждать свою личность и права доступа — паролями, бесконтактными метками, отпечатками пальцев и так далее. Можно это делать и с помощью визуального отпечатка — лица пользователя. Достаточно посмотреть на наш гаджет, как он понимает — что перед ним авторизованный пользователь, и снимает блокировку экрана.
Мы решили реализовать подобную схему с помощью подручных материалов и open source решений. В качестве физического объекта, который будет обладать соответствующей «избирательностью к открытиям», был выбран сейф.
Все подробности под катом.
Рисунок 1. Процесс сборки корпуса
Корпус изготовлен из обрезков ламинированных МДФ панелей 40×40 см, соединенных мебельными шурупами. Впоследствии все стыки были густо промазаны акриловой шпатлевкой по дереву, не очень тщательно зашкурены, после чего весь корпус несколько раз покрывался акриловой белой краской толстым слоем. Красим, ждем пока высохнет текущий слой, зашкуриваем, покрываем очередным слоем. После трех слоев получилось равномерное белое матовое покрытие, по которому я прошелся тонким слоем белой глянцевой эмали.
Рисунок 2. Итоговый корпус во время монтажа электрики
Снизу корпуса прикручиваем напечатанные ножки — первые детали, нарисованные в 3D-редакторе.
Рисунок 3. Ножки. Пластик PLA
Замок для сейфа был сделан из гибрида привода центрального замка и фалевого язычка межкомнатной двери — из последнего выкидываем поворотную гильзу и делаем зацеп под тягу.
С помощью напечатанных деталей все собирается в единую конструкцию и крепится на двери. Основная пластина сама по себе довольно тонкая (3 мм) и легко гнется, но все меняется после установки на место. Итоговая конструкция получилась достаточно прочная для дальнейших экспериментов.
Рисунок 4. Механизм замка в сборе
Конечно если мы говорим о полноценной системе контроля доступа, то можно купить и цельнометаллический готовый электрический замок, установив его в нормальный металлический сейф. Но нет.
Помимо замка нам еще нужен концевик, дабы контролировать состояние двери, трехпозиционный переключатель, чтобы управлять системой, и двухцветный светодиод, для отображения текущих состояний программы.
Рисунок 5. Принципиальная схема обвеса
Не забываем, что напряжение на пинах 1,8В (с платой расширения уже 3,3В), поэтому светодиоды подключаем через транзисторный каскад — от 1,8В они просто не зажгутся.
Основные компоненты системы — камера и одноплатный компьютер были созданы друг для друга (в нашем случае это не оборот речи, а известный факт):
Рисунок 6. Intel Joule 570x Development Kit — одноплатный микрокомпьютер с 4-х ядерным 64-разрядным Intel Atom на борту, 4GB памяти и разъемом USB 3.0
Рисунок 7. Intel RealSense Camera SR300 — 3D-камера ближнего радиуса действия в качестве органа зрения. Эффективная дальность распознавания глубины 0,2 — 1,2 м.
Буквально спустя пару дней после старта проекта, Intel Joule успел обзавестись статусом EOL (End Of Life), но нас это не остановило.
В качестве вычислительного модуля можно взять практически любой современный одноплатник с USB3.0 на базе процессора Intel. Например Up Squared Grove IoT Developement Kit или MinnowBoard Turbot*. Intel NUC тоже подойдет.
Устанавливаем детали замка на ящик так, чтобы замок нормально закрывался. Чтобы дверка отскакивала при срабатывании (как в постаматах), распечатаем и установим пружинный толкатель. Его задача — после втягивания язычка увести дверь от защелки на несколько милиметров, дабы после снятия напряжения ящик не закрылся вновь.
Рисунок 8. Защелка для язычка и пружинный толкатель двери
Спереди монтируем камеру. В крышку для камеры, в точку над i вклеиваем светодиод — в силу определенных причин он успел метаморфировать в один зеленый светодиод. Закрепляем ее с помощью пары шурупов.
Рисунок 9. Установленная камера
Для Intel Joule нужен корпус, поэтому в 3D-редакторе рисуется кейс необходимых размеров с окнами под разъемы.
Рисунок 10. Чертеж корпуса для Intel Joule
Для 40-пиновых GPIO-разъемов никаких окон не предусматривается, поскольку принято решение разместить всю электрику внутри корпуса. Для этого рисуется толстая крышка, с пазами под реле и 4 контакта, а также окнами под переключатели. Не забываем что процессор на плате не самый слабый, так что в крышке делаем несколько вентиляционных отверстий.
Рисунок 11. Чертеж крышки
Тут два косяка. Во-первых, при разработке обвеса не был учтен разъем подключения светодиода, что привело к тому что:
- В корпусе не предусмотрено отверстие под шлейф/разъем и пришлось прожигать отверстие паяльником;
- Собранный корпус имеет длинный хвост со светодиодами на конце.
Во-вторых, корпус надо как-то соединять и ничего лучшего чем делать это с помощью кусков проволоки в итоге придумано не было ¯_(ツ)_/¯. Про навесной монтаж вообще молчу. Вам не видно, а где-то там, под термосоплями, скрыто 3 транзистора и пяток резюков.
Тут я вспоминаю картинку собственного авторства:
И слова человека, который принес мне правый девайс — «мне уже сделали прототип, надо только прошивку немного подправить — что-то работает нестабильно и батарейка быстро садится».
Рисунок 12. Собранный блок электроники
Внутренности коробки — четыре клеммы — два для питания и два для мотора, концевик для двери, туда-сюдашечка для управления программой, и реле, подающее напряжение на замок. Во время печати угол возле полости для реле оторвало от стола и реле решило не помещаться в ней. Пришлось клеить переключатель на термосопли. Равно как и одноплатник.
Зеленой изолентой приклеены Wi-Fi антенны платы. Вообще они на самоклейке, но мы их уже столько раз клеили отдирали за время экспериментов, что свойство липнуть к поверхности они потеряли.
Рисунок 13. Собранный блок электроники в закрытом виде
Помещаем кишки внутрь корпуса, закрываем и приступаем к разработке программной части.
Лирическое отступление по 3D-печати.
Детали замка — любимым многим и ненавистный мне PLA. Материал очень хороший для печати высокоточных моделей, но его совершенно невозможно обрабатывать. А еще эта зараза плывет при нагреве, что является Очень плохим свойством для конструкционных элементов.
Все остальные детали HIPS — ИМХО он менее капризный чем ABS, и при печати практически не дает запаха. Единственный нюанс — пока не поднял температуру стола до 95 градусов, деталь на столе коробило. По инструкции температура стола должна быть около 100 градусов, но кто ж ее читает пока все хорошо?
Подготовка системы
В первую очередь необходимо обновить BIOS на плате, чтобы установить необходимый нам образ операционной системы. Мы использовали Эту и Эту инструкции из официальной документации на сайте Intel.
Далее, подключив к плате монитор и клавиатуру, устанавливаем специальный дистрибутив Ubuntu* Desktop 16.04 LTS для Intel Joule в привычном графическом или текстовом режиме. Если в качестве компьютера используется Intel NUC или другой компьютер — пойдет и стоковый образ системы.
После установки ОС штатными средствами подключаемся к интернету через встроенный Wi-Fi. Так как на плате разъем USB всего один и он нам нужен для подключения камеры, подключаемся к плате по ssh. Теперь можем освободить порт от клавиатуры и подключить Intel RealSense.
Установка пакетов и зависимостей.
Сперва установим Python 3.5.4, на котором написан наш проект. Скачаем и построим из исходного кода Python-модуль OpenCV, так как неофициальный модуль OpenCV для Python на Intel Joule работает некорректно.
Установим или обновим дополнительные зависимости:
apt install -y --fix-missing build-essential cmake gfortran git wget curl graphicsmagick libgraphicsmagick1-dev libatlas-dev libavcodec-dev libavformat-dev libboost-all-dev libgtk2.0-dev libjpeg-dev liblapack-dev libswscale-dev pkg-config python3-dev python3-numpy software-properties-common zip
git clone https://github.com/davisking/dlib.git /root/dlib; cd /root/dlib; mkdir build; cd build; cmake .. -DUSE_AVX_INSTRUCTIONS=1; cmake --build . ; cd .. ; python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA
pip3 install face_recognition
Ставим libmraa — эта библиотека нам пригодится для общения с ящиком. Подробная иструкция по сборке находится здесь.
Либо можно установить готовые бинарники из PPA:
sudo add-apt-repository ppa:mraa/mraa
sudo apt-get update
sudo apt-get install libmraa1 libmraa-dev libmraa-java python-mraa python3-mraa node-mraa mraa-tools
После установки всех зависимостей можем проверить, что все работает корректно. Для этого Поднимаем VNC — vnc4server наше все, запускаем сэмпл по работе с камерой и убеждаемся, что камера работает.
Последней точкой проверки является корректный импорт модуля face_recognition. По сути это и есть наша нейросетка ResNet, заточенная на идентификацию людей на фото. Так это выглядит в демо автора:
import face_recognition
Как все будет готово, выгружаем исходный код нашего приложения из репозитория и приступаем к работе.
Для удобства мы добавили все библиотеки как подмодули в наш проект. Чтобы их скачать, выполните git submodule update --init --recursive из директории с проектом.
./launcher.py
При первом включении в базе нет лиц, следовательно ящик будет закрыт. Открываем его вручную (у нас для этого есть встроенный бэкдор — маленькая дырочка четко напротив язычка) и производим обучение.
Для этого встаем перед ящиком — на лицевой панели загорается светодиод, показывающий что некое лицо находится в поле зрения камеры.
Щелкаем переключателем в сторону запоминания лица и в консоли появляется соответствующая запись.
Теперь, если закрыть ящик и встать перед ним — система узнает его лицо и радостно откроет дверь.
В консоли будут появляться записи о предоставлении доступа.
Если встанет незнакомый человек — система его опознать не сможет, в результате чего дверь останется закрытой. Другое дело, что систему можно взять измором — процент ложноположительных срабатываний в нашем случае был довольно высок и если долго ходить с кучей разных предметов в руках — сезам таки откроется.
Это можно решить использованием канала глубины — в текущей версии он не используется, так как заставить его стабильно работать так и не удалось, а проблему совместимости с Intel Joule слать было поздно. У автора face_recognition измеренная точность составиля 99,38% на бенчмарке Labeled Faces in the Wild Home
Разумеется этот Proof-Of-Concept может быть существенно улучшен, а его функционал многократно расширен. Например можно добавить логгирование успешного и неуспешного доступа, а также удобное управление через web-интерфейс.
Основной принцип конструирования данного девайса был: «Я его слепила из того что было». Мы лишь хотели показать, что из подручных материалов вполне можно слепить что-то интересное.
Спасибо Дмитрию (dmitryvodop) и Сергею за работу над программной частью проекта.
Все модели в формате *.stl и исходный код программы выложен на GitHub под лицензией MIT.