Ir al contenido

Cómo convertir anotaciones COCO a formato YOLO

El entrenamiento de modelos Ultralytics YOLO requiere anotaciones en formato YOLO, pero muchas herramientas de anotación populares exportan en formato COCO JSON. Esta guía le muestra cómo convertir sus anotaciones de COCO a formato YOLO y comenzar a entrenar modelos de detección de objetos, segmentación de instancias y estimación de pose.

¿Por qué convertir de COCO a YOLO?

El formato COCO JSON almacena todas las anotaciones en un solo archivo, mientras que YOLO utiliza un archivo de texto por imagen con coordenadas normalizadas. La conversión es necesaria porque:

  • Los modelos YOLO requieren .txt archivos de etiquetas con un archivo por imagen, que contiene class x_center y_center width height en coordenadas normalizadas.
  • COCO JSON utiliza coordenadas de píxeles en [x_min, y_min, width, height] formato con un único archivo JSON para todas las imágenes.
  • Los IDs de clase difieren — COCO utiliza category_id valores arbitrarios, mientras que YOLO requiere IDs de clase con índice cero.
CaracterísticaCOCO JSONYOLO TXT
EstructuraArchivo JSON único para todas las imágenesUno .txt archivo por imagen
Formato de Bbox[x_min, y_min, width, height] en píxelesclass x_center y_center width height normalizado (0-1)
IDs de Clasecategory_id (pueden empezar desde cualquier número)Con índice cero (empieza desde 0)
SegmentaciónArrays de polígonos en segmentation campoCoordenadas de polígono después del ID de clase
Puntos clave[x, y, visibility, ...] en píxeles[x, y, visibility, ...] normalizado

Inicio rápido

La forma más rápida de convertir anotaciones COCO y empezar a entrenar:

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
)

Después de la conversión, organice la estructura de su directorio, cree un dataset.yaml y empiece a entrenar. Consulte la guía completa paso a paso a continuación.

Conjuntos de datos personalizados: utilice siempre cls91to80=False

El cls91to80=True el predeterminado está diseñado solo para el flujo de trabajo estándar Conjunto de datos COCO con 80 clases de objetos, que mapea 91 IDs de categoría no contiguos a 80 IDs de clase contiguos. Para cualquier conjunto de datos personalizado, usted debe establecer cls91to80=False — de lo contrario, sus IDs de clase se mapearán incorrectamente de forma silenciosa y su modelo aprenderá clases erróneas.

Guía de conversión paso a paso

1. Prepare su conjunto de datos COCO

Un conjunto de datos típico en formato COCO exportado desde herramientas de anotación tiene la siguiente estructura:

my_dataset/
├── images/
│   ├── train/
│   │   ├── img_001.jpg
│   │   ├── img_002.jpg
│   │   └── ...
│   └── val/
│       ├── img_100.jpg
│       └── ...
└── annotations/
    ├── instances_train.json
    └── instances_val.json

Cada archivo JSON sigue la formato de datos COCO especificación con tres campos obligatorios — images, annotations, y 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. Convertir anotaciones

Utilice el convert_coco() función para convertir sus anotaciones JSON de COCO a YOLO .txt formato:

Convertir COCO a formato 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. Organizar la estructura de directorios

Después de la conversión, los archivos de etiquetas deben colocarse junto a sus imágenes. YOLO espera un labels/ directorio que refleja el images/ directorio:

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))

La estructura final de su conjunto de datos debería ser similar a:

my_dataset/
├── images/
│   ├── train/
│   │   ├── img_001.jpg
│   │   └── ...
│   └── val/
│       └── ...
├── labels/
│   ├── train/
│   │   ├── img_001.txt
│   │   └── ...
│   └── val/
│       └── ...
└── dataset.yaml

4. Crear dataset.yaml

Crea un dataset.yaml archivo de configuración que mapea sus categorías COCO a nombres de clase YOLO. Este archivo le indica a YOLO dónde están sus datos y qué clases debe 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)

El archivo YAML resultante:

path: /absolute/path/to/my_dataset
train: images/train
val: images/val
names:
    0: helmet
    1: vest

Para más detalles sobre el formato YAML del conjunto de datos, consulte la guía de configuración del conjunto de datos.

5. Entrenar su modelo YOLO

Con su conjunto de datos convertido listo, entrene un modelo YOLO:

Entrenar con datos COCO convertidos

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

Para consejos de entrenamiento y mejores prácticas, consulte la guía de entrenamiento de modelos.

6. Verificar su conversión

Antes de entrenar, verifique algunos archivos de etiquetas para confirmar que los IDs de clase y las coordenadas sean correctos:

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}"

Consejo

Si ve IDs de clase negativos, es probable que su JSON COCO utilice category_id comenzando desde 0. Agregue 1 a todos los category_id valores en su JSON antes de ejecutar convert_coco(), ya que mapea los IDs de clase como category_id - 1.

Solución de problemas comunes

ID de clase incorrectos después de la conversión

Si su modelo entrena pero detects clases de objetos incorrectas, es probable que esté utilizando cls91to80=True (por defecto) en un conjunto de datos personalizado. Esto mapea sus category_id valores a través de la tabla de búsqueda COCO de 91 a 80, lo cual solo es correcto para el estándar Conjunto de datos COCO.

