Посмотреть как Markdown

Форматы датасетов

Эта страница повторяет контракт файлов датасета из docs/dataset_schema.md в самой библиотеке. Здесь описаны ключи YAML и раскладка на диске, которых ожидает каждая каноническая задача.

Общий YAML

Относится к detect, segment, pose и obb.

КлючОбязателенОписание
pathКорень датасета
trainДля обученияИзображения для обучения
valДля валидацииИзображения для валидации
testТестовые изображения
namesДаСписок классов или словарь с целочисленными ключами
ncКоличество классов; должно совпадать с names, если он задан
downloadИнструкции для скачивания; Python-скрипты требуют явного разрешения
annotationsСопоставление сплита с нативным файлом COCO JSON, для detect, segment и obb

train, val и test могут быть каталогами изображений, .txt-файлами со списками изображений или списками таких путей. Пути к разметке получаются одной подстановкой:

images/.../image.jpg -> labels/.../image.txt

Для датасета в нативном формате COCO JSON annotations сопоставляет сплит с его JSON-файлом, а путь сплита задаёт корень изображений:

yaml
path: dataset
train: images/train
val: images/val
annotations:
  train: annotations/train.json
  val: annotations/val.json

Если names задан, имена категорий в нативном COCO JSON должны совпадать с именами классов из YAML, и именно эти имена определяют ID меток модели. Без names ID категорий COCO сортируются и плотно отображаются в 0..N-1.

YAML датасета не содержит ключа task. Приоритет у явного выбора модели и задачи.

Правила, общие для всех текстовых файлов разметки:

  • один .txt-файл разметки на изображение;
  • отсутствующий или пустой файл разметки означает, что объектов нет;
  • class_id — целое число в 0..nc-1;
  • координаты — конечные нормализованные числа с плавающей точкой в [0, 1];
  • координаты заданы относительно исходных ширины и высоты изображения;
  • в строках нет ни оценки уверенности, ни ID трека.

Разбор одной строки разметки detect
from libreyolo.data import parse_yolo_label_line # class_id cx cy w h, нормализовано в [0, 1]row = parse_yolo_label_line("0 0.5 0.5 0.25 0.5", 640, 480, num_classes=80) # (class_id, x1, y1, x2, y2, area) в пикселяхprint(row)

detect

Ровно пять полей в строке:

<class_id> <cx> <cy> <w> <h>

cx cy w h — нормализованная рамка, выровненная по осям, а w и h должны быть положительными.

segment

Строка с полигоном:

<class_id> <x1> <y1> ... <xN> <yN>

N — не меньше 3, число координат после class_id должно быть чётным, а полигон — невырожденным. Строка детекции из пяти полей тоже принимается и задаёт прямоугольный сегмент.

pose

В YAML добавляется обязательный kpt_shape со значением [K, 2] или [K, 3], а также необязательный flip_idx — целочисленная перестановка 0..K-1.

<class_id> <cx> <cy> <w> <h> <k1x> <k1y> [<k1v>] ... <kKx> <kKy> [<kKv>]

Полей ровно 5 + K * D, где D — второе значение kpt_shape. Координаты ключевых точек нормализованы. Видимость v, если она есть, равна 0, 1 или 2.

obb

Ровно девять полей:

<class_id> <x1> <y1> <x2> <y2> <x3> <y3> <x4> <y4>

Четыре точки — нормализованные координаты изображения в [0, 1], образующие невырожденный повёрнутый прямоугольник. Угол в файле разметки не хранится.

Канонический парсер по умолчанию строгий и отклоняет координаты вне диапазона. При загрузке датасета и на валидации координаты могут обрезаться до [0, 1], если разметка на границе кропа в остальном корректна, — но вырожденные рамки всё равно отклоняются. Разбор учитывает задачу: девять полей означают obb только в режиме obb, а в режиме segment они могут быть полигоном из четырёх точек.

Внутри нормализованные вершины преобразуются в канонический xywhr, где угол в радианах задаёт поворот стороны ширины вокруг центра рамки. В публичных результатах детекции OBB представлены строками xywhr, conf, cls.

Загрузка OBB из нативного COCO JSON принимает аннотации в таком порядке приоритета: obb как восемь пиксельных координат вершин; obb как [cx, cy, w, h, angle] с углом в радианах; полигон или RLE из COCO segmentation, пересчитанный в прямоугольник минимальной площади; и COCO bbox, прочитанный как выровненный по осям и приведённый к каноническому виду.

