Как преобразовать аннотации COCO в формат YOLO
Для обучения моделей Ultralytics YOLO требуются аннотации в формате YOLO, но многие популярные инструменты аннотирования экспортируют их в формате COCO JSON. Это руководство покажет, как конвертировать ваши аннотации COCO в формат YOLO и начать обучение моделей object detection, instance segmentation и pose estimation.
Зачем преобразовывать из COCO в YOLO?
Формат COCO JSON хранит все аннотации в одном файле, в то время как YOLO использует один текстовый файл на изображение с нормализованными координатами. Конвертация необходима, потому что:
- Моделям YOLO требуются
.txtфайлы меток с одним файлом на изображение, содержащимclass x_center y_center width heightв нормализованных координатах. - COCO JSON использует пиксельные координаты в
[x_min, y_min, width, height]формат с одним JSON-файлом для всех изображений. - Идентификаторы классов различаются — COCO использует произвольные
category_idзначения, в то время как YOLO требует идентификаторы классов с нулевым индексом.
| Функциональность | COCO JSON | YOLO TXT |
|---|---|---|
| Структура | Один JSON-файл для всех изображений | Один .txt файл на изображение |
| Формат Bbox | [x_min, y_min, width, height] в пикселях | class x_center y_center width height нормализованный (0-1) |
| Идентификаторы классов | category_id (могут начинаться с любого числа) | С нулевым индексом (начинается с 0) |
| Сегментация | Массивы полигонов в segmentation поле | Координаты полигона после ID класса |
| Ключевые точки | [x, y, visibility, ...] в пикселях | [x, y, visibility, ...] нормализованный |
Быстрый старт
Самый быстрый способ конвертировать аннотации COCO и начать обучение:
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="path/to/annotations/", # directory containing your JSON files
save_dir="path/to/output/", # where to save converted labels
cls91to80=False, # IMPORTANT: set False for custom datasets
)
После конвертации организуйте структуру каталогов, создайте dataset.yaml и начните обучение. Полное пошаговое руководство см. ниже.
Пользовательские наборы данных: всегда используйте cls91to80=False
Параметр cls91to80=True по умолчанию разработан только для стандартного Набор данных COCO с 80 классами объектов, который сопоставляет 91 несмежный ID категории с 80 смежными ID классов. Для любого пользовательского набора данных вы должны установить cls91to80=False — иначе ID ваших классов будут некорректно сопоставлены без уведомления, и ваша модель будет обучаться на неверных классах.
Пошаговое руководство по преобразованию
1. Подготовьте ваш набор данных COCO
Типичный набор данных в формате COCO, экспортированный из инструментов аннотирования, имеет следующую структуру:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ └── val/
│ ├── img_100.jpg
│ └── ...
└── annotations/
├── instances_train.json
└── instances_val.json
Каждый JSON-файл соответствует формату данных COCO спецификации с тремя обязательными полями — images, annotationsи categories:
{
"images": [{ "id": 1, "file_name": "img_001.jpg", "width": 640, "height": 480 }],
"annotations": [
{
"id": 1,
"image_id": 1,
"category_id": 1,
"bbox": [100, 50, 200, 150],
"area": 30000,
"iscrowd": 0
}
],
"categories": [
{ "id": 1, "name": "helmet" },
{ "id": 2, "name": "vest" }
]
}
2. Преобразуйте аннотации
Используйте convert_coco() функция для конвертации ваших JSON-аннотаций COCO в YOLO .txt формат:
Конвертировать COCO в формат YOLO
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
cls91to80=False,
)
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
use_segments=True,
cls91to80=False,
)
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
use_keypoints=True,
cls91to80=False,
)
3. Организуйте структуру каталогов
После конвертации файлы меток должны быть размещены рядом с вашими изображениями. YOLO ожидает labels/ каталог, который зеркально отображает images/ каталог:
import shutil
from pathlib import Path
# Paths
converted_dir = Path("my_dataset/converted/labels")
dataset_dir = Path("my_dataset")
# Move labels next to images for each split
for split in ["train", "val"]:
src = converted_dir / split # convert_coco strips "instances_" prefix from JSON filename
dst = dataset_dir / "labels" / split
dst.mkdir(parents=True, exist_ok=True)
for f in src.glob("*.txt"):
shutil.move(str(f), str(dst / f.name))
Ваша окончательная структура набора данных должна выглядеть так:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ └── ...
│ └── val/
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img_001.txt
│ │ └── ...
│ └── val/
│ └── ...
└── dataset.yaml
4. Создайте файл dataset.yaml
Создайте dataset.yaml файл конфигурации, который сопоставляет ваши категории COCO с именами классов YOLO. Этот файл сообщает YOLO, где находятся ваши данные и какие классы detect:
import json
from pathlib import Path
import yaml
# Read categories from your COCO JSON
with open("my_dataset/annotations/instances_train.json") as f:
coco = json.load(f)
# Build class names matching convert_coco output (category_id - 1)
categories = sorted(coco["categories"], key=lambda x: x["id"])
names = {cat["id"] - 1: cat["name"] for cat in categories}
# NOTE: convert_coco maps class IDs as category_id - 1, so category_id must
# start from 1. If your categories start from 0, add 1 to each ID first.
# Create dataset.yaml
dataset = {
"path": str(Path("my_dataset").resolve()),
"train": "images/train",
"val": "images/val",
"names": names,
}
with open("my_dataset/dataset.yaml", "w") as f:
yaml.dump(dataset, f, default_flow_style=False)
Полученный YAML-файл:
path: /absolute/path/to/my_dataset
train: images/train
val: images/val
names:
0: helmet
1: vest
Более подробную информацию о формате YAML набора данных см. в руководстве по конфигурации набора данных.
5. Обучите вашу модель YOLO
Когда ваш конвертированный набор данных готов, обучите модель YOLO:
Обучение на конвертированных данных COCO
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load a pretrained model
results = model.train(data="my_dataset/dataset.yaml", epochs=100, imgsz=640)
yolo detect train model=yolo26n.pt data=my_dataset/dataset.yaml epochs=100 imgsz=640
Советы и лучшие практики по обучению см. в руководстве по обучению моделей.
6. Проверьте ваше преобразование
Перед обучением выборочно проверьте несколько файлов меток, чтобы убедиться в правильности идентификаторов классов и координат:
from pathlib import Path
label_file = Path("my_dataset/labels/train/img_001.txt")
for line in label_file.read_text().strip().splitlines():
parts = line.split()
cls_id = int(parts[0])
coords = [float(v) for v in parts[1:5]]
assert cls_id >= 0, f"Negative class ID {cls_id} — category_id in your JSON may start from 0"
assert all(0 <= v <= 1 for v in coords), f"Coordinates out of [0, 1] range: {coords}"
Совет
Если вы видите отрицательные идентификаторы классов, ваш JSON COCO, вероятно, использует category_id начиная с 0. Добавьте 1 ко всем category_id значениям в вашем JSON перед запуском convert_coco(), поскольку он сопоставляет идентификаторы классов как category_id - 1.
Устранение распространенных проблем
Неправильные идентификаторы классов после преобразования
Если ваша модель обучается, но обнаруживает неверные классы объектов, вы, вероятно, используете cls91to80=True (по умолчанию) на пользовательском наборе данных. Это сопоставляет ваши category_id значения через таблицу соответствия COCO 91-к-80, которая верна только для стандартного Набор данных COCO.
Решение: Всегда используйте cls91to80=False для пользовательских наборов данных.
Метки не найдены во время обучения
Если обучение показывает WARNING: No labels found или 0 images, N backgrounds, ваши файлы меток находятся не в ожидаемом каталоге. convert_coco() сохраняет метки в отдельный выходной каталог (например, save_dir/labels/train/), но YOLO ожидает labels/ параллельно с images/ внутри каталога вашего набора данных.
Решение: Переместите файлы меток, чтобы они соответствовали ожидаемой структуре каталогов. Убедитесь, что labels/train/ является родственным по отношению к images/train/.
KeyError во время преобразования
Если вы получите KeyError: 'bbox' или аналогичные ошибки при запуске convert_coco(), ваш labels_dir вероятно, содержит JSON-файлы, не относящиеся к экземплярам (например, captions_train2017.json) с другой структурой аннотаций.
Решение: Размещайте только JSON-файлы аннотаций экземпляров (например, instances_train2017.json) в каталоге labels_dir.
Пустые файлы меток после преобразования
Если преобразование завершено, но .txt файлы пусты или отсутствуют, все аннотации могут иметь iscrowd: 1 (часто встречается с SAM-сгенерированными масками) или ограничивающие рамки имеют нулевую ширину или высоту.
Решение: Проверьте ваши JSON-аннотации на наличие iscrowd значений. Если используются маски SAM, предварительно обработайте JSON, чтобы установить iscrowd: 0.
Пробелы в идентификаторах классов в преобразованных метках
Если идентификаторы классов в файлах меток не являются последовательными (например, 0, 4, 9 вместо 0, 1, 2), ваш инструмент аннотирования использует непоследовательные category_id значения.
Решение: Убедитесь, что идентификаторы классов в ваших .txt файлах соответствуют names в dataset.yaml. При необходимости переназначьте идентификаторы на последовательные значения.
Полную информацию об API и описания параметров см. в convert_coco справочнике API.
Часто задаваемые вопросы
Как мне преобразовать аннотации COCO JSON в формат YOLO?
Используйте convert_coco() функции Ultralytics для преобразования аннотаций COCO JSON в формат YOLO .txt формат. Установите cls91to80=False для пользовательских наборов данных:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)
После преобразования реорганизуйте файлы меток так, чтобы labels/ отражал структуру images/ каталога, затем создайте файл dataset.yaml . См. пошаговое руководство для полного рабочего процесса.
Почему обучение YOLO показывает "Метки не найдены" после преобразования COCO?
Это происходит потому, что convert_coco() сохраняет метки во вложенную директорию внутри save_dir/labels/ (например, save_dir/labels/train/), а не непосредственно в директорию вашего набора данных labels/train/ наряду с images/train/. YOLO ожидает, что метки будут находиться параллельно изображениям — например, images/train/img.jpg требует labels/train/img.txt. Переместите преобразованные метки, чтобы они соответствовали этой структуре. См. исправление структуры каталогов.
Что делает cls91to80 в convert_coco()?
Параметр cls91to80 параметр управляет тем, как значения COCO category_id сопоставляются с идентификаторами классов YOLO. Когда True (по умолчанию), он использует таблицу поиска, разработанную для стандартного Набор данных COCO, который имеет 80 классов с несмежными идентификаторами (1-90). Для пользовательских наборов данных, всегда устанавливайте cls91to80=False — это просто вычитает 1 из каждого category_id , чтобы создать идентификаторы классов с нулевым индексом.
Могу ли я обучать YOLO напрямую на COCO JSON без конвертации?
Не с текущим конвейером обучения YOLO — аннотации должны быть в формате YOLO .txt с одним файлом на изображение. Используйте convert_coco() , чтобы сначала преобразовать ваш COCO JSON, затем следуйте этому руководству , чтобы организовать и обучить. Для получения дополнительной информации о поддерживаемых форматах см. форматы наборов данных.
Могу ли я конвертировать аннотации сегментации COCO в формат YOLO?
Да, используйте use_segments=True при вызове convert_coco() для включения полигональных масок сегментации в преобразованные метки YOLO. Это позволяет создавать файлы меток, совместимые с моделями сегментации YOLO:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_segments=True, cls91to80=False)
Как конвертировать аннотации ключевых точек COCO в формат YOLO?
Используйте use_keypoints=True для преобразования аннотаций ключевых точек COCO для оценка позы обучения:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)
Обратите внимание, что если оба use_segments и use_keypoints установлены в True, в файлы меток будут записаны только ключевые точки — сегменты будут молчаливо проигнорированы.