Библиотека 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 возвращает объект позы с ключевыми точками (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 позволяет реализовать:
poseNet.singlePose(video)
для одного человека, если многопозовый режим не требуется.frameCount % n === 0.Совместное использование Handpose и PoseNet в ml5.js позволяет создавать высокоинтерактивные приложения с точным отслеживанием как положения тела, так и движений рук. Продуманная визуализация и оптимизация обеспечивают плавную работу в браузере без заметных задержек, открывая широкие возможности для творчества и обучения.