Skip to main content

So konvertierst du COCO-Annotationen in das YOLO-Format

Das Training von Ultralytics YOLO-Modellen erfordert Annotationen im YOLO-Format, aber viele beliebte Annotation-Tools exportieren stattdessen im COCO JSON-Format. Dieser Leitfaden zeigt dir, wie du deine COCO-Annotationen in das YOLO-Format konvertierst und mit dem Training beginnst. Objekterkennungs, Instanzsegmentierung, und Pose-Schätzung Modellen feinabgestimmt.

Warum von COCO zu YOLO konvertieren?

Das COCO JSON-Format speichert alle Annotationen in einer einzigen Datei, während YOLO eine Textdatei pro Bild mit normalisierten Koordinaten verwendet. Die Konvertierung ist notwendig, weil:

  • YOLO-Modelle benötigen .txt Label-Dateien mit einer Datei pro Bild, die class x_center y_center width height in normalisierten Koordinaten enthalten.
  • COCO JSON verwendet das Pixel-Koordinaten in [x_min, y_min, width, height]-Format mit einer einzelnen JSON-Datei für alle Bilder.
  • Klassen-IDs unterscheiden sich — COCO verwendet beliebige category_id-Werte, während YOLO nullbasierte Klassen-IDs erfordert.
FunktionCOCO JSONYOLO TXT
StrukturEinzelne JSON-Datei für alle BilderEine .txt-Datei pro Bild
Bbox-Format[x_min, y_min, width, height] in Pixelnclass x_center y_center width height normalisiert (0-1)
Klassen-IDscategory_id (können bei einer beliebigen Zahl beginnen)Nullbasiert (beginnt bei 0)
SegmentationPolygon-Arrays im segmentation-FeldPolygon-Koordinaten nach der Klassen-ID
Keypoints[x, y, visibility, ...] in Pixeln[x, y, visibility, ...] normalisiert

Schnellstart

Der schnellste Weg, COCO-Annotationen zu konvertieren und das Training zu starten:

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
)

Nach der Konvertierung organisiere deine Verzeichnisstruktur, erstelle eine dataset.yaml, und starte das Training. Siehe den vollständigen Schritt-für-Schritt-Leitfaden unten.

Benutzerdefinierte Datensätze: verwende immer `cls91to80=False`

Die cls91to80=True Standard ist nur für das Standard-COCO Datensatz mit 80 Objektklassen konzipiert, das 91 nicht zusammenhängende Kategorie-IDs auf 80 zusammenhängende Klassen-IDs abbildet. Für jeden benutzerdefinierten Datensatz musst du musst setzen cls91to80=False — andernfalls werden deine Klassen-IDs stillschweigend falsch zugeordnet und dein Modell lernt falsche Klassen.

Schritt-für-Schritt-Konvertierungsanleitung

1. Bereite deinen COCO-Datensatz vor

Ein typischer Datensatz im COCO-Format, der aus Annotationstools exportiert wurde, hat folgende Struktur:

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

Jede JSON-Datei folgt der COCO-Datenformat-Spezifikation mit drei erforderlichen Feldern — images, annotations, und 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. Konvertiere Annotationen

Verwende den convert_coco()-Funktion, um deine COCO JSON-Annotationen in das YOLO-.txt-Format zu konvertieren:

Konvertiere COCO in das YOLO-Format
from ultralytics.data.converter import convert_coco

convert_coco(
    labels_dir="my_dataset/annotations/",
    save_dir="my_dataset/converted/",
    cls91to80=False,
)

3. Organisiere die Verzeichnisstruktur

Nach der Konvertierung müssen die Label-Dateien neben deinen Bildern platziert werden. YOLO erwartet ein labels/-Verzeichnis, das das images/-Verzeichnis spiegelt:

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

Dein endgültiges Datensatzstruktur sollte so aussehen:

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

4. Erstelle dataset.yaml

Eine dataset.yaml-Konfigurationsdatei, die deine COCO-Kategorien auf YOLO-Klassennamen abbildet. Diese Datei sagt YOLO, wo deine Daten liegen und welche Klassen erkannt werden sollen:

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)

Die resultierende YAML-Datei:

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

Weitere Details zum Dataset-YAML-Format findest du im Dataset-Konfigurationsleitfaden.

5. Trainiere dein YOLO-Modell

Sobald dein konvertierter Datensatz bereit ist, trainiere ein YOLO-Modell:

Trainiere auf konvertierten COCO-Daten
from ultralytics import YOLO

model = YOLO("yolo26n.pt")  # load a pretrained model
results = model.train(data="my_dataset/dataset.yaml", epochs=100, imgsz=640)

Für Trainingstipps und Best Practices siehe den Modell-Trainingsleitfaden.

6. Überprüfe deine Konvertierung

Bevor du trainierst, prüfe stichprobenartig einige Label-Dateien, um sicherzustellen, dass Klassen-IDs und Koordinaten korrekt sind:

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

Wenn du negative Klassen-IDs siehst, verwendet dein COCO JSON wahrscheinlich category_id, die bei 0 beginnen. Addiere 1 zu allen category_id-Werten in deinem JSON, bevor du convert_coco() ausführst, da es Klassen-IDs zuordnet als category_id - 1.

Fehlerbehebung bei häufigen Problemen

Falsche Klassen-IDs nach der Konvertierung

Wenn dein Modell trainiert, aber falsche Objektklassen erkennt, verwendest du wahrscheinlich cls91to80=True (Standard) für einen benutzerdefinierten Datensatz. Dies ordnet deine category_id-Werte über die COCO 91-zu-80-Lookup-Tabelle zu, was nur für den Standard COCO Datensatz.

