Работа с изображениями: загрузка, декодирование, изменение размера

Для работы с изображениями в Keras.js первым шагом является их загрузка в память в виде объектов, с которыми можно производить дальнейшие операции. Обычно изображения загружаются в формате Image или HTMLImageElement через стандартные средства Jav * aScript:

const img = new Image();
img.src = 'path/to/image.jpg';
img.onl oad = () => {
    // Изображение готово для обработки
};

Ключевой момент — изображение должно полностью загрузиться, прежде чем его можно будет передавать в Keras.js. Попытка обработки незагруженного объекта приведет к ошибкам или некорректным результатам.


Декодирование изображений в массивы

После загрузки изображение необходимо преобразовать в числовой массив, который будет совместим с моделью Keras. Keras.js работает с тензорами, поэтому изображение сначала нужно представить как трехмерный массив [высота, ширина, каналы]. Для этого часто используется Canvas:

const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);

const imageData = ctx.getImageData(0, 0, img.width, img.height);
const data = imageData.data; // Uint8ClampedArray

imageData.data содержит значения пикселей в формате RGBA, где каждый пиксель представлен четырьмя числами от 0 до 255. Для нейронных сетей чаще всего используется только RGB, игнорируя альфа-канал. Конвертация в нормализованный формат может выглядеть так:

const width = img.width;
const height = img.height;
const channels = 3;
const input = new Float32Array(width * height * channels);

for (let i = 0, j = 0; i < data.length; i += 4, j += 3) {
    input[j] = data[i] / 255;     // R
    input[j + 1] = data[i + 1] / 255; // G
    input[j + 2] = data[i + 2] / 255; // B
}

Здесь производится масштабирование значений пикселей в диапазон [0, 1], что является стандартной практикой при работе с Keras-моделями.


Изменение размера изображений

Модели, обученные в Keras, требуют фиксированного размера входного изображения. Для приведения изображения к нужным параметрам используется метод drawImage с указанием размеров:

const targetWidth = 224;
const targetHeight = 224;

const resizedCanvas = document.createElement('canvas');
resizedCanvas.width = targetWidth;
resizedCanvas.height = targetHeight;
const resizedCtx = resizedCanvas.getContext('2d');

resizedCtx.drawImage(img, 0, 0, targetWidth, targetHeight);
const resizedData = resizedCtx.getImageData(0, 0, targetWidth, targetHeight).data;

После этого массив пикселей снова конвертируется в Float32Array и нормализуется. Важно учитывать правильное распределение данных по каналам: Keras.js ожидает данные в формате [каналы, высота, ширина] или [высота, ширина, каналы] в зависимости от модели. Преобразование может выглядеть следующим образом:

const inputResized = new Float32Array(targetWidth * targetHeight * channels);
for (let y = 0; y < targetHeight; y++) {
    for (let x = 0; x < targetWidth; x++) {
        const index = (y * targetWidth + x) * 4;
        const flatIndex = (y * targetWidth + x) * channels;
        inputResized[flatIndex] = resizedData[index] / 255;
        inputResized[flatIndex + 1] = resizedData[index + 1] / 255;
        inputResized[flatIndex + 2] = resizedData[index + 2] / 255;
    }
}

Формирование входного тензора для Keras.js

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

const inputTensor = {
    input_1: inputResized
};

Где input_1 — это имя входного слоя модели. Следует строго соблюдать соответствие размеров тензора и ожидаемого входа модели, иначе вычисления вызовут ошибку.


Практические рекомендации

  • Всегда проверять размер изображения перед обработкой. Несоответствие размеров может привести к silent errors.
  • Использовать Float32Array вместо стандартных массивов JavaScript для повышения производительности и совместимости с Keras.js.
  • Нормализовать значения пикселей в диапазон [0, 1], так как большинство моделей обучаются на нормализованных данных.
  • Ориентироваться на формат каналов модели. Многие модели требуют channels-first ([C, H, W]), но веб-среда обычно использует channels-last ([H, W, C]). Преобразование необходимо для корректного распознавания изображений.
  • При работе с большими изображениями использовать промежуточное уменьшение размеров через canvas, чтобы избежать чрезмерного потребления памяти.

Итоговые шаги обработки изображения

  1. Загрузка изображения через Image и ожидание события onload.
  2. Рисование изображения на Canvas для получения массива пикселей.
  3. Преобразование RGBA в RGB и нормализация значений.
  4. Изменение размера до требуемого моделью.
  5. Формирование входного тензора в нужном формате.

Эта последовательность обеспечивает корректную подачу изображений в Keras.js, позволяет использовать любые обученные модели и гарантирует соответствие входных данных требованиям нейронной сети.