Недавно исследователи из GoogleAI показали свой поход к задаче трекинга руки и определения жестов в реальном времени. Я занимался подобной задачей и потому решил разобраться с тем как они подошли к решению, какие технологии они использовали, и как добились хорошей точности при риал тайм работе на мобильном устройстве. Также запустил модель на android и протестировал в реальных условиях.


Почему это важно?


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

image

В чем сложность?


Естественное восприятие рук в реальном времени является реальным вызовом для компьютерного зрения, руки часто перекрывают себя или друг друга (перекрещивание пальцев или рукопожатие). В то время как лица имеют высококонтрастные узоры, например, в области глаз и рта, отсутствие таких признаков в руках затрудняет надежное обнаружение только по их визуальным признакам. 

Руки постоянно находятся в движении, меняют углы наклона и перекрывают друг друга. Для приемлемого пользовательского опыта нужно чтобы распознавание работало с высоким FPS(25+). К тому же все это должно работать на мобильных устройствах, что добавляет к требованиям по скорости, также ограничения по ресурсам.

Что сделали в GoogleAI?


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

Как они это сделали?


Подход реализован с помощью MediaPipe?-?кроссплатформенный фреймворк с открытым кодом для построения пайплайнов обработки данных (видео, аудио, временные ряды). Что-то наподобие Deepstream от Nvidia, только с кучей фичей и кроссплатформенностью.

Решение состоит из 3 основных моделей работающих вместe:

Детектор ладони (BlazePalm)

  • принимает полное изображение из видео
  • возвращает ориентированный bounding box (ограничивающая рамка)

Модель для определения ключевых точек на руке

  • принимает обрезанную картинку руки
  • возвращает 21 ключевую точку руки в 3D пространстве + показатель уверенности (подробнее далее в статье)

Алгоритм распознавания жестов

  • принимает ключевые точки руки
  • возвращает название жеста который показывает рука

Архитектура похожая на ту, которую используют при задаче pose estimation. Предоставляя точно обрезанное и выровненное изображение руки, значительно уменьшается потребность в аугментации данных (повороты, трансляции и масштабирование) и вместо этого модель может сконцентрироваться на точности предсказания координат.

Детектор ладони


Для нахождения ладони используется модель называемая BlazePalm?-?single shot detector (SSD) модель оптимизированная под работу на мобильном устройстве в реальном времени.

В исследовании GoogleAI натренировали детектор ладони вместо детектора всей руки (palm?-?основа ладони без пальцев). Преимущество такого подхода в том, что распознать ладонь или кулак проще чем всю руку с жестикулирующими пальцами, к тому же ладонь может быть выделена используя квадратные bounding boxes (анкоры) игнорируя соотношения сторон, и таким образом сокращая количество требуемых анкоров в 3–5 раза

Также использовался экстрактор фич Feature Pyramid Networks for Object Detection (FPN) для лучшего понимания контекста изображения даже для небольших объектов

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

 Классическая кросс-энтропия: CE(pt) = -log(pt )
 Фокал лосс: FL(pt) =-(1-pt) log(pt)

Подробнее про Focall loss можно почитать в отличном пейпере от Facebook AI Research (рекомендовано к прочтению)

Используя вышеперечисленные техники было достигнуто средней точности (Average Precision) 95.7%. При использовании простой кросс-энтропии и без FPN?-?86.22%.

Определение ключевых точек


После того как детектор ладони определил на всем изображение позицию ладони, регион сдвигается на определенный коэффициент вверх и расширяется, чтобы охватить всю руку. Дальше на обрезанном изображение решается задача регрессии?-?определяется точное положение 21 точки в 3D пространстве.

Для тренировки было вручную размечено 30 000 реальных изображений. Также была сделана реалистичная 3D модель руки с помощью которой сгенерировали еще искусственных примеров на разных фонах.


Вверху: реальные изображения рук с размеченными ключевыми точками. Внизу: искусственные изображения руки сделанные с помощью 3D модели

