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
.txtLabel-Dateien mit einer Datei pro Bild, dieclass x_center y_center width heightin 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.
| 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 (können bei einer beliebigen Zahl beginnen) | Nullbasiert (beginnt bei 0) |
| Segmentation | Polygon-Arrays im segmentation-Feld | Polygon-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.
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.jsonJede 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:
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.yaml4. 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: vestWeitere 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:
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}"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.