Реализация распознавания жестов в мобильном приложении
Распознавание жестов через камеру — это интерфейс без касания. Используется в фитнес-приложениях (подсчёт повторений), в приложениях для людей с ограниченными возможностями, в AR-взаимодействиях и presentation-режимах. Ключевой инструмент — MediaPipe Hand Landmarker.
MediaPipe Hand Landmarker: как это работает
MediaPipe Hand Landmarker детектирует до 2 рук в кадре и возвращает 21 landmark для каждой руки: запястье, пястные кости, фаланги. Координаты — нормализованные (0..1) в пространстве изображения и 3D-координаты (z — глубина относительно запястья).
Латентность на современных устройствах:
- Pixel 7 (GPU): ~12 ms
- iPhone 14 (CPU): ~18 ms
- Snapdragon 665 mid-range (CPU): ~45 ms
Для real-time UI с 30 FPS бюджет — 33 ms. На слабых устройствах приходится выбирать: снизить частоту инференса до 15 FPS или работать только с одной рукой (numHands = 1).
Распознавание жестов поверх landmarks
MediaPipe Gesture Recognizer — надстройка над Hand Landmarker, распознаёт 7 жестов из коробки: Open_Palm, Closed_Fist, Pointing_Up, Thumb_Up, Thumb_Down, Victory, ILoveYou. Это достаточно для базового управления (следующий слайд, лайк/дизлайк, подтверждение).
Для кастомных жестов — два подхода:
Геометрический. Вычисляем углы между фалангами, расстояния между ключевыми точками, определяем «согнут ли палец» через скалярное произведение векторов. Быстро (нет дополнительного инференса), легко отлаживать. Хорошо работает для статических жестов (конкретная форма кисти).
ML-классификатор. Записываем набор landmark-векторов для каждого жеста, обучаем небольшой MLP или кастомный GestureRecognizer через MediaPipe Model Maker. Лучше работает для жестов, близких по форме, и для динамических жестов (движение руки).
Кейс: приложение для управления презентацией жестами во время стендапа. Жесты: «следующий слайд» (взмах вправо), «предыдущий» (взмах влево), «стоп» (открытая ладонь). Статические жесты через геометрию (Open_Palm из MediaPipe Gesture Recognizer). Динамические взмахи — через трекинг положения запястья (WRIST landmark) за 10 кадров: если delta_x > 0.3 нормализованных единиц за 333 ms — свайп. Порог подобрали экспериментально на 15 тест-пользователях.
Привязка жестов к действиям
Распознанный жест — это событие с confidence и timestamp. Не каждое событие нужно обрабатывать. Важен debouncing: жест «большой палец вверх» не должен засчитываться повторно, если рука не убиралась из кадра. Храним состояние: lastGestureTime, lastGestureType. Новый жест засчитывается только если прошло >500 ms или изменился тип.
На iOS: MediaPipeTasksVision пакет через Swift Package Manager, обёртка для GestureRecognizer в actor-классе. Результаты через @Published in ObservableObject.
На Android: MediaPipe Tasks Android SDK (com.google.mediapipe:tasks-vision). GestureRecognizerOptions с runningMode = RunningMode.LIVE_STREAM для видеопотока, callbacks через ResultListener.
Типичные ошибки реализации
Не учитывать handedness — MediaPipe возвращает LEFT/RIGHT с точки зрения модели (зеркально от фронтальной камеры). «Большой палец вправо» с фронтальной камеры детектируется как левая рука. Если логика зависит от конкретной руки — применять зеркальную коррекцию.
Не учитывать расстояние до камеры. Нормализованные координаты не несут информации о физическом расстоянии — геометрические пороги, работающие на 50 cm, будут другими на 150 cm.
Сроки
Базовые жесты через MediaPipe Gesture Recognizer + привязка к действиям — 1 неделя. Кастомные геометрические или ML-жесты + динамические свайпы — 2 недели. Стоимость рассчитывается индивидуально.







