So konvertierst du COCO-Annotationen in das YOLO-Format
Das Trainieren von Ultralytics YOLO-Modellen erfordert Annotationen im YOLO-Format, aber viele beliebte Annotationstools exportieren stattdessen im COCO JSON-Format. Dieser Leitfaden zeigt dir, wie du deine COCO-Annotationen in das YOLO-Format konvertierst und mit dem Training von Objekterkennungs-, Instanzsegmentierungs- und Pose-Estimation-Modellen beginnst.
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. Eine Konvertierung ist aus folgenden Gründen notwendig:
- YOLO-Modelle benötigen
.txt-Label-Dateien, eine Datei pro Bild, mit dem Inhaltclass x_center y_center width heightin normalisierten Koordinaten. - COCO JSON verwendet Pixelkoordinaten im Format
[x_min, y_min, width, height]in einer einzigen JSON-Datei für alle Bilder. - Klassen-IDs unterscheiden sich — COCO verwendet beliebige
category_id-Werte, während YOLO nullbasierte Klassen-IDs erfordert.
| Funktion | COCO JSON | YOLO TXT |
|---|---|---|
| Struktur | Einzelne JSON-Datei für alle Bilder | Eine .txt-Datei pro Bild |
| Bbox-Format | [x_min, y_min, width, height] in Pixeln | class x_center y_center width height normalisiert (0-1) |
| Klassen-IDs | category_id (kann mit einer beliebigen Zahl beginnen) | Nullbasiert (beginnt bei 0) |
| Segmentierung | Polygon-Arrays im Feld segmentation | Polygon-Koordinaten nach der Klassen-ID |
| Keypoints | [x, y, visibility, ...] in Pixeln | [x, y, visibility, ...] normalisiert |
Schnellstart
Der schnellste Weg, um COCO-Annotationen zu konvertieren und mit dem Training zu beginnen:
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 organisierst du deine Verzeichnisstruktur, erstellst eine dataset.yaml und startest das Training. Siehe den vollständigen Schritt-für-Schritt-Leitfaden unten.
Die Standardeinstellung cls91to80=True ist nur für den Standard-COCO-Datensatz mit 80 Objektklassen konzipiert, der 91 nicht zusammenhängende Kategorie-IDs auf 80 zusammenhängende Klassen-IDs abbildet. Für jeden benutzerdefinierten Datensatz musst du cls91to80=False setzen — andernfalls werden deine Klassen-IDs im Hintergrund falsch gemappt 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.jsonJede JSON-Datei folgt der Spezifikation des COCO-Datenformats 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 die Funktion convert_coco(), um deine COCO JSON-Annotationen in das YOLO .txt-Format zu konvertieren:
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 widerspiegelt:
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))Deine finale Datensatzstruktur sollte so aussehen:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ └── ...
│ └── val/
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img_001.txt
│ │ └── ...
│ └── val/
│ └── ...
└── dataset.yaml4. Erstelle dataset.yaml
Erstelle eine dataset.yaml-Konfigurationsdatei, die deine COCO-Kategorien auf YOLO-Klassennamen abbildet. Diese Datei sagt YOLO, wo deine Daten sind 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: vestWeitere Details zum Datensatz-YAML-Format findest du im Datensatz-Konfigurationsleitfaden.
5. Trainiere dein YOLO-Modell
Sobald dein konvertierter Datensatz bereit ist, trainiere ein YOLO-Modell:
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load a pretrained model
results = model.train(data="my_dataset/dataset.yaml", epochs=100, imgsz=640)Tipps für das Training und Best Practices findest du im Modell-Trainingsleitfaden.
6. Überprüfe deine Konvertierung
Überprüfe vor dem Training 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}"Wenn du negative Klassen-IDs siehst, verwendet dein COCO JSON wahrscheinlich eine category_id, die bei 0 beginnt. Addiere 1 zu allen category_id-Werten in deinem JSON, bevor du convert_coco() ausführst, da es Klassen-IDs als category_id - 1 abbildet.
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 bildet deine category_id-Werte über die COCO-Lookup-Tabelle 91-zu-80 ab, was nur für den Standard-COCO-Datensatz korrekt ist.
Lösung: Verwende für benutzerdefinierte Datensätze immer cls91to80=False.
Keine Labels während des Trainings gefunden
Wenn das Training WARNING: No labels found oder 0 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 Datensatzverzeichnisses.
Lösung: Verschiebe die Label-Dateien, damit sie der erwarteten Verzeichnisstruktur entsprechen. Stelle sicher, dass labels/train/ ein Geschwisterverzeichnis von images/train/ ist.
KeyError während der Konvertierung
Wenn du KeyError: 'bbox' oder ähnliche Fehler beim Ausführen von convert_coco() erhältst, enthält dein labels_dir wahrscheinlich JSON-Dateien, die keine Instanzdaten enthalten (z. B. captions_train2017.json), welche eine andere Annotationsstruktur aufweisen.
Lösung: Platziere nur JSON-Dateien mit Instanzannotationen (z. B. instances_train2017.json) im labels_dir.
Leere Label-Dateien nach der Konvertierung
Wenn die Konvertierung abgeschlossen ist, aber .txt-Dateien leer oder fehlend sind, haben möglicherweise alle Annotationen iscrowd: 1 (häufig bei SAM-generierten Masken) oder Bounding Boxen 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 so vor, dass iscrowd: 0 gesetzt ist.
Lücken in den Klassen-IDs in konvertierten Labels
Wenn Klassen-IDs in Label-Dateien nicht zusammenhängend sind (z. B. 0, 4, 9 statt 0, 1, 2), verwendet dein Annotationstool nicht zusammenhängende category_id-Werte.
Lösung: Überprüfe, ob die Klassen-IDs in deinen .txt-Dateien mit dem names-Wörterbuch in dataset.yaml übereinstimmen. Bilde die IDs bei Bedarf auf zusammenhängende Werte ab.
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 die Funktion convert_coco() 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)Nach der Konvertierung ordnest du deine Label-Dateien so um, dass labels/ das images/-Verzeichnis widerspiegelt, und erstellst dann eine dataset.yaml-Datei. Siehe den Schritt-für-Schritt-Leitfaden für den gesamten 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/ speichert (z. B. save_dir/labels/train/) und nicht direkt in das labels/train/ deines Datensatzes neben images/train/. 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, um dieser Struktur zu entsprechen. Siehe Korrektur der Verzeichnisstruktur.
Was bewirkt cls91to80 in convert_coco()?
Der Parameter cls91to80 steuert, wie COCO-category_id-Werte auf YOLO-Klassen-IDs abgebildet werden. Wenn True (Standard), verwendet es eine Lookup-Tabelle für den Standard-COCO-Datensatz, der 80 Klassen mit nicht zusammenhängenden IDs (1-90) hat. Setze für benutzerdefinierte Datensätze immer cls91to80=False — dies subtrahiert einfach 1 von jeder category_id, um nullbasierte Klassen-IDs zu erstellen.
Kann ich YOLO direkt auf COCO JSON trainieren, ohne zu konvertieren?
Nicht mit der aktuellen YOLO-Trainingspipeline — Annotationen müssen im YOLO .txt-Format mit einer Datei pro Bild vorliegen. Verwende zuerst convert_coco(), um dein COCO JSON zu konvertieren, und folge dann dieser Anleitung, um alles zu organisieren und zu trainieren. Weitere Informationen zu unterstützten Formaten findest du unter Datensatzformate.
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 aufzunehmen. Dies erzeugt Label-Dateien, die mit YOLO-Segmentierungsmodellen kompatibel 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 Training von Pose Estimation 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 als auch use_keypoints auf True gesetzt sind, nur Keypoints in die Label-Dateien geschrieben werden — Segmente werden ignoriert.