Работа с Canvas API совместно с ml5.js

Основы интеграции ml5.js и Canvas API

ml5.js — это библиотека, построенная поверх TensorFlow.js, предоставляющая упрощённый доступ к моделям машинного обучения в браузере. Canvas API позволяет создавать динамическую графику, что делает их совместное использование естественным для визуализации результатов моделей. Взаимодействие сводится к двум основным этапам: получение данных от модели и отображение их на канве.

Создание канвы и контекста:

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
canvas.width = 640;
canvas.height = 480;

Контекст ctx предоставляет методы для рисования фигур, линий, текста и изображений, которые будут использоваться для визуализации предсказаний ml5.js.

Использование модели PoseNet с Canvas

PoseNet позволяет распознавать позы человека на изображении или видеопотоке. Для работы с Canvas API необходимо сначала загрузить модель и видео:

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

video = createCapture(VIDEO);
video.size(640, 480);

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

video.hide();

function modelLoaded() {
  console.log('PoseNet модель загружена');
}

Для визуализации используется функция draw(), вызываемая каждый кадр:

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

  drawKeypoints();
  drawSkeleton();
}

Отрисовка ключевых точек:

function drawKeypoints() {
  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) {
        ctx.beginPath();
        ctx.arc(keypoint.position.x, keypoint.position.y, 5, 0, 2 * Math.PI);
        ctx.fillStyle = 'red';
        ctx.fill();
      }
    }
  }
}

Отрисовка скелета:

function drawSkeleton() {
  for (let i = 0; i < poses.length; i++) {
    let skeleton = poses[i].skeleton;
    for (let j = 0; j < skeleton.length; j++) {
      let partA = skeleton[j][0];
      let partB = skeleton[j][1];
      ctx.beginPath();
      ctx.moveTo(partA.position.x, partA.position.y);
      ctx.lineTo(partB.position.x, partB.position.y);
      ctx.strokeStyle = 'green';
      ctx.lineWidth = 2;
      ctx.stroke();
    }
  }
}

Взаимодействие с другими моделями ml5.js

Canvas API подходит не только для PoseNet. Любые модели, возвращающие координаты, вероятности или метки, могут быть визуализированы:

  • Image Classification: отображение меток поверх изображения или видео.
  • Object Detection (COCO-SSD): отрисовка ограничивающих рамок и подписей.
  • Face API: наложение масок или выделение лиц.

Пример отрисовки объектов COCO-SSD:

let objectDetector;
let objects = [];

objectDetector = ml5.objectDetector('cocossd', modelReady);
video.hide();

function modelReady() {
  objectDetector.detect(video, gotResults);
}

function gotResults(err, results) {
  if (err) {
    console.error(err);
    return;
  }
  objects = results;
  objectDetector.detect(video, gotResults);
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

  for (let i = 0; i < objects.length; i++) {
    let object = objects[i];
    ctx.strokeStyle = 'blue';
    ctx.lineWidth = 2;
    ctx.strokeRect(object.x, object.y, object.width, object.height);
    ctx.fillStyle = 'blue';
    ctx.font = '16px Arial';
    ctx.fillText(`${object.label} (${Math.floor(object.confidence * 100)}%)`, object.x + 5, object.y - 5);
  }
}

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

При работе с Canvas API важно учитывать частоту обновления кадров и размер канвы. Для видео 640x480 рекомендуется:

  • Ограничивать количество одновременных вызовов модели.
  • Использовать requestAnimationFrame(draw) вместо setInterval, чтобы синхронизировать отрисовку с частотой обновления экрана.
  • Очищать канву перед каждой отрисовкой через ctx.clearRect() для предотвращения наложения предыдущих кадров.

Работа с цветом, стилями и прозрачностью

Canvas API предоставляет гибкие возможности стилизации. Для визуализации результатов ml5.js можно использовать:

  • ctx.globalAlpha — прозрачность объектов.
  • ctx.fillStyle и ctx.strokeStyle — цвет заливки и линий.
  • ctx.lineWidth — толщина линий.
  • ctx.shadowBlur и ctx.shadowColor — эффекты тени для выделения ключевых точек.

Использование этих инструментов позволяет создавать информативные и эстетически привлекательные визуализации предсказаний моделей машинного обучения в реальном времени.

Интерактивные визуализации

Canvas API позволяет не только рисовать, но и реагировать на события пользователя:

canvas.addEventListener('click', function(event) {
  const x = event.offsetX;
  const y = event.offsetY;
  console.log(`Клик по координатам: ${x}, ${y}`);
});

Это открывает возможности для создания интерактивных проектов, где предсказания моделей ml5.js могут использоваться для управления графикой, а пользовательские действия — для изменения параметров модели или визуализации.

Закрепление данных между кадрами

Для сложных анимаций и эффектов важно сохранять состояние между кадрами. Это может быть массив предыдущих координат, история движений или накопление статистики, которую можно визуализировать на канве.

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