Mosaic и mixup отключены при обучении OBB, пока нет аугментации OBB, учитывающей вершины рамок.

Канонический парсер строк — libreyolo.data.parse_yolo_obb_label_line.

semantic

Каждому изображению соответствует плотная одноканальная маска в формате без потерь, обычно PNG, вместо .txt-файла:

images/.../image.jpg -> <masks_dir>/.../image.png

Маска одноканальная, а PNG в палитровом режиме читаются как индексы палитры. Значение каждого пикселя — ID класса в 0..nc-1, значение 255 означает игнорирование и исключается из функции потерь и метрик, а разрешение маски должно совпадать с разрешением изображения.

Поверх общего контракта добавляются два необязательных ключа YAML. masks_dir — имя каталога масок, которое подставляется вместо images в каждом пути изображения; по умолчанию masks. label_mapping — переотображение {source_id: train_id}, применяемое к значениям пикселей маски при загрузке, в котором неотображённые исходные значения становятся игнорируемыми, а train ID должны попадать в 0..nc-1.

Если masks_dir не задан, маски растеризуются при загрузке из полигональной разметки segment, найденной по соглашению подстановки images на labels, а после классов объектов добавляется класс background, так что nc увеличивается на единицу.

Канонический загрузчик: libreyolo.data.SemanticDataset.

panoptic

LibreYOLO использует формат COCO-panoptic без изменений (Kirillov et al., CVPR 2019). Отдельного паноптического формата у LibreYOLO нет.

Один RGB PNG на изображение, в разрешении изображения, кодирует цветом ID сегмента каждого пикселя:

segment_id = R + 256 * G + 256 * 256 * B

Каждый пиксель принадлежит ровно одному сегменту, и сегменты никогда не пересекаются. ID сегмента 0, чёрный в RGB, — это void: неразмеченные пиксели, исключённые из метрики.

json
{
  "images":      [{"id": 139, "file_name": "000000000139.jpg"}],
  "annotations": [{"image_id": 139, "file_name": "000000000139.png",
                   "segments_info": [
                     {"id": 3226956, "category_id": 1, "area": 2840,
                      "bbox": [413, 158, 53, 138], "iscrowd": 0}]}],
  "categories":  [{"id": 1, "name": "person", "isthing": 1, "supercategory": "person"}]
}

annotations[].file_name задаёт имя PNG с ID сегментов внутри panoptic_dir, а segments_info[].id соответствует значению в этом PNG. iscrowd помечает групповые области: они никогда не считаются ложноотрицательными, а предсказание, покрывающее такую область по большей части, не считается ложноположительным.

Разделение на thing и stuff — свойство категории. isthing находится в categories, никогда — в segments_info.

Значения category_id в COCO-panoptic — это исходные ID датасета, и они обычно идут не подряд. Модели предсказывают идущие подряд 0..nc-1, поэтому исходные ID переотображаются через YAML-ключ names по имени категории — по тому же правилу, которому следует загрузчик detect для нативного COCO JSON. Категория из JSON, которой нет в names, — это ошибка, а не молчаливое отбрасывание, потому что иначе она навсегда засчитывалась бы как ложноотрицательная.

yaml
path: coco
val: images/val2017
annotations:
  val: annotations/panoptic_val2017.json
panoptic_dir:
  val: annotations/panoptic_val2017
names: {0: person, 1: bicycle, 132: rug-merged}

annotations и panoptic_dir принимают либо один путь, либо словарь по сплитам.

Валидация выдаёт Panoptic Quality, вычисленное в разрешении эталонной разметки и усреднённое по встречающимся категориям, а затем разделённое на PQ_things и PQ_stuff. Сопоставление взаимно однозначное: предсказанный и эталонный сегменты одной категории сопоставляются, когда IoU выше 0.5.

Канонический загрузчик: libreyolo.data.PanopticDataset.

depth

Каждому изображению соответствует плотная одноканальная карта глубины:

images/.../image.jpg -> <depths_dir>/.../image.png

Карта — одноканальный PNG или TIF либо .npy-файл, в разрешении изображения. Значения — обычная глубина в единицах, единых для датасета. Нулевые, отрицательные, NaN и бесконечные значения помечают невалидные пиксели и исключаются из функции потерь и метрик.

