Como converter anotações COCO para o formato YOLO
Treinar modelos Ultralytics YOLO requer anotações no formato YOLO, mas muitas ferramentas de anotação populares exportam no formato COCO JSON. Este guia mostra como converter suas anotações COCO para o formato YOLO e começar a treinar modelos de detecção de objetos, segmentação de instâncias e estimativa de pose.
Por que converter de COCO para YOLO?
O formato COCO JSON armazena todas as anotações em um único arquivo, enquanto o YOLO usa um arquivo de texto por imagem com coordenadas normalizadas. A conversão é necessária porque:
- Modelos YOLO requerem arquivos de rótulo
.txtcom um arquivo por imagem, contendoclass x_center y_center width heightem coordenadas normalizadas. - COCO JSON usa coordenadas de pixel no formato
[x_min, y_min, width, height]com um único arquivo JSON para todas as imagens. - Os IDs de classe diferem — COCO usa valores
category_idarbitrários, enquanto o YOLO requer IDs de classe indexados em zero.
| Recurso | COCO JSON | YOLO TXT |
|---|---|---|
| Estrutura | Arquivo JSON único para todas as imagens | Um arquivo .txt por imagem |
| Formato Bbox | [x_min, y_min, width, height] em pixels | class x_center y_center width height normalizado (0-1) |
| IDs de classe | category_id (pode começar de qualquer número) | Indexado em zero (começa de 0) |
| Segmentação | Matrizes de polígono no campo segmentation | Coordenadas do polígono após o ID da classe |
| Keypoints | [x, y, visibility, ...] em pixels | [x, y, visibility, ...] normalizado |
Início rápido
A maneira mais rápida de converter anotações COCO e começar a treinar:
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
)Após a conversão, organize a estrutura do seu diretório, crie um dataset.yaml e comece o treinamento. Veja o guia passo a passo completo abaixo.
O padrão cls91to80=True é projetado apenas para o COCO dataset padrão com 80 classes de objetos, que mapeia 91 IDs de categoria não contíguos para 80 IDs de classe contíguos. Para qualquer conjunto de dados personalizado, você deve definir cls91to80=False — caso contrário, seus IDs de classe serão mapeados incorretamente de forma silenciosa e seu modelo aprenderá classes erradas.
Guia de conversão passo a passo
1. Prepare seu conjunto de dados COCO
Um conjunto de dados típico no formato COCO exportado de ferramentas de anotação tem a seguinte estrutura:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ └── val/
│ ├── img_100.jpg
│ └── ...
└── annotations/
├── instances_train.json
└── instances_val.jsonCada arquivo JSON segue a especificação do formato de dados COCO com três campos obrigatórios — images, annotations e 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. Converter anotações
Use a função convert_coco() para converter suas anotações COCO JSON para o formato YOLO .txt:
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
cls91to80=False,
)3. Organizar a estrutura do diretório
Após a conversão, os arquivos de rótulo precisam ser colocados ao lado de suas imagens. O YOLO espera um diretório labels/ que espelhe o diretório 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))Sua estrutura final do conjunto de dados deve ser:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ └── ...
│ └── val/
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img_001.txt
│ │ └── ...
│ └── val/
│ └── ...
└── dataset.yaml4. Criar dataset.yaml
Crie um arquivo de configuração dataset.yaml que mapeie suas categorias COCO para os nomes de classe YOLO. Este arquivo informa ao YOLO onde estão seus dados e quais classes detectar:
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)O arquivo YAML resultante:
path: /absolute/path/to/my_dataset
train: images/train
val: images/val
names:
0: helmet
1: vestPara mais detalhes sobre o formato YAML do conjunto de dados, consulte o guia de configuração do conjunto de dados.
5. Treine seu modelo YOLO
Com seu conjunto de dados convertido pronto, treine um modelo 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)Para dicas de treinamento e melhores práticas, consulte o guia de treinamento de modelos.
6. Verificar sua conversão
Antes de treinar, verifique alguns arquivos de rótulo para confirmar se os IDs de classe e as coordenadas estão corretos:
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}"Se você vir IDs de classe negativos, seu COCO JSON provavelmente usa category_id começando em 0. Adicione 1 a todos os valores de category_id em seu JSON antes de executar convert_coco(), já que ele mapeia IDs de classe como category_id - 1.
Solução de problemas comuns
IDs de classe incorretos após a conversão
Se seu modelo treina, mas detecta classes de objetos erradas, você provavelmente está usando cls91to80=True (padrão) em um conjunto de dados personalizado. Isso mapeia seus valores de category_id através da tabela de consulta COCO 91-para-80, que só é correta para o COCO dataset padrão.
Solução: Sempre use cls91to80=False para conjuntos de dados personalizados.
Nenhum rótulo encontrado durante o treinamento
Se o treinamento mostrar WARNING: No labels found ou 0 images, N backgrounds, seus arquivos de rótulo não estão no diretório esperado. convert_coco() salva rótulos em um diretório de saída separado (por exemplo, save_dir/labels/train/), mas o YOLO espera labels/ paralelo a images/ dentro do seu diretório de conjunto de dados.
Solução: Mova os arquivos de rótulo para corresponder à estrutura de diretórios esperada. Certifique-se de que labels/train/ seja um irmão de images/train/.
KeyError durante a conversão
Se você obtiver KeyError: 'bbox' ou erros semelhantes ao executar convert_coco(), seu labels_dir provavelmente contém arquivos JSON que não são de instância (por exemplo, captions_train2017.json) que possuem uma estrutura de anotação diferente.
Solução: Coloque apenas arquivos JSON de anotação de instância (por exemplo, instances_train2017.json) no labels_dir.
Arquivos de rótulo vazios após a conversão
Se a conversão for concluída, mas os arquivos .txt estiverem vazios ou ausentes, todas as anotações podem ter iscrowd: 1 (comum com máscaras geradas pelo SAM), ou as caixas delimitadoras têm largura ou altura zero.
Solução: Inspecione suas anotações JSON para valores iscrowd. Se estiver usando máscaras SAM, pré-processe o JSON para definir iscrowd: 0.
Lacunas nos IDs de classe em rótulos convertidos
Se os IDs de classe nos arquivos de rótulo não forem contíguos (por exemplo, 0, 4, 9 em vez de 0, 1, 2), sua ferramenta de anotação usa valores category_id não contíguos.
Solução: Verifique se os IDs de classe em seus arquivos .txt correspondem ao dicionário names em dataset.yaml. Remapeie os IDs para valores contíguos, se necessário.
Para detalhes completos da API e descrições de parâmetros, consulte a referência da API convert_coco.
FAQ
Como converto anotações COCO JSON para o formato YOLO?
Use a função convert_coco() da Ultralytics para converter anotações COCO JSON para o formato YOLO .txt. Defina cls91to80=False para conjuntos de dados personalizados:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)Após a conversão, reorganize seus arquivos de rótulo para que labels/ espelhe o diretório images/ e, em seguida, crie um arquivo dataset.yaml. Consulte o guia passo a passo para o fluxo de trabalho completo.
Por que o treinamento YOLO mostra "No labels found" após a conversão COCO?
Isso acontece porque convert_coco() salva rótulos em um subdiretório dentro de save_dir/labels/ (por exemplo, save_dir/labels/train/) em vez de diretamente no labels/train/ do seu conjunto de dados, ao lado de images/train/. O YOLO espera que os rótulos fiquem paralelos às imagens — por exemplo, images/train/img.jpg precisa de labels/train/img.txt. Mova seus rótulos convertidos para corresponder a essa estrutura. Consulte corrigir a estrutura do diretório.
O que o cls91to80 faz no convert_coco()?
O parâmetro cls91to80 controla como os valores category_id do COCO são mapeados para os IDs de classe YOLO. Quando True (padrão), ele usa uma tabela de consulta projetada para o COCO dataset padrão, que tem 80 classes com IDs não contíguos (1-90). Para conjuntos de dados personalizados, sempre defina cls91to80=False — isso simplesmente subtrai 1 de cada category_id para criar IDs de classe indexados em zero.
Posso treinar YOLO diretamente no COCO JSON sem converter?
Não com o pipeline de treinamento YOLO atual — as anotações devem estar no formato YOLO .txt com um arquivo por imagem. Use convert_coco() para converter seu COCO JSON primeiro, depois siga este guia para organizar e treinar. Para saber mais sobre os formatos suportados, consulte formatos de conjunto de dados.
Posso converter anotações de segmentação COCO para o formato YOLO?
Sim, use use_segments=True ao chamar convert_coco() para incluir máscaras de segmentação de polígono nos rótulos YOLO convertidos. Isso produz arquivos de rótulo compatíveis com modelos de segmentação YOLO:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_segments=True, cls91to80=False)Como converto anotações de keypoint COCO para o formato YOLO?
Use use_keypoints=True para converter anotações de keypoint COCO para treinamento de estimativa de pose:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)Observe que se tanto use_segments quanto use_keypoints forem definidos como True, apenas os keypoints serão gravados nos arquivos de rótulo — os segmentos serão ignorados silenciosamente.