Библиотека ml5.js представляет собой высокоуровневый интерфейс для работы с моделями машинного обучения в браузере на языке JavaScript. Она строится поверх TensorFlow.js и ориентирована на простоту использования, сохраняя при этом гибкость и возможности работы с реальными данными. Для задач отслеживания жестов в реальном времени ml5.js предлагает несколько подходов, включая использование предварительно обученных моделей, таких как Handpose и PoseNet, а также кастомные классификаторы на основе webcam-данных.
Для работы с ml5.js необходимо подключить библиотеку через CDN или npm-пакет. В случае веб-приложения подключение через CDN выглядит следующим образом:
<script src="https://cdn.jsdelivr.net/npm/ml5@latest/dist/ml5.min.js"></script>
После подключения можно инициализировать видеопоток с веб-камеры и загрузить модель:
let video;
let handposeModel;
async function setupCameraAndModel() {
video = document.createElement('video');
video.width = 640;
video.height = 480;
video.autoplay = true;
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
handposeModel = await ml5.handpose(video);
handposeModel.on('predict', handlePredictions);
}
Модель Handpose предназначена для обнаружения и
анализа 21 ключевой точки руки (keypoints) в пространстве 3D. Каждая
точка содержит координаты x, y и
z, где z отражает глубину относительно камеры.
Эти данные позволяют не только визуализировать положение кисти, но и
распознавать сложные жесты.
Пример обработки предсказаний:
function handlePredictions(predictions) {
if (predictions.length > 0) {
const hand = predictions[0];
hand.landmarks.forEach((point, index) => {
console.log(`Точка ${index}: x=${point[0]}, y=${point[1]}, z=${point[2]}`);
});
}
}
Для отображения ключевых точек и соединительных линий удобно использовать Canvas API. Это позволяет строить интерактивные интерфейсы, где положение руки напрямую влияет на графику или объекты на экране.
function drawHand(ctx, landmarks) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// Рисуем ключевые точки
landmarks.forEach(point => {
ctx.beginPath();
ctx.arc(point[0], point[1], 5, 0, 2 * Math.PI);
ctx.fillStyle = 'red';
ctx.fill();
});
// Соединяем точки линиями (пример: соединяем суставы пальцев)
const fingers = [
[0, 1, 2, 3, 4],
[0, 5, 6, 7, 8],
[0, 9, 10, 11, 12],
[0, 13, 14, 15, 16],
[0, 17, 18, 19, 20]
];
fingers.forEach(finger => {
ctx.beginPath();
ctx.moveTo(landmarks[finger[0]][0], landmarks[finger[0]][1]);
for (let i = 1; i < finger.length; i++) {
ctx.lineTo(landmarks[finger[i]][0], landmarks[finger[i]][1]);
}
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
ctx.stroke();
});
}
Для распознавания конкретных жестов можно использовать два подхода:
Классификация через KNN или нейронную сеть ml5.js Предварительно собираются примеры жестов с разметкой, после чего модель обучается классифицировать новые предсказания Handpose.
Логический анализ ключевых точек Для простых жестов, таких как поднятая ладонь или сжатый кулак, можно анализировать расстояния между определёнными ключевыми точками.
Пример простого распознавания «кулака»:
function isFist(landmarks) {
const tipDistances = [
distance(landmarks[4], landmarks[0]),
distance(landmarks[8], landmarks[0]),
distance(landmarks[12], landmarks[0]),
distance(landmarks[16], landmarks[0]),
distance(landmarks[20], landmarks[0])
];
const threshold = 30; // пиксели, зависит от разрешения видео
return tipDistances.every(d => d < threshold);
}
function distance(a, b) {
return Math.sqrt(Math.pow(a[0]-b[0], 2) + Math.pow(a[1]-b[1], 2));
}
requestAnimationFrame или setInterval для
ограничения частоты обработки кадров.Результаты Handpose можно применять для:
Ключевой особенностью ml5.js является простота интеграции с существующими веб-технологиями, включая Canvas, WebGL и даже библиотеки визуализации вроде p5.js. Это позволяет строить динамичные и отзывчивые приложения с трекингом жестов в реальном времени, минимизируя объем кода и сложность работы с нейросетями напрямую через TensorFlow.js.