КлючПо умолчаниюОписание
depths_dirdepthsКаталог глубины, подставляемый вместо images
depth_stem_suffixСуффикс, добавляемый к имени файла изображения; если он не задан, проверяются и то же имя, и вариант с суффиксом _depth
depth_mask_suffix_maskСуффикс маски валидности; значения маски, равные нулю или меньше, а также NaN и бесконечности делают пиксель глубины невалидным
depth_scale256.0Делитель для карт глубины целочисленного типа, обычное соглашение для 16-битных PNG

Вещественные .npy-карты используются как есть и не применяют depth_scale.

Канонический загрузчик: libreyolo.data.DepthDataset.

edge

Каждому RGB-изображению соответствует одноканальная карта без потерь с тем же именем файла и необязательная маска валидности:

images/val/scene.jpg -> edges/val/scene.png
                     -> masks/val/scene.png

Карта — одноканальный PNG или TIF, а не RGB-визуализация, в разрешении изображения. Целочисленные карты делятся на максимум своего dtype; вещественные карты уже должны быть конечными и лежать в [0, 1]. 0 означает отсутствие края, а 1 — край. Пиксели необязательной маски валидны, когда они ненулевые. При изменении размера для целей и масок используется интерполяция по ближайшему соседу, а добавленные паддингом пиксели невалидны и не влияют на валидацию.

КлючПо умолчаниюОписание
edges_diredgesКаталог карт краёв, подставляемый вместо images
edge_stem_suffixСуффикс, добавляемый к именам файлов изображений
edge_extension.pngРасширение цели в формате без потерь
edge_invertЗадайте true, когда исходные карты хранят чёрные края на белом
masks_dirmasksНеобязательный каталог масок валидности
yaml
path: edge-dataset
train: images/train
val: images/val
edges_dir: edges
masks_dir: masks
nc: 1
names: {0: edge}

Валидация утончает непрерывные предсказания подавлением немаксимумов по градиенту в четырёх направлениях и выдаёт F-меры ODS и OIS по настраиваемому перебору порогов. Предсказанные и эталонные пиксели сопоставляются один к одному в пределах edge_max_dist * image_diagonal, с нормализованным допуском 0.0075 по умолчанию.

Канонический загрузчик: libreyolo.data.EdgeDataset. Загрузчик отвечает только за формат: он не скачивает и не распространяет данные бенчмарков.

normal

Каждому изображению соответствует трёхканальный 16-битный PNG с тем же именем файла, плюс необязательная маска валидности с тем же именем:

images/val/room.jpg -> normals/val/room.png
                    -> masks/val/room.png

PNG — строго трёхканальный uint16 с каналами, записанными как RGB, в разрешении изображения. Декодируется как n = png / 65535 * 2 - 1, после чего каждый вектор перенормируется. Декодированные векторы заданы в системе координат камеры OpenCV — +x вправо, +y вниз, +z вглубь сцены — и направлены к камере. Необязательная маска — одноканальный PNG, где ненулевое значение означает «валидно»; без маски валиден каждый конечный ненулевой декодированный вектор. Невалидные и добавленные паддингом пиксели цели представляются внутри как (0, 0, 0). При изменении размера три компоненты интерполируются билинейно и затем перенормируются, для масок валидности используется интерполяция по ближайшему соседу, а горизонтальное отражение ещё и меняет знак компоненты x.

КлючПо умолчаниюОписание
normals_dirnormalsКаталог карт нормалей, подставляемый вместо images
masks_dirmasksНеобязательный каталог масок валидности

Валидация выдаёт среднюю и медианную угловую ошибку в градусах и долю валидных пикселей в пределах 11.25, 22.5 и 30 градусов.

Канонический загрузчик: libreyolo.data.NormalDataset.

restore

Каждому искажённому входному изображению соответствует чистая RGB-цель:

inputs/.../image.jpg -> targets/.../image.jpg

Вход и цель — файлы изображений, совместимые с RGB, и их разрешения должны совпадать точно. Валидация сохраняет исходное разрешение и добавляет паддинг ровно настолько, чтобы собрать батч, а метрики считаются на исходном холсте изображения. При обучении к паре «вход — цель» применяются согласованные кроп и горизонтальное отражение.

КлючПо умолчаниюОписание
input_dirinputsКаталог искажённых входов, используемый в путях сплитов
target_dirtargetsКаталог чистых целей, подставляемый вместо input_dir
target_stem_suffixСуффикс, добавляемый к имени входного файла перед поиском цели
target_stem_suffixesСписочная форма target_stem_suffix
degradationМетка метаданных, например deblur или denoise
datasetМетка датасета или его происхождения

Поля YAML, связанные с классами, — заглушки схемы: используйте nc: 1 и names: {0: image}. Модели restore возвращают Results.restored, а не детекции.

Канонический загрузчик: libreyolo.data.RestoreDataset.

matte

Каждому RGB-изображению соответствует одноканальная эталонная карта маттинга с тем же именем файла, где 0 — фон, а 255 — передний план:

images/subject.jpg -> mattes/subject.png

Принимаются две раскладки. Корневой каталог с images/ и каталогом маттинга — он определяется автоматически среди mattes/, matte/, gt/, masks/, mask/ и alpha/, — который передаётся как data=. Либо YAML с path плюс val_images и val_mattes по сплитам, а также, при необходимости, train_images и train_mattes, каждый относительно path или абсолютный.

Карта маттинга хранится в градациях серого и читается как непрозрачность в [0, 1], а если формы различаются, она масштабируется до холста предсказания билинейной интерполяцией. Метрики — MAE и S-measure (Fan et al., ICCV 2017) на исходном холсте изображения, причём по S-measure выбирается лучший чекпойнт.

Поля YAML, связанные с классами, — заглушки схемы: используйте nc: 1 и names: {0: matte}. Модели matte возвращают Results.matte.

В этой версии валидация работает только в режиме инференса. Канонический резолвер пар: libreyolo.data.matte_dataset.resolve_matte_pairs.

ocr

Разметка — один JSONL-файл на сплит, по одному JSON-объекту на изображение:

images/val/receipt.jpg -> labels/val.jsonl
json
{"image": "receipt.jpg", "regions": [{"polygon": [[10, 12], [118, 14], [117, 40], [9, 38]], "text": "TOTAL 12.50"}]}

polygon — четырёхугольник из четырёх точек в абсолютных пиксельных координатах, в порядке: левый верхний, правый верхний, правый нижний, левый нижний. Области с нечитаемым текстом используют "text": "###" — соглашение ICDAR do-not-care: они исключаются из оценки распознавания, а предсказания, перекрывающие их, при сопоставлении детекций игнорируются, а не штрафуются.

Метрики — hmean детекции с взаимно однозначным сопоставлением полигонов при IoU выше 0.5; сквозной F1, требующий и IoU выше 0.5, и точного совпадения текста после NFKC-нормализации и удаления пробелов, с учётом регистра; и 1-NED на сопоставленных парах. Лучший чекпойнт выбирается по сквозному F1.

Принимаются две раскладки: корневой каталог с images/<split>/ и labels/<split>.jsonl, передаваемый как data=, либо YAML с path и необязательными именами каталогов images и labels.

Поля YAML, связанные с классами, — заглушки схемы: используйте nc: 1 и names: {0: text}. Модели OCR возвращают Results.ocr.

В этой версии валидация работает только в режиме инференса. Канонический резолвер примеров: libreyolo.data.ocr_dataset.resolve_ocr_samples.

classify

Дерево каталогов в стиле ImageFolder, а не файлы разметки:

dataset_root/
  train/
    class_a/*.jpg
    class_b/*.jpg
  val/
    class_a/*.jpg
    class_b/*.jpg

train/ обязателен для обучения и задаёт соответствие класса индексу по отсортированным именам папок. val/ обязателен для валидации. test/ может присутствовать, но команды обучения и валидации по умолчанию его не используют. Сплиты, отличные от обучающего, должны содержать те же имена папок классов, что и ожидаемый набор классов обучения или чекпойнта. Поддерживаемые расширения изображений заданы в libreyolo.data.classify_dataset.IMAGE_EXTENSIONS.

gaze и point

Для gaze контракт файлов датасета для обучения и валидации не реализован.

point — это задача на уровне вывода модели, а не схема разметки датасета. Семейства point могут внутренне адаптировать существующую разметку, например выводя центры объектов из строк с рамками, но текстовый формат разметки только для точек не определён.

Повторяет docs/dataset_schema.md из репозитория libreyolo на версии v1.5.0; имена загрузчиков сверены с libreyolo/data/.