Совместное использование Handpose и PoseNet

Библиотека ml5.js предоставляет высокоуровневый интерфейс для работы с различными моделями машинного обучения на JavaScript. Среди доступных моделей особое место занимают PoseNet и Handpose, которые позволяют отслеживать положение тела и рук в реальном времени. Их совместное использование открывает возможности для создания интерактивных приложений, распознающих сложные жесты и позы.


Инициализация камер и моделей

Для начала работы требуется подключить ml5.js через CDN или npm. После этого необходимо настроить видео-поток с камеры:

let video;
let poseNet;
let handpose;
let poses = [];
let hands = [];

video = createCapture(VIDEO);
video.size(640, 480);
video.hide();
  • createCapture(VIDEO) — захват видео с веб-камеры.
  • video.size(width, height) — установка разрешения.
  • video.hide() — скрытие стандартного HTML-элемента <video> для использования канваса.

Модели инициализируются асинхронно:

poseNet = ml5.poseNet(video, modelReady);
poseNet.on('pose', function(results) {
  poses = results;
});

handpose = ml5.handpose(video, handModelReady);
handpose.on('hand', function(results) {
  hands = results;
});
  • poseNet.on('pose', callback) — получает массив поз с ключевыми точками.
  • handpose.on('hand', callback) — возвращает массив объектов рук с ключевыми точками пальцев.

Функции modelReady и handModelReady служат для подтверждения готовности моделей к обработке видео.


Структура данных PoseNet и Handpose

PoseNet возвращает объект позы с ключевыми точками (keypoints), содержащими координаты x, y и уверенность (confidence):

{
  "keypoints": [
    { "part": "nose", "position": { "x": 300, "y": 200 }, "score": 0.99 },
    ...
  ]
}

Handpose формирует объект с 21 ключевой точкой руки, каждая из которых имеет координаты x, y, z:

{
  "landmarks": [
    [x, y, z], 
    ...
  ],
  "annotations": {
    "thumb": [[x, y, z], ...],
    "indexFinger": [[x, y, z], ...],
    ...
  }
}
  • landmarks — полный массив точек.
  • annotations — логическая группировка точек по пальцам и ладони.

Совмещение данных для визуализации

Для отображения и анализа одновременно позы тела и рук используется один канвас. Основной цикл рисования:

function draw() {
  image(video, 0, 0, width, height);
  
  drawPoses();
  drawHands();
}

Рисование позы тела:

function drawPoses() {
  for (let i = 0; i < poses.length; i++) {
    let pose = poses[i].pose;
    for (let j = 0; j < pose.keypoints.length; j++) {
      let keypoint = pose.keypoints[j];
      if (keypoint.score > 0.5) {
        fill(255, 0, 0);
        noStroke();
        ellipse(keypoint.position.x, keypoint.position.y, 10, 10);
      }
    }
  }
}

Рисование рук:

function drawHands() {
  for (let i = 0; i < hands.length; i++) {
    let hand = hands[i];
    for (let j = 0; j < hand.landmarks.length; j++) {
      let [x, y, z] = hand.landmarks[j];
      fill(0, 0, 255);
      noStroke();
      ellipse(x, y, 8, 8);
    }

    // Соединение пальцев
    let fingers = Object.values(hand.annotations);
    for (let k = 0; k < fingers.length; k++) {
      let finger = fingers[k];
      for (let l = 0; l < finger.length - 1; l++) {
        stroke(0, 255, 0);
        line(finger[l][0], finger[l][1], finger[l + 1][0], finger[l + 1][1]);
      }
    }
  }
}
  • Ключевые точки тела выделяются красным, руки — синим.
  • Пальцы соединяются зелеными линиями для наглядного отображения.

Синхронизация данных

Совместное использование моделей требует синхронизации кадров. PoseNet и Handpose обрабатывают один и тот же видео-поток, поэтому нужно следить за тем, чтобы обработка не создавала задержек:

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

Применение совместного отслеживания

Совмещение Handpose и PoseNet позволяет реализовать:

  1. Системы управления жестами — например, поднятие руки для запуска события.
  2. Интерактивные игры — персонаж реагирует на движения тела и пальцев.
  3. Визуальные эффекты в реальном времени — наложение графики на руки и тело.
  4. Анализ движений — спорт и танцы, где важны как поза, так и положение кистей.

Оптимизация производительности

  • Снижать разрешение видео при необходимости.
  • Использовать poseNet.singlePose(video) для одного человека, если многопозовый режим не требуется.
  • Объединять отрисовку ключевых точек в один цикл для уменьшения нагрузки на рендеринг.
  • Ограничивать частоту обработки модели с помощью таймеров или frameCount % n === 0.

Совместное использование Handpose и PoseNet в ml5.js позволяет создавать высокоинтерактивные приложения с точным отслеживанием как положения тела, так и движений рук. Продуманная визуализация и оптимизация обеспечивают плавную работу в браузере без заметных задержек, открывая широкие возможности для творчества и обучения.