Хабрахабр

Дверь, которая с нами здоровается по именам и открывает только сотрудникам отдела

У нас была пара дней промежутка между большими проектами, и мы решили поиздеваться над дверью руководителя подразделения. Just for fun. Потому что дроны нас в лицо уже узнают — чем дверь-то хуже?

За два дня из железа, готовых библиотек и какой-то матери мы сделали прототип устройства, которое учитывает сотрудников или позволяет проверять, что человек прошёл через турникет именно по своему пропуску. На момент старта IT-проекта у нас уже была накладная панель, напечатанная на 3D-принтере.

Мы использовали только опенсорс. Никаких денег.

Вы можете повторить это минут за 15–20 с нашим скриптом.

Идея и подход к реализации

Началось всё с дачи, где мы отдыхали после сдачи одного крупного проекта. Был такой момент, когда было очень сложно попадать ключом в калитку. В смысле, что мы сразу подумали о том, что зимой плохо доставать руки из карманов, ну и придумали ещё кучу применений вплоть до проверки пропусков и личностей сотрудников.

И вообще захотелось эффекта взаимодействия с системой, чтобы она ещё и отвечала голосом. Вообще-то мы хотели сделать коридор с лазерными лучами, как в фильме Resident Evil, но не успели.

Получилось страшно, зато быстро и работает. Поскольку мы хотели прототип, то здесь максимальная ориентация на функциональность и быстрый результат в ущерб внешнему виду, габаритам и красивой архитектуре.

Модуль распознавания в первый день был внешним из веб-сервиса партнёра, ещё был наш старый внутренний нейросетевой движок из другого проекта, плюс были опенсорсные решения. Сначала мы разбили управление дверью на модули и каждый начал писать свой. В итоге выиграл опенсорс: наш собственный движок требовал рефакторинга и обновления (это долго), партнёрский веб-ресурс хотел денег и не пускал внутрь, ну а опенсорс — это опенсорс.

Электроника и корпус

Первоначально рассматривали вариант просто купить замок с электронным управлением и заменить им стандартный внутренний замок двери. Но из-за наличия в двери стекла с жалюзи внутренний замок был нестандартно узким и на рынке просто не оказалось электронной замены. Поэтому наш инженер напечатал съёмный накладной замок, предусмотрев в нём ёмкости для блока управления и блока открывания замка.

Итак, проект корпуса:

Печатали мы его с модели, которую сами сделали до проекта (моделирование и подгонка заняли времени больше, чем написание кода):

Проект корпуса сделан в Компас-3D. В итоге Дима изготовил 3 версии корпуса, покуда смог подобрать оптимальное расположение элементов и крепежей.

Этот же контроллер проворачивал шестерёнки ключа. Внутри корпуса замка к вставленному ключику на шестерёнках поставили мотор MG-995 с усилием 10 кг (реальная сила проворачивания — 5–7 кг), пару инфракрасных датчиков, чтобы управлять автоматикой при входе и выходе, Esp8266-микроконтроллер с Wi-Fi-модулем и веб-сервером, который для простоты принимал по http управляющие команды на открытие и закрытие двери.

Программная часть микроконтроллера написана на языке C.

Погружаясь в детали изготовления корпуса и начинки, невольно задумались над сложностью, казалось бы, простых предметов.

Итого: блок управления замком может принимать команды на открытие по Wi-Fi.

Часть по распознаванию лиц

Нужен блок распознавания лиц, который будет отправлять замку команду «открывай», если надо будет открывать. Из-за модульной архитектуры он может работать на мини-сервере в умном доме или быть веб-сервисом в интернете. Нужна ещё точка c Wi-Fi в локальной сети с блоком управления замка: это либо тонкий клиент, либо домашний сервер. Мы развернули сервер прямо на старом ноутбуке, то есть совместили сервер и тонкий клиент. В ноут по USB воткнули камеру.
Для самого распознавания остановились на Python-библиотеке face recognition по открытой лицензии Массачусетского Технологического Университета.

По идее, чем больше фоток вы загрузите в модель, тем выше будет её точность, но в большинстве случаев хватает аватарки с Facebook или картинки из базы данных эйчаров. В модель загрузили несколько фотографий каждого участника проекта — в фас, в профиль и на природе.

Деплой новой виртуальной машины со всеми сервисами занял 20 минут. Развернули инфраструктуру как сервис в своём облаке Техносерв Cloud и быстро отладились. Потом залили весь код с библиотеками на рабочий ноут для автономной работы.

Система выбирает самое большое лицо в кадре и распознаёт его 2 раза с частотой 0,5 секунды.

Какая уж была, но её вполне хватило. Пошла в ход web-камера из коробки забытых вещей из 90-х.

Это потому, что ноут реально старый и видеокарты у него нет. Общее время распознавания — чуть больше трёх секунд. С видюхой и быстрой web-камерой скорость распознавания увеличится в разы.

Сразу написали коннектор для распознавания голоса, поскольку только по лицу достаточно ненадёжно (об этом далее), обязательно нужно два фактора.

Ушло 6 часов на более-менее отлаженный прототип после выбора библиотеки.

Сам ноут спрятали в шкаф с благодарственными письмами, типа embedded device. Ещё мы подключили bluetooth-динамик к ноутбуку, чтобы он мог разговаривать.

Тесты

В описании к библиотеке написано: «Built using dlib’s state-of-the-art face recognition built with deep learning. The model has an accuracy of 99.38% on the Labeled Faces in the Wild benchmark». Естественно, там не 99,38%, а куда меньше. Потому что надо грузить нормальные фотографии (и побольше), ставить нормальную камеру и выравнивать свет. Но поскольку, пока вы пыритесь на дверь, она успевает сделать 4-5 кадров, открывается она обычно почти сразу.

Чужие люди из других отделов в дверь зайти не смогли. Ошибки: пару раз дверь путалась и не пускала нас сразу.

Корчить рожи двери можно, она всё понимает и открывается.

Мы дописали модуль распознавания целого человека в следующей версии (за пределами этих пары дней), и она стала открывать только бюсту. По фотографии сотрудника, конечно, открывает.

Потом докрутили проверку на цветность (библиотека даунсемплит и берёт чёрно-белые изображения в процессинг), мимические движения и моргание — нужна камера получше, чтобы видеть человека, когда он ещё подходит, и всё будет.

Но для некритичных дверей подходит. То есть как замена ключа, конечно, нет, потому что нужен второй фактор — например, голос. Для проверки, соответствует ли сотрудник пропуску на проходной, тоже. Для учёта прошедших мимо двери сотрудников тоже. Если вы вспомните историю распознавания образов, то одно из первых промышленных применений было в том, что американского разработчика достал соседский кот, гадящий на газон. Ещё дверью можно распознавать вернувшуюся домой собаку. Через пару дней кот понял, что лучше не гадить. Он сделал распознавание кота в полуприседе и подключил систему полива к своему мини-серверу. Нигде. Никогда.

Корпус получился футуристичным и громоздким, в коммерческом варианте на двери вообще ничего не должно быть, кроме камеры с микрофоном и небольшого экрана с визуальным и аудиопомощником.

Повторить дома

Ссылка на библиотеку выше.

Делай два

#/usr/bin/env python """
Скрипт распознавания людей и отмыкания замка: """ import os
import face_recognition
import cv2
import random
from pygame import mixer
import requests
import datetime
import time known_faces = [ ‘Emp1’ , ‘Emp2’ , ‘Emp3’
] faces_folder = 'faces' welcome_folder = 'welcome' known_faces_encodings = [face_recognition.face_encodings(face_recognition.load_image_file(os.path.join(faces_folder, i +".jpg")))[0] for i in known_faces] def init_recognition(): pass def face_detection(face_encodings): name = "Unknown" for face_encoding in face_encodings: matches = face_recognition.compare_faces(known_faces_encodings, face_encoding) if True in matches: first_match_index = matches.index(True) name = known_faces[first_match_index] return name def unlock(): unlock_url = 'http://192.168.4.1/yes' unlock_req = requests.get(unlock_url) #return unlock_req.status_code def lock(): lock_url = 'http://192.168.4.1/no' lock_req = requests.get(lock_url) #return lock_req.status_code def welcome(type): messages = mixer.init() mixer.music.load(random.choice(messages[type])) mixer.music.play() def main(): current = datetime.datetime.now() vc = cv2.VideoCapture(0) if vc.isOpened(): is_capturing = vc.read()[0] else: is_capturing = False user_counter = 0 while is_capturing: is_capturing, frame = vc.read() small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) rgb_small_frame = small_frame[:, :, ::-1] face_locations = face_recognition.face_locations(rgb_small_frame) face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations) if len(face_encodings) > 0: user_counter += 1 if user_counter > 6: welcome('hello') print('hello') time.sleep(2) user = face_detection(face_encodings) timing = datetime.datetime.now() - current if timing.seconds > 4: if user in [‘Emp3’]: welcome('unwelcome') print('go home, ' + user) lock() elif user in known_faces: welcome('welcome') print('welcome, ' + user) unlock() else: welcome('whoareyou') print('who is there?') current = datetime.datetime.now() user_counter = 0 time.sleep(0.5) if __name__ == '__main__': main()

В самом скрипте у нас имена сотрудников (Emp1, Emp2) соответствуют файлам с их фото в каталоге, вам нужно добавить свои. Разрешение неважно, можно хоть 640х480. Есть две категории сотрудников — целевые, кого пропустить, и те, кого сразу отправить домой.

Вместо ноута вполне можно использовать микроконтроллер, но нужно разбираться, как на него поставить питон и выбранные библиотеки. В качестве камеры мы использовали самую простую web-камеру logitech.

Результат

Технологию пощупали продавцы соседних департаментов, работающие с нами на одном этаже. Особенно круто выглядит накладной корпус замка, а с каким звуком он открывает дверь! Не поверите, но внутренняя популяризация технологий также необходима, как и внешняя.

Нас пару раз спросили, зачем мы это сделали в нерабочее время.

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

Мы обычно делаем быстрые (2-3 недели) пилотные проекты для производств. Ну и мы убедились, как быстро можно делать промышленные прототипы. Пишите на tmishin@technoserv.com, если что.  Кстати, если интересно что-то быстро рассчитать в плане автоматизации и сделать пилот — это как раз специализация нашей команды.

Ощущения как после хорошего хакатона.

И теперь у нас есть игрушка.

Кажется, у нас есть пара идей… Вчера прибежал коллега и показал видео дрона с огнемётом.

Для контроля размера фракции материала на ленте конвейера, для остановки в случае попадания посторонних предметов, для отключения при рабочем в опасной зоне и так далее. Я всё это рассказывал ещё и к тому, что буквально 3-4 года назад было очень дорого и долго писать промышленные детекторы для видеонаблюдения. И куда дешевле. Сегодня это делается очень-очень быстро. Не настолько быстро, как в случае с дверью, но пилот за 2 недели — это очень реалистичная оценка.

Показать больше

Похожие публикации

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

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

Кнопка «Наверх»