Реалізація оцінки поз (Pose Estimation) у мобільних додатках
Оцінка поз детектує 17–33 ключових точок скелета людини в реальному часі. Використовується у фітнес-додатках (підрахунок повторень, оцінка техніки), медичних додатках (реабілітація, аналіз ходи) та AR-продуктах. Складніше за детекцію об'єктів: потребує не тільки точності локалізації точок, але й стабільності між кадрами.
Вибір моделі: MoveNet vs BlazePose vs ML Kit Pose Detection
MoveNet Lightning/Thunder (Google)—найкращий баланс точність/швидкість для мобіля. Lightning: 17 точок, 30+ FPS на iPhone 12, TFLite-оптимізована. Thunder: точніша, ~15 FPS. Доступна через TFLite Task Library як PoseLandmarker.
MediaPipe BlazePose / Pose Landmarker—33 точки (включаючи точки обличчя, ніг, рук). Потрібна коли деталі важливі: кут зап'ястка, положення пальців. Latency: ~25 ms на Pixel 7 GPU, ~55 ms на CPU.
ML Kit Pose Detection—33 точки, простої Firebase інтеграції. In-process, без мережі. Трохи повільніше MoveNet, простіша для Android/iOS cross-platform.
Для фітнес-трекінгу повторень, MoveNet Lightning достатньо. Для медичного аналізу ходи, BlazePose з 33 точками та z-координатами.
Підрахунок повторень: складніше, ніж здається
Типове завдання: "підрахувати прихови". Наївний підхід: стежити за Y-координатою стегна, лічити перетину порога. Працює в ідеальних умовах, ломається в реальності.
Правильний підхід: обраховуйте кут у колінному суглобі через dot product векторів [HIP → KNEE] та [KNEE → ANKLE]. Прихід = кут впав нижче 120°. Вставання = кут повернувся вище 160°. Державна машина: STANDING → DOWN → STANDING = 1 повторення.
3D кут через z-координати стабільніший за 2D якщо камера не строго боком. BlazePose/MoveNet повертають z в нормалізованих одиницях—це оцінка глибини, не абсолютні метри. Достатньо для кутів, недостатньо для абсолютних дистанцій.
Згладження landmarks—обов'язково. Сирі дані стрибають на 3–5 пікселів між кадрами. Найпростіший фільтр: експоненціальне рухоме середнє EMA(α=0.6) на координату. MediaPipe надає VelocityFilter—краще для нелінійних рухів.
Інтеграція: iOS та Android
iOS: MediaPipe Tasks Vision через Swift Package Manager. PoseLandmarker з runningMode = .liveStream. Callback повертає PoseLandmarkerResult з landmarks (нормалізовані) та worldLandmarks (метри, для фізичних обчислень). Малюйте скелет на AVCaptureVideoPreviewLayer через CAShapeLayer—не UIKit UIView (важче).
Android: com.google.mediapipe:tasks-vision. PoseLandmarker.create() з BaseOptions.GPU_DELEGATE на підтримуваних пристроях. Малюйте через Canvas.drawLine() на SurfaceView.
Кейс: програма реабілітації після травми колінниці. Потребує оцінки кута згинання у колінниці при виконанні вправ. Використовували MoveNet Thunder (точніша за Lightning для невеликих рухів). Кут через dot product 2D-векторів (z непотрібна, камера строго боком—обмеження завдання). Помилка вимірювання кута проти гоніометра лікаря: ±4.2°. Достатньо для контролю прогресу, не для медичної діагностики—важливо повідомити в UI.
Малюйте скелет через CAShapeLayer з CABasicAnimation на path—плавніше ніж перерисовування в drawRect кожен кадр.
Поширені помилки
Малювання скелета в координатах моделі без трансформації в координати preview. MoveNet точки нормалізовані (0..1), координати preview залежать від gravity AVCaptureVideoPreviewLayer. Потребує явної трансформації з врахуванням aspect ratio та crop.
Запуск infer на main thread—гарантований 0 FPS UI. Infer на DispatchQueue.global(qos: .userInteractive) (iOS) або Executors.newSingleThreadExecutor() (Android).
Часові рамки
Базовий скелет на відеопотоці + підрахунок однієї вправи: 1–2 тижні. Повний фітнес-модуль з кількома вправами, голосовою зворотною синтез та історією: 3–4 тижні. Вартість розраховується індивідуально.