Распознавание жестов


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

Оптимизации


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

Для устойчивости такого подхода к модели определения ключевых точек добавили еще один выход?-?скаляр, который показывает насколько модель уверена в том, что на обрезанном изображение присутствует рука и что она правильно развернута. Когда значение уверенности падает ниже определенного порога?-?запускается детектор ладони и применяется ко всему кадру.


Тест в реальных условиях


Я запустил это решение на android девайсе (Xiaomi Redmi Note 5) для теста в реальных условиях. Модель ведет себя хорошо, правильно мапит скелет руки и высчитывает глубину при приличном количестве кадров в секунду.


Из минусов можно отметить то как начинает проседать точность и скорость при постоянном движение руки по фрейму. Это вызвано тем, что модели постоянно приходится перезапускать детектор, так как она теряет положение руки при движении. Если вам больше важна скорость нахождения двигающейся руки чем определение жестов?-?вам стоит поискать другие подходы. 


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

Статья на GoogleAI Blog
Github mediapipe Hand Tracking

Комментарии (11)


  1. Dimtry44
    09.09.2019 18:11

    Уже кто-то сделал приложение для языка жестов глухонемых?


    1. Nazar_kh Автор
      09.09.2019 22:54

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

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

      Но есть еще момент в том, что многие слова на язык жестов — это не просто жесты, а движения (то есть важно видеть последовательность кадров)

      А вот с подходом описанным в статье можно оперировать массивом ключевых точек в 3D пространстве и с предыдущих кадров также, что делает относительно несложным добавление новых жестов и при этом никак не влияя на точность и скорость. Но работ с реализацией пока не находил)


  1. LaG1924
    10.09.2019 08:51

    На мобилках не успевает быстро-движущуюся руку отслеживать. А если попробовать это на десктопе? Насколько мне известно, существующие аналоги либо дорогие, либо имеют малую рабочую зону, либо очень посредственной точности, либо комбинации вышеперечисленного, а тут вроде что-то точное и дешевое (по цене одной вебки, но неуверен насчет стоимости железа для работы нейросети).


    1. allerria
      10.09.2019 10:12

      iphone XR, XS работают с нейросетями достаточно быстро, может быть, на ниъ получится.


    1. vashanin
      10.09.2019 12:56
      +1

      Зависит от выбора архитектуры сеток. Если говорить о CNN архитектурах — eсть тяжелые с большим количеством параметров, такие как VGG-16, AlexNet и т.п. Последние, возможно, будуть давать немного лучшую точность, но в риал-тайме смогут работать только на дорогом железе, и уж явно не на мобильных устройствах. Но в последнее время появились относительно лёгкие архитектуры MobileNet и MobileNetV2, которые используют depthwise convolution блоки — что позволяет в разы сократить количество тренируемых параметров. Такие нейронки могут бежать уже и на мобильных устройствах при достаточно годном значении FPS и достойной точностью. Если говорить о последних версиях iPhone — там вообще можно добиться 30+ FPS (только при этом заряд батареи будет уходить так же стремительно xD). Да и на более-менее новых телефонах средней ценовой категории тоже можно добиться неплохих метрик.


  1. rPman
    10.09.2019 19:03

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


    1. Nazar_kh Автор
      11.09.2019 16:30

      Вот тест на однородном фоне, так что проблема все же в производительности) Тест уже на телефоне помощнее — Xiaomi Mi A2


      1. rPman
        12.09.2019 19:26

        Это не модель виновата а камера, сенсор медленный изображение смазано…

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


  1. dim2r
    10.09.2019 20:58

    подскажите, как можно распознать положение тела? мне интересны 2 положения — стоя и лежа.


    1. rPman
      10.09.2019 21:13

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


    1. vashanin
      10.09.2019 22:16

      Есть претрейненная модель, которая называется PoseNet. Она позволяет трекать ключевые точки на теле человека. Ну а исходя их взаимного положения этих точек можно определять непосредственно положение тела.