Конверсия датасетов MNIST в формат PPM P6

Конверсия датасетов MNIST в формат PPM P6

При работе с машинным обучением и обработкой изображений, часто возникает необходимость преобразования датасетов в удобные для использования форматы. Один из самых известных датасетов для задачи распознавания рукописных цифр — MNIST. Этот датасет содержит изображения цифр и их метки. В данной статье мы рассмотрим, как устроены форматы данных и подписей в MNIST, и как их можно конвертировать в более удобный графический формат, например, PPM P6.

Форматы данных и подписей в MNIST

Формат данных

MNIST состоит из двух файлов: один для изображений и другой для меток. Формат файлов следующий:

  1. Файл изображений (train-images-idx3-ubyte):
  • Первые 4 байта: магическое число (0x00000803)
  • Следующие 4 байта: количество изображений
  • Следующие 4 байта: количество строк в изображении (28)
  • Следующие 4 байта: количество столбцов в изображении (28)
  • Далее идут байты с изображениями, каждое изображение представлено в виде последовательности 28×28 байт (0–255).
  1. Файл меток (train-labels-idx1-ubyte):
  • Первые 4 байта: магическое число (0x00000801)
  • Следующие 4 байта: количество меток
  • Далее идут байты с метками, каждая метка представлена одним байтом (0–9).

Конвертация в формат PPM P6

Формат PPM P6

PPM (Portable Pixmap) — это простой формат хранения изображений. Формат PPM P6 поддерживает цветные изображения и хранит данные в бинарном виде. Структура PPM P6 файла:

  1. Заголовок:
  • P6 (идентификатор формата)
  • Ширина изображения
  • Высота изображения
  • Максимальное значение цвета (обычно 255)
  1. Данные изображения: последовательность байтов для всех пикселей (R, G, B).

Пример скрипта на D для конверсии

import std.stdio;
import std.file;
import std.zlib;
import std.conv;
import std.array;

void convertMNISTtoPPM(string imageFilePath, string labelFilePath, string outputDir) {
    // Скачиваем и распаковываем файлы MNIST (предполагаем, что файлы уже скачаны и находятся в imageFilePath и labelFilePath)
    ubyte[] imageData = cast(ubyte[]) read(imageFilePath);
    ubyte[] labelData = cast(ubyte[]) read(labelFilePath);

    // Парсим заголовки файлов
    size_t numImages = to!size_t(imageData[4..8].reverse);
    size_t numRows = to!size_t(imageData[8..12].reverse);
    size_t numCols = to!size_t(imageData[12..16].reverse);
    assert(numRows == 28 && numCols == 28);

    // Создаем выходную директорию, если она не существует
    if (!exists(outputDir)) {
        mkdir(outputDir);
    }

    // Конвертируем каждое изображение в PPM
    size_t imageSize = numRows * numCols;
    foreach (i; 0 .. numImages) {
        // Извлекаем изображение
        ubyte[] image = imageData[16 + i * imageSize .. 16 + (i + 1) * imageSize];

        // Извлекаем метку
        ubyte label = labelData[8 + i];

        // Генерируем имя файла
        string outputFileName = format("%s/%02d_%05d.ppm", outputDir, label, i);
        File outputFile = File(outputFileName, "wb");

        // Пишем заголовок PPM
        outputFile.write("P6\n%d %d\n255\n".format(numCols, numRows));

        // Пишем данные изображения, преобразуем в формат RGB (серые значения)
        foreach (pixel; image) {
            outputFile.rawWrite([pixel, pixel, pixel]);
        }

        outputFile.close();
    }
}

void main() {
    string imageFilePath = "train-images-idx3-ubyte";
    string labelFilePath = "train-labels-idx1-ubyte";
    string outputDir = "output";

    convertMNISTtoPPM(imageFilePath, labelFilePath, outputDir);
}

Пояснение работы скрипта

  1. Загрузка данных:
  • Скрипт предполагает, что файлы MNIST уже скачаны и находятся в директориях, указанных в imageFilePath и labelFilePath.
  • Файлы читаются целиком в массивы imageData и labelData.
  1. Парсинг заголовков:
  • Из массива данных извлекаются заголовки, чтобы получить количество изображений, количество строк и столбцов.
  1. Конвертация изображений:
  • Для каждого изображения извлекается его часть из массива данных.
  • Метка изображения используется для генерации имени файла.
  • Создается файл PPM и записывается его заголовок.
  • Данные изображения записываются в формате RGB (серые значения повторяются трижды для каждого пикселя).
  1. Создание выходной директории:
  • Проверяется наличие директории для выходных файлов, при отсутствии — создается.
  1. Вывод файлов:
  • Каждый файл сохраняется в директорию с именем, включающим метку и индекс изображения.

Особенности и ограничения

  • Для работы требуется наличие библиотек для работы с файлами и бинарными данными.
  • Скрипт использует методы read, write, mkdir и другие функции стандартной библиотеки языка D для работы с файловой системой и бинарными данными.

Конвертация датасетов в более удобные форматы позволяет значительно облегчить их использование в задачах машинного обучения и анализа данных. Приведенный пример скрипта на языке D демонстрирует процесс конверсии изображений из формата MNIST в формат PPM P6, что делает данные более доступными для последующей обработки и визуализации.


Карпов Ярослав

Автор статьи:

Обновлено:

24.05.2024


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *