Comment convertir les annotations COCO au format YOLO
L'entraînement de modèles Ultralytics YOLO nécessite des annotations au format YOLO, mais de nombreux outils d'annotation populaires exportent au format COCO JSON au lieu de cela. Ce guide te montre comment convertir tes annotations COCO au format YOLO et commencer l'entraînement de object detection, la segmentation d'instances, et la , l'estimation de pose, le bien entraînés.
Pourquoi convertir de COCO vers YOLO ?
Le format COCO JSON stocke toutes les annotations dans un seul fichier, tandis que YOLO utilise un fichier texte par image avec des coordonnées normalisées. La conversion est nécessaire car :YOLOLes modèles YOLO nécessitent des
- YOLO models require
.txtfichiers d'étiquettes avec un fichier par image, contenant desclass x_center y_center width heighten coordonnées normalisées. - COCO JSON utilise le format de coordonnées en pixels dans
[x_min, y_min, width, height]avec un seul fichier JSON pour toutes les images. - Les IDs de classe diffèrent — COCO utilise des valeurs
category_idarbitraires, tandis que YOLO nécessite des IDs de classe indexés à partir de zéro.
| Fonctionnalité | COCO JSON | YOLO TXT |
|---|---|---|
| Structure | Un seul fichier JSON pour toutes les images | Un fichier .txt par image |
| Format Bbox | [x_min, y_min, width, height] en pixels | class x_center y_center width height normalisé (0-1) |
| IDs de classe | category_id (peuvent commencer à partir de n'importe quel nombre) | Indexés à partir de zéro (commencent à 0) |
| Segmentation | Tableaux de polygones dans le champ segmentation field | Coordonnées de polygone après l'ID de classe |
| Keypoints | [x, y, visibility, ...] en pixels | [x, y, visibility, ...] normalisées |
Démarrage rapide
La méthode la plus rapide pour convertir les annotations COCO et commencer l'entraînement :
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
)Après la conversion, organise ta structure de répertoire, crée un dataset.yaml, et la commence l'entraînement. Consulte le guide étape par étape complet ci-dessous.
La méthode cls91to80=True la valeur par défaut est conçue uniquement pour le jeu de données COCO standard avec 80 classes d'objets, qui mappe 91 IDs de catégorie non contigus vers 80 IDs de classe contigus. Pour tout jeu de données personnalisé, tu dois définir dois set cls91to80=False — sinon tes IDs de classe seront incorrectement mappés silencieusement et ton modèle apprendra de mauvaises classes.
Guide de conversion étape par étape
1. Prépare ton jeu de données COCO
Un jeu de données au format COCO typique exporté depuis des outils d'annotation a la structure suivante :
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ └── val/
│ ├── img_100.jpg
│ └── ...
└── annotations/
├── instances_train.json
└── instances_val.jsonChaque fichier JSON suit la spécification du COCO data format avec trois champs requis — images, annotations, et la 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. Convertis les annotations
Utilise la commande convert_coco() fonction pour convertir tes annotations COCO JSON au format .txt YOLO :
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
cls91to80=False,
)3. Organise la structure du répertoire
Après la conversion, les fichiers d'étiquettes doivent être placés à côté de tes images. YOLO attend un répertoire labels/ qui reflète le répertoire 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))Ton structure du jeu de données final devrait ressembler à :
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ └── ...
│ └── val/
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img_001.txt
│ │ └── ...
│ └── val/
│ └── ...
└── dataset.yaml4. Crée dataset.yaml
Créer un fichier dataset.yaml fichier de configuration qui mappe tes catégories COCO aux noms de classe YOLO. Ce fichier indique à YOLO où se trouvent tes données et quelles classes détecter :
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)Le fichier YAML résultant :
path: /absolute/path/to/my_dataset
train: images/train
val: images/val
names:
0: helmet
1: vestPour plus de détails sur le format YAML du dataset, consulte le dataset configuration guide.
5. Entraîne ton modèle YOLO
Avec ton dataset converti prêt, entraîne un modèle YOLO :
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # load a pretrained model
results = model.train(data="my_dataset/dataset.yaml", epochs=100, imgsz=640)Pour des conseils d'entraînement et les meilleures pratiques, consulte le model training guide.
6. Vérifie ta conversion
Avant l'entraînement, vérifie rapidement quelques fichiers d'étiquettes pour confirmer que les IDs de classe et les coordonnées sont corrects :
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}"Si tu vois des IDs de classe négatifs, ton COCO JSON utilise probablement category_id commençant à 0. Ajoute 1 à toutes les valeurs category_id dans ton JSON avant d'exécuter convert_coco(), car il mappe les IDs de classe comme category_id - 1.
Dépannage des problèmes courants
Mauvais IDs de classe après la conversion
Si ton modèle s'entraîne mais détecte les mauvaises classes d'objets, tu utilises probablement cls91to80=True (par défaut) sur un dataset personnalisé. Cela mappe tes valeurs category_id à travers la table de correspondance COCO 91-à-80, ce qui n'est correct que pour le jeu de données COCO.
standard. Solution: Utilise toujours cls91to80=False pour les datasets personnalisés.
Aucune étiquette trouvée pendant l'entraînement
Si l'entraînement affiche WARNING: No labels found ou 0 images, N backgrounds, tes fichiers d'étiquettes ne sont pas dans le répertoire attendu. convert_coco() enregistre les étiquettes dans un répertoire de sortie séparé (par ex. save_dir/labels/train/), mais YOLO attend labels/ parallèle à images/ à l'intérieur de ton répertoire de dataset.
standard. Solution: Déplace les fichiers d'étiquettes pour correspondre à la structure de répertoire attendue. Assure-toi que labels/train/ est un pair de images/train/.
KeyError lors de la conversion
Si tu obtiens KeyError: 'bbox' ou des erreurs similaires lors de l'exécution de convert_coco(), ton labels_dir contient probablement des fichiers JSON qui ne sont pas des instances (par exemple, captions_train2017.json) qui ont une structure d'annotation différente.
standard. Solution: Place uniquement les fichiers JSON d'annotation d'instance (par exemple, instances_train2017.json) dans le labels_dir.
Fichiers de labels vides après conversion
Si la conversion se termine mais que les fichiers .txt sont vides ou manquants, il se peut que toutes les annotations aient iscrowd: 1 (courant avec les masques générés par SAM), ou que bounding boxes aient une largeur ou une hauteur nulle.
standard. Solution: Vérifie tes annotations JSON pour les valeurs iscrowd. Si tu utilises des masques SAM, prétraite le JSON pour définir iscrowd: 0.
Lacunes dans les ID de classe des labels convertis
Si les ID de classe dans les fichiers de labels ne sont pas contigus (par exemple 0, 4, 9 au lieu de 0, 1, 2), ton outil d'annotation utilise des valeurs category_id non contiguës.
standard. Solution: Vérifie que les ID de classe dans tes fichiers .txt correspondent au dictionnaire names dans dataset.yaml. Remappe les ID vers des valeurs contiguës si nécessaire.
Pour tous les détails de l'API et les descriptions des paramètres, consulte la convert_coco référence de l'API.
FAQ
Comment convertir des annotations COCO JSON au format YOLO ?
Utilise la commande convert_coco() de Ultralytics pour convertir des annotations COCO JSON au format YOLO .txt. Configure cls91to80=False pour les jeux de données personnalisés :
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)Après la conversion, réorganise tes fichiers de labels afin que labels/ reflète le répertoire images/, puis crée un fichier dataset.yaml. Consulte le guide étape par étape pour le flux de travail complet.
Pourquoi l'entraînement YOLO affiche "No labels found" après la conversion COCO ?
Cela arrive parce que convert_coco() enregistre les labels dans un sous-répertoire à l'intérieur de save_dir/labels/ (par exemple, save_dir/labels/train/) au lieu de les mettre directement dans le labels/train/ aux côtés des répertoires images/train/ de ton jeu de données. YOLO s'attend à ce que les labels soient parallèles aux images — par exemple, images/train/img.jpg nécessite labels/train/img.txt. Déplace tes labels convertis pour correspondre à cette structure. Voir corriger la structure du répertoire.
Que fait cls91to80 dans convert_coco()?
La méthode cls91to80 ? Le paramètre contrôle comment les valeurs category_id COCO sont mappées aux ID de classe YOLO. Quand True (par défaut), il utilise une table de correspondance conçue pour le jeu de données COCO standard, qui a 80 classes avec des ID non contigus (1-90). Pour jeux de données personnalisés, règle toujours cls91to80=False — cela soustrait simplement 1 de chaque category_id pour créer des ID de classe indexés à zéro.
Puis-je entraîner YOLO directement sur COCO JSON sans convertir ?
Pas avec le pipeline d'entraînement YOLO actuel — les annotations doivent être au format YOLO .txt avec un fichier par image. Utilise convert_coco() pour convertir ton COCO JSON d'abord, puis suis ce peuvent encore améliorer la diversité du jeu de données. Apprends-en plus sur la segmentation d'instances et le suivi dans notre pour organiser et entraîner. Pour en savoir plus sur les formats supportés, consulte les formats de jeux de données.
Puis-je convertir des annotations de segmentation COCO au format YOLO ?
Oui, utilise use_segments=True lors de l'appel de convert_coco() pour inclure les masques de segmentation polygonaux dans les labels YOLO convertis. Cela produit des fichiers de labels compatibles avec les modèles de segmentation YOLO:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_segments=True, cls91to80=False)Comment puis-je convertir des annotations de points clés COCO au format YOLO ?
Utilise use_keypoints=True pour convertir les annotations de points clés COCO pour l'entraînement , l'estimation de pose, le :
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)Note que si les deux use_segments et en use_keypoints sont réglés sur True, seuls les points clés seront écrits dans les fichiers de labels — les segments sont ignorés silencieusement.