Lösung: Verwende immer cls91to80=False für benutzerdefinierte Datensätze.

Keine Labels während des Trainings gefunden

Wenn das Training WARNING: No labels foundSAM 2.10 images, N backgrounds anzeigt, befinden sich deine Label-Dateien nicht im erwarteten Verzeichnis. convert_coco() speichert Labels in einem separaten Ausgabeverzeichnis (z. B. save_dir/labels/train/), aber YOLO erwartet labels/ parallel zu images/ innerhalb deines Dataset-Verzeichnisses.

Lösung: Verschiebe die Label-Dateien, um der erwarteten Verzeichnisstruktur zu entsprechen. Stelle sicher, dass labels/train/ ist ein Geschwisterelement von images/train/.

KeyError während der Konvertierung

Wenn du KeyError: 'bbox' oder ähnliche Fehler erhältst, während du convert_coco() ausführst, enthält dein labels_dir wahrscheinlich Nicht-Instanz-JSON-Dateien (z. B. captions_train2017.json), die eine abweichende Annotationsstruktur haben.

Lösung: Lege nur Instanz-Annotations-JSON-Dateien (z. B. instances_train2017.json) in den labels_dir.

Leere Label-Dateien nach der Konvertierung

Wenn die Konvertierung abgeschlossen ist, aber .txt-Dateien leer oder nicht vorhanden sind, haben möglicherweise alle Annotationen iscrowd: 1 (häufig bei SAM-generierten Masken) oder Bounding Boxes haben eine Breite oder Höhe von Null.

Lösung: Überprüfe deine JSON-Annotationen auf iscrowd-Werte. Wenn du SAM-Masken verwendest, bereite das JSON vor, um iscrowd: 0.

Lücken bei Klassen-IDs in konvertierten Labels

Wenn Klassen-IDs in Label-Dateien nicht fortlaufend sind (z. B. 0, 4, 9 anstatt 0, 1, 2), verwendet dein Annotationstool nicht fortlaufende category_id-Werte.

Lösung: Überprüfe, ob die Klassen-IDs in deinen .txt-Dateien mit dem names-Wörterbuch in dataset.yaml übereinstimmen. Weise die IDs bei Bedarf neu zu, um sie fortlaufend zu machen.

Für vollständige API-Details und Parameterbeschreibungen siehe die convert_coco API-Referenz.

FAQ

Wie konvertiere ich COCO JSON-Annotationen in das YOLO-Format?

Verwende den convert_coco()-Funktion von Ultralytics, um COCO JSON-Annotationen in das YOLO-.txt-Format zu konvertieren. Setze cls91to80=False für benutzerdefinierte Datensätze:

from ultralytics.data.converter import convert_coco

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

Organisiere nach der Konvertierung deine Label-Dateien so, dass labels/ das images/-Verzeichnis widerspiegelt, und erstelle dann eine dataset.yaml-Datei. Siehe das Schritt-für-Schritt-Leitfaden für den vollständigen Arbeitsablauf.

Warum zeigt das YOLO-Training nach der COCO-Konvertierung "No labels found" an?

Dies passiert, weil convert_coco() Labels in einem Unterverzeichnis innerhalb von save_dir/labels/ (z. B. save_dir/labels/train/) speichert, anstatt direkt in das labels/train/ zusammen mit images/train/ deines Datensatzes. YOLO erwartet, dass Labels parallel zu den Bildern liegen – zum Beispiel benötigt images/train/img.jpg ein labels/train/img.txt. Verschiebe deine konvertierten Labels, damit diese Struktur übereinstimmt. Siehe Anpassung der Verzeichnisstruktur.

Was macht cls91to80 in convert_coco()?

Die cls91to80 Der Parameter steuert, wie COCO category_id-Werte auf YOLO-Klassen-IDs gemappt werden. Wenn True (Standard), wird eine Lookup-Tabelle verwendet, die für den Standard-COCO Datensatz ausgelegt ist, welcher 80 Klassen mit nicht fortlaufenden IDs (1-90) besitzt. Für benutzerdefinierten Datensätzen, setze immer cls91to80=False – dies subtrahiert einfach 1 von jeder category_id, um nullbasierte Klassen-IDs zu erstellen.

Kann ich YOLO direkt mit COCO JSON trainieren, ohne zu konvertieren?

Nicht mit der aktuellen YOLO-Trainings-Pipeline – Annotationen müssen im YOLO-.txt-Format mit einer Datei pro Bild vorliegen. Nutze convert_coco(), um zuerst dein COCO JSON zu konvertieren, und folge dann dieser guide, um die Daten zu organisieren und zu trainieren. Für mehr Informationen zu unterstützten Formaten siehe Datensatz-Formate.

Kann ich COCO-Segmentierungs-Annotationen in das YOLO-Format konvertieren?

Ja, verwende use_segments=True beim Aufruf von convert_coco(), um Polygon-Segmentierungsmasken in die konvertierten YOLO-Labels einzuschließen. Dies erzeugt Label-Dateien, die kompatibel mit YOLO-Segmentierungsmodellen sind.:

from ultralytics.data.converter import convert_coco

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

Wie konvertiere ich COCO-Keypoint-Annotationen in das YOLO-Format?

Verwende use_keypoints=True, um COCO-Keypoint-Annotationen für das Pose-Schätzung-Training zu konvertieren:

from ultralytics.data.converter import convert_coco

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

Beachte, dass wenn sowohl use_segments und use_keypoints auf True gesetzt sind, nur Keypoints in die Label-Dateien geschrieben werden – Segmente werden stillschweigend ignoriert.

Kommentare