Для эффективного использования Keras.js при работе с видео в реальном времени критически важна корректная подготовка кадров перед передачей их в модель. Основные задачи предобработки включают:
Для большинства моделей Keras.js требуется передача данных в виде
Float32Array. Стандартная процедура нормализации:
function normalizeFrame(frameData) {
const normalized = new Float32Array(frameData.length);
for (let i = 0; i < frameData.length; i++) {
normalized[i] = frameData[i] / 255.0;
}
return normalized;
}
Ключевой момент: при работе с реальным временем необходимо избегать создания лишних объектов на каждый кадр, чтобы не перегружать сборщик мусора и не снижать частоту кадров.
Использование встроенного HTML5 Canvas позволяет эффективно менять размер кадров перед подачей в модель:
function resizeFrame(frame, width, height) {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
ctx.drawImage(frame, 0, 0, width, height);
return ctx.getImageData(0, 0, width, height).data;
}
Особое внимание уделяется сохранению пропорций объектов на кадре. При этом можно использовать добавление полей (padding) с последующей нормализацией координат объектов.
Keras.js ожидает данные в формате
[канал, высота, ширина] или
[высота, ширина, канал] в зависимости от конфигурации
модели (channels_first или channels_last).
Пример перестановки каналов:
function convertToCHW(imageData, width, height) {
const [r, g, b] = [new Float32Array(width * height), new Float32Array(width * height), new Float32Array(width * height)];
for (let i = 0; i < width * height; i++) {
r[i] = imageData[i * 4] / 255.0;
g[i] = imageData[i * 4 + 1] / 255.0;
b[i] = imageData[i * 4 + 2] / 255.0;
}
return new Float32Array([...r, ...g, ...b]);
}
Эффективность обработки напрямую влияет на задержку модели. При видео 30 fps каждая миллисекунда на предобработку имеет значение.
Предобработка кадров в реальном времени требует работы с
MediaStream или <video> элементом:
const video = document.querySelector('video');
const processFrame = () => {
const frameData = captureFrame(video);
const resized = resizeFrame(frameData, 224, 224);
const normalized = normalizeFrame(resized);
const chwData = convertToCHW(normalized, 224, 224);
model.predict({input: chwData});
requestAnimationFrame(processFrame);
};
video.onp lay = processFrame;
Здесь важно использовать requestAnimationFrame, чтобы
синхронизировать обработку с частотой обновления экрана и не перегружать
браузер.
OffscreenCanvas:
позволяет обрабатывать кадры вне основного потока интерфейса.TypedArray.Эффективная предобработка кадров обеспечивает не только корректность работы модели, но и стабильную работу приложения в реальном времени, позволяя достигать высоких FPS и низкой задержки при анализе видеопотока.