Отслеживание поз в реальном времени

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

PoseNet работает по принципу детекции ключевых точек на теле человека. Модель возвращает массив объектов, каждый из которых содержит координаты (x, y) и уровень уверенности (confidence) для 17 стандартных точек: нос, глаза, уши, плечи, локти, запястья, бедра, колени, лодыжки.


Подключение ml5.js и настройка видео

Для работы с PoseNet необходимо подключить ml5.js и получить доступ к видеопотоку с камеры. Основные шаги:

  1. Подключение библиотеки:
<script src="https://cdn.jsdelivr.net/npm/ml5@latest/dist/ml5.min.js"></script>
  1. Создание видеопотока:
let video;

function setup() {
    createCanvas(640, 480);
    video = createCapture(VIDEO);
    video.size(width, height);
    video.hide();
}

Важно: video.hide() используется для того, чтобы скрыть стандартный элемент <video>, так как визуализация будет происходить на canvas.


Инициализация PoseNet

PoseNet можно создать с помощью метода ml5.poseNet(). Модель поддерживает два режима:

  • Single Pose Detection — определяет одну позу на кадр.
  • Multi Pose Detection — определяет несколько людей на одном кадре.

Пример инициализации:

let poseNet;
let poses = [];

function setup() {
    createCanvas(640, 480);
    video = createCapture(VIDEO);
    video.size(width, height);
    video.hide();

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

function modelReady() {
    console.log('PoseNet готов к работе');
}

Ключевой момент: обработчик poseNet.on('pose', callback) вызывается каждый раз, когда модель возвращает новый результат. Это позволяет отслеживать позы в реальном времени.


Работа с ключевыми точками

Каждая поза состоит из массива ключевых точек (keypoints). Для каждой точки доступны следующие параметры:

  • position.x — горизонтальная координата
  • position.y — вертикальная координата
  • score — уровень уверенности (от 0 до 1)
  • part — название точки ('nose', 'leftEye', 'rightShoulder' и т.д.)

Пример перебора всех ключевых точек и отрисовки их на canvas:

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

    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);
            }
        }
    }
}

Совет: порог уверенности (score > 0.5) помогает игнорировать малонадежные точки.


Отслеживание соединений между ключевыми точками

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

const skeletonConnections = [
    ['leftShoulder', 'rightShoulder'],
    ['leftShoulder', 'leftElbow'],
    ['leftElbow', 'leftWrist'],
    ['rightShoulder', 'rightElbow'],
    ['rightElbow', 'rightWrist'],
    ['leftHip', 'rightHip'],
    ['leftShoulder', 'leftHip'],
    ['rightShoulder', 'rightHip'],
    ['leftHip', 'leftKnee'],
    ['leftKnee', 'leftAnkle'],
    ['rightHip', 'rightKnee'],
    ['rightKnee', 'rightAnkle']
];

function drawSkeleton(pose) {
    for (let [partA, partB] of skeletonConnections) {
        let pointA = pose.keypoints.find(k => k.part === partA);
        let pointB = pose.keypoints.find(k => k.part === partB);
        if (pointA && pointB && pointA.score > 0.5 && pointB.score > 0.5) {
            stroke(0, 255, 0);
            line(pointA.position.x, pointA.position.y, pointB.position.x, pointB.position.y);
        }
    }
}

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

    for (let i = 0; i < poses.length; i++) {
        drawSkeleton(poses[i].pose);
    }
}

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

При работе с видеопотоком важно учитывать нагрузку на процессор. Рекомендации:

  • Уменьшение разрешения видео (video.size(320, 240)) снижает вычислительную нагрузку.
  • Использование Single Pose Mode для одного человека.
  • Ограничение частоты отрисовки с помощью frameRate(30).

Применение данных о позах

Отслеживание поз открывает возможности для интерактивных приложений:

  • Игры и упражнения — управление объектами через движение тела.
  • Анализ спортивной техники — оценка углов суставов.
  • Анимация — передача движений реального человека на 3D-модель.
  • Интерфейсы жестов — управление веб-приложениями с помощью жестов.

В ml5.js данные о позах можно использовать как обычные объекты JavaScript, что упрощает интеграцию с визуализацией, графикой на canvas и веб-анимацией.


Расширенные возможности

Помимо PoseNet, ml5.js предлагает и другие модели для отслеживания тела:

  • Handpose — детекция ключевых точек руки.
  • BodyPix — сегментация тела на пиксельном уровне.
  • FaceApi — отслеживание лицевых выражений и ключевых точек лица.

Эти модели могут комбинироваться с PoseNet для создания комплексных систем интерактивного взаимодействия.


Практические советы

  • Проверять уровень уверенности ключевых точек перед использованием для вычислений.
  • Использовать сглаживание координат, чтобы движения выглядели более плавными.
  • Хранить предыдущие позы для анализа динамики движения.
  • Визуализация скелета и ключевых точек помогает отладке и корректной настройке приложения.