12 ноября 2018
Кейсы

Как мы используем распознавание лиц для поиска тестовых телефонов

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

Мобильное приложение

Мы решили автоматизировать задачу поиска нужного устройства. Первым шагом стало написание мобильного приложения, которое умеет определять и сообщать о своем местоположении в комнатах по Wi-Fi точкам доступа. А также научили смартфоны сообщать на сервер о версии ОС и показывать заряд батареи. 

Мы установили приложение на тестовые устройства и поработали с ним несколько месяцев. Оказалось, что такой вариант удобен, но не идеален. Устройства разряжаются, просто выключаются, точки доступа Wi-Fi переставляются из одного места в другое, а геолокация сама по себе говорит только о том, что устройство находится в офисе.

Как мы хотели, чтобы это было

Мы придумали концепт системы, которая бы распознавала сотрудников по лицам, тестовые устройства — по специальным меткам, запрашивала бы подтверждение смены статуса устройства, а потом вносила изменения в онлайн-базу, которую любой сотрудник может посмотреть, не вставая с кресла.

Распознавание лиц

Распознавание лиц в целом решенная задача в 2018 году. Поэтому мы не стали изобретать велосипед и пытаться обучать собственные модели, а воспользовались готовым решением. Самым удобным вариантом показался модуль FaceRecognition, т.к. он не требует дообучения и работает весьма быстро даже без ускорения на GPU.

С помощью функции face_locations на фотографиях сотрудников обнаруживались лица, а с помощью face_encodings из них извлекались признаки лица конкретного сотрудника.

Полученные данные собирались в базу. Для определения конкретного сотрудника с помощью функции face_distance считалась «разница» между кодировкой обнаруженного сотрудника и кодировками из базы. 

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

Дело в шляпе?

Казалось бы, мы научились распознавать устройства и лица, работа сделана. Что ещё может быть нужно?

На самом деле, работа только начинается. Теперь все компоненты системы нужно заставить стабильно и быстро работать «на бою». Нужно оптимизировать затраты ресурсов сервера в idle’е, продумать юзкейсы и понять, как это вообще должно выглядеть графически.

Интерфейс

Едва ли не самым важным пунктом в разработке подобных систем является интерфейс. Кто-то возможно будет спорить, но пользователь — центральный элемент в такой ситуации. Максимально быстро можно реализовать фронтенд-часть с помощью Tkinter.

Несколько замечаний о Tkinter:

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

.attributes("-fullscreen", True)

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


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

image
 

Вот ключевые компоненты интерфейса:
  • Устройство
    На экран выводятся карточки устройств с указанием версии операционной системы, названия и ID устройства, а также пользователя, на котором это устройство сейчас зарегистрировано.
  • Фотофиксирование
    Справа находится блок управления, где выводится изображение с веб-камеры, а также кнопки для регистрации и редактирования персональной информации.

    Изображение выводим, чтобы дать пользователю обратную связь — ты точно попал в экран меткой устройства.
  • Выбор версии ОС
    Мы сделали список с выбором интересующей версии ОС, т.к. часто для тестирования нужен не конкретный девайс, а определенная версия Android или iOS. Фильтр версий сделан горизонтальным, чтобы сэкономить место и чтобы список версий был доступен без прокрутки, на одном экране.
Оптимизация

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

При этом понятно, что 99 % времени система будет производить эту работу вхолостую. 

Чтобы этого избежать, были приняты следующие оптимизационные решения:
 

  1. В обработку подаётся лишь каждый восьмой кадр. Задержка реакции системы повышается примерно до 8/30 секунды, при этом время реакции человека — примерно одна секунда. Соответственно, такая задержка всё ещё не будет заметной для пользователя. А мы уже в восемь раз снизили нагрузку на систему.
  2. Сначала в кадре ищется маркер устройства, и лишь при его обнаружении запускается распознавание лиц. Так как поиск маркеров в кадре примерно в 300 раз менее затратен, чем поиск лиц, мы решили, что в режиме ожидания будем проверять только наличие маркера.
  3. Чтобы уменьшить «тормоза» при поиске лиц, когда лиц на изображении нет, в функции face_locations был отключен параметр number_of_time_to_upsample.


face_locations = face_recognition.face_locations(rgb_small_frame, number_of_times_to_upsample=0)

Благодаря этому время обработки кадра, на котором нет лиц, сравнялось со временем обработки кадра, где лица легко обнаруживаются.

Что в итоге?

На текущий момент, система успешно развернута на подвернувшемся под руку MacMini Late 2009, на двух ядрах Core 2 Duo. В рамках тестирования, она вполне успешно работала даже на одном виртуальном ядре с 1024 мегабайтами оперативной и 4 гигабайтами постоянной памяти в контейнере Docker. К MacMini подключили сенсорный дисплей, чтобы внешний вид стал минималистичным.

Сейчас даже те пользователи, которые не пользовались старой доской, с энтузиазмом и улыбкой регистрируют на себя устройства, а случаев безуспешных поисков стало намного меньше!

Что дальше?

В текущей системе, несомненно, ещё много моментов, которые можно и хочется улучшить:

Сделать так, чтобы элементы управления ОС не проявлялись при появлении диалоговых окон (сейчас это messagebox из пакета Tkinter).

  • Разнести вычисления и запросы к серверу в разные потоки с обработкой интерфейса (сейчас они выполняются в основном потоке, mainloop Tkinter’а, что замораживает интерфейс в момент отправки запросов в онлайн-базу).
  • Привести интерфейс к одному дизайну с другими корпоративными ресурсами.
  • Сделать полноценный веб-интерфейс для удаленного просмотра данных.
  • Использовать распознавание голоса для подтверждения/отмены действий и заполнения текстовых полей.
  • Реализовать регистрацию нескольких устройств одновременно.

 

Оригинал статьи опубликован на Habr.com