Solución: Utilice siempre cls91to80=False para conjuntos de datos personalizados.

No se encontraron etiquetas durante el entrenamiento

Si el entrenamiento muestra WARNING: No labels found o 0 images, N backgrounds, sus archivos de etiquetas no están en el directorio esperado. convert_coco() guarda las etiquetas en un directorio de salida separado (p. ej., save_dir/labels/train/), pero YOLO espera labels/ paralelo a images/ dentro de su directorio de conjunto de datos.

Solución: Mueva los archivos de etiquetas para que coincidan con la estructura esperada de directorios. Asegúrese de que labels/train/ sea un hermano de images/train/.

KeyError durante la conversión

Si obtiene KeyError: 'bbox' o errores similares al ejecutar convert_coco(), su labels_dir probablemente contiene archivos JSON que no son de instancia (p. ej., captions_train2017.json) que tienen una estructura de anotación diferente.

Solución: Solo coloque archivos JSON de anotación de instancia (p. ej., instances_train2017.json) en el directorio labels_dir.

Archivos de etiquetas vacíos después de la conversión

Si la conversión se completa pero los .txt archivos están vacíos o faltan, es posible que todas las anotaciones tengan iscrowd: 1 (común con máscaras generadas por SAM), o cajas delimitadoras tengan ancho o alto cero.

Solución: Inspeccione sus anotaciones JSON en busca de valores iscrowd . Si utiliza máscaras SAM, preprocese el JSON para establecer iscrowd: 0.

Brechas en los ID de clase en las etiquetas convertidas

Si los IDs de clase en los archivos de etiquetas no son contiguos (p. ej., 0, 4, 9 en lugar de 0, 1, 2), su herramienta de anotación utiliza valores category_id no contiguos.

Solución: Verifique que los IDs de clase en sus archivos .txt coincidan con el names diccionario en dataset.yaml. Reasigne los IDs a valores contiguos si es necesario.

Para obtener detalles completos de la API y descripciones de parámetros, consulte la convert_coco referencia de la API.

Preguntas frecuentes

¿Cómo convierto anotaciones JSON de COCO a formato YOLO?

Utilice el convert_coco() función de Ultralytics para convertir anotaciones JSON de COCO a formato YOLO .txt . Establezca cls91to80=False para conjuntos de datos personalizados:

from ultralytics.data.converter import convert_coco

convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)

Después de la conversión, reorganice sus archivos de etiquetas para que el directorio de labels/ refleje el directorio de images/ , luego cree un archivo dataset.yaml . Consulte la guía paso a paso para el flujo de trabajo completo.

¿Por qué el entrenamiento de YOLO muestra "No se encontraron etiquetas" después de la conversión de COCO?

Esto ocurre porque convert_coco() guarda las etiquetas en un subdirectorio dentro de save_dir/labels/ (p. ej., save_dir/labels/train/) en lugar de directamente en el de su conjunto de datos labels/train/ junto con images/train/. YOLO espera que las etiquetas se encuentren paralelas a las imágenes; por ejemplo, images/train/img.jpg necesita labels/train/img.txt. Mueva sus etiquetas convertidas para que coincidan con esta estructura. Consulte corrección de la estructura de directorios.

¿Qué hace cls91to80 en convert_coco()?

El cls91to80 parámetro controla cómo los valores de COCO category_id se mapean a los IDs de clase de YOLO. Cuando True (predeterminado), utiliza una tabla de búsqueda diseñada para el estándar Conjunto de datos COCO, que tiene 80 clases con IDs no contiguos (1-90). Para conjuntos de datos personalizados, siempre establezca cls91to80=False — esto simplemente resta 1 a cada category_id para crear IDs de clase con índice cero.

¿Puedo entrenar YOLO directamente con COCO JSON sin convertir?

No con el pipeline de entrenamiento actual de YOLO — las anotaciones deben estar en formato YOLO .txt con un archivo por imagen. Utilice convert_coco() para convertir su JSON de COCO primero, luego siga esta guía para organizar y entrenar. Para más información sobre los formatos compatibles, consulte formatos de conjuntos de datos.

¿Puedo convertir las anotaciones de segmentación de COCO a formato YOLO?

Sí, utilice use_segments=True al llamar convert_coco() para incluir máscaras de segmentación poligonal en las etiquetas YOLO convertidas. Esto produce archivos de etiquetas compatibles con modelos de segmentación YOLO:

from ultralytics.data.converter import convert_coco

convert_coco(labels_dir="annotations/", save_dir="output/", use_segments=True, cls91to80=False)

¿Cómo convierto las anotaciones de puntos clave de COCO a formato YOLO?

Utilice use_keypoints=True para convertir anotaciones de puntos clave COCO para estimación de pose entrenamiento:

from ultralytics.data.converter import convert_coco

convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)

Tenga en cuenta que si ambos use_segments y use_keypoints están configurados en True, solo se escribirán los puntos clave en los archivos de etiquetas — los segment se ignoran silenciosamente.



📅 Creado hace 7 días ✏️ Actualizado hace 6 días
dependabotraimbekovm

Comentarios