Обработка видеопотока с getUserMedia

Для работы с Keras.js требуется подключение библиотеки через <script> или установку через пакетный менеджер. В браузерной среде проще всего использовать CDN:

<script src="https://cdn.jsdelivr.net/npm/keras-js@0.4.0/dist/keras.min.js"></script>

После подключения создаётся объект KerasJS.Model, который загружает предварительно обученную модель. Модель должна быть экспортирована из Keras в формат JSON с весами в бинарном виде.

const model = new KerasJS.Model({
  filepath: 'model.json',
  gpu: true
});
await model.ready();

Флаг gpu: true позволяет использовать WebGL для ускорения вычислений. Для браузерного приложения это критично при обработке видеопотока в реальном времени.


Получение видеопотока с getUserMedia

Для доступа к камере используется API navigator.mediaDevices.getUserMedia. Необходимо указать параметры потока:

const constraints = {
  video: { width: 640, height: 480, facingMode: "user" },
  audio: false
};

const stream = await navigator.mediaDevices.getUserMedia(constraints);
const videoElement = document.createElement('video');
videoElement.srcObject = stream;
videoElement.play();

Параметры width и height задают разрешение кадра. facingMode: "user" выбирает фронтальную камеру. Поток можно сразу выводить в элемент <video> для визуальной отладки.


Подготовка кадра для модели

Keras.js ожидает входные данные в формате Float32Array с нормализованными значениями (обычно от 0 до 1). Для преобразования видео в такой формат используется <canvas>:

const canvas = document.createElement('canvas');
canvas.width = 224;
canvas.height = 224;
const ctx = canvas.getContext('2d');

function preprocessFrame(video) {
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  const { data } = imageData;
  const input = new Float32Array(canvas.width * canvas.height * 3);
  for (let i = 0; i < canvas.width * canvas.height; i++) {
    input[i * 3 + 0] = data[i * 4 + 0] / 255; // R
    input[i * 3 + 1] = data[i * 4 + 1] / 255; // G
    input[i * 3 + 2] = data[i * 4 + 2] / 255; // B
  }
  return input;
}
  • Канал альфа игнорируется.
  • Изображение масштабируется до размера модели (например, 224×224).
  • Нормализация в диапазон [0,1] обязательна для корректного предсказания.

Передача данных в модель

После подготовки кадра создаётся объект входных данных. Keras.js требует словарь с именами входных слоёв:

const inputData = {
  'input_1': preprocessFrame(videoElement)
};

const outputData = await model.predict(inputData);
console.log(outputData);

outputData содержит массивы чисел — результаты последнего слоя сети. Для классификации обычно применяется argmax по выходу модели.


Организация обработки в реальном времени

Для видеопотока важна оптимизация частоты обработки, чтобы не перегружать браузер. Используется requestAnimationFrame:

async function processVideoFrame() {
  const inputData = { 'input_1': preprocessFrame(videoElement) };
  const outputData = await model.predict(inputData);
  handlePrediction(outputData);
  requestAnimationFrame(processVideoFrame);
}

processVideoFrame();
  • Асинхронная функция позволяет не блокировать интерфейс.
  • requestAnimationFrame синхронизирует обработку с частотой обновления экрана.
  • Можно уменьшать размер кадра или пропускать кадры для повышения производительности.

Применение результатов модели

В зависимости от задачи, результаты могут использоваться для:

  • Классификации объектов в кадре.
  • Детекции жестов или лиц.
  • Генерации визуальных эффектов на основе анализа видео.

Например, для отображения вероятностей классов:

function handlePrediction(outputData) {
  const probabilities = outputData['dense_2']; // последний слой модели
  const maxIndex = probabilities.indexOf(Math.max(...probabilities));
  console.log(`Класс: ${maxIndex}, вероятность: ${probabilities[maxIndex]}`);
}

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

  • Использовать WebGL (gpu: true).
  • Масштабировать кадр до минимально допустимого размера для модели.
  • Пропускать кадры при высокой нагрузке.
  • Кэшировать объекты Float32Array для уменьшения аллокаций памяти.
  • Выполнять предварительную загрузку модели и весов до старта видеопотока.

Особенности работы в браузере

  • Запрос камеры требует HTTPS.
  • Некоторые браузеры блокируют автоматическое воспроизведение <video> без взаимодействия пользователя.
  • Разные устройства могут выдавать разное разрешение потока — необходимо динамически адаптировать размеры canvas.

Интеграция с другими библиотеками

Keras.js легко комбинируется с:

  • TensorFlow.js — для сложной предобработки или кастомных слоёв.
  • tracking.js — для выделения объектов на видео до подачи на модель.
  • Three.js — для визуализации результатов предсказаний в 3D.

Такой подход позволяет строить интерактивные веб-приложения с обработкой видео в реальном времени, сохраняя совместимость с браузерными стандартами и WebGL.