Skip to main content

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 tuas anotações COCO para o formato YOLO e começar a treinar object detection, segmentação de instâncias, e estimativa de pose bem treinados.

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 .txt arquivos de rótulo com um arquivo por imagem, contendo class x_center y_center width height em coordenadas normalizadas.
  • COCO JSON usa o formato de coordenadas de pixel em [x_min, y_min, width, height] com um único arquivo JSON para todas as imagens.
  • IDs de classe diferem — COCO usa valores category_id arbitrários, enquanto YOLO requer IDs de classe indexados em zero.
RecursoCOCO JSONYOLO TXT
EstruturaArquivo JSON único para todas as imagensUm .txt arquivo por imagem
Formato Bbox[x_min, y_min, width, height] em pixelsclass x_center y_center width height normalizados (0-1)
IDs de classecategory_id (podem começar de qualquer número)Indexados em zero (começam em 0)
SegmentationArrays de polígono no segmentation campoCoordenadas de polígono após ID de classe
Keypoints[x, y, visibility, ...] em pixels[x, y, visibility, ...] normalizadas

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, organiza a estrutura do teu diretório, cria um dataset.yaml, e começa o treinamento. Vê o guia passo a passo completo abaixo.

Datasets personalizados: usa sempre `cls91to80=False`

O argumento cls91to80=True o padrão é 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 dataset personalizado, tu deves define cls91to80=False — caso contrário, teus IDs de classe serão mapeados incorretamente de forma silenciosa e teu modelo aprenderá as classes erradas.

Guia de conversão passo a passo

1. Prepara o teu dataset COCO

Um dataset típico em 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.json

Cada arquivo JSON segue a especificação do COCO data format 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. Converte anotações

Usa o convert_coco() função para converter as tuas anotações COCO JSON para o formato YOLO .txt:

Converte COCO para formato YOLO
from ultralytics.data.converter import convert_coco

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

3. Organiza a estrutura do diretório

Após a conversão, os arquivos de rótulo precisam ser colocados ao lado das tuas imagens. YOLO espera um labels/ diretório que espelhe o images/ diretório:

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

O teu estrutura do dataset final deve ficar assim:

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

4. Cria o dataset.yaml

Criar um arquivo dataset.yaml arquivo de configuração que mapeia tuas categorias COCO para nomes de classe YOLO. Este arquivo diz ao YOLO onde estão os teus 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: vest

Para mais detalhes sobre o formato YAML do dataset, vê o dataset configuration guide.

5. Treina o teu modelo YOLO

Com o teu dataset convertido pronto, treina um modelo YOLO:

Treina em dados COCO convertidos
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, vê o model training guide.

6. Verifica a tua conversão

Antes de treinar, verifica alguns arquivos de rótulo para confirmar se os IDs de classe e 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}"
Dica

Se vires IDs de classe negativos, é provável que o teu COCO JSON use category_id começando de 0. Adiciona 1 a todos os category_id valores no teu JSON antes de executar convert_coco(), já que ele mapeia IDs de classe como category_id - 1.

Resolução de problemas comuns

IDs de classe errados após a conversão

Se o teu modelo treina mas detecta classes de objetos erradas, provavelmente estás a usar cls91to80=True (padrão) num dataset personalizado. Isso mapeia os teus category_id valores através da tabela de consulta 91-para-80 do COCO, que só é correta para o COCO dataset.

padrão: Usa sempre cls91to80=False para datasets personalizados.

Nenhum rótulo encontrado durante o treinamento

Se o treinamento mostrar WARNING: No labels found ou 0 images, N backgrounds, os teus arquivos de rótulo não estão no diretório esperado. convert_coco() salva rótulos num diretório de saída separado (por exemplo, save_dir/labels/train/), mas YOLO espera labels/ paralelo ao images/ dentro do teu diretório de dataset.

padrão: Move os arquivos de rótulo para corresponder à estrutura de diretório esperada. Certifica-te de labels/train/ é um irmão de images/train/.

KeyError durante a conversão

Se você receber um KeyError: 'bbox' ou erros similares ao executar convert_coco(), o 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.

padrã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 faltando, todas as anotações podem ter iscrowd: 1 (comum com máscaras geradas pelo SAM), ou os bounding boxes têm largura ou altura zero.

padrão: Inspecione suas anotações JSON em busca de 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.

padrão: Verifique se os IDs de classe nos 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 API reference.

FAQ

Como converto anotações COCO JSON para o formato YOLO?

Usa o convert_coco() função 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/, então crie um arquivo dataset.yaml. Veja o guia passo a passo para o fluxo de trabalho completo.

Por que o treinamento YOLO mostra "Nenhum rótulo encontrado" após a conversão COCO?

Isso acontece porque convert_coco() salva os rótulos em um subdiretório dentro de save_dir/labels/ (por exemplo, save_dir/labels/train/) em vez de diretamente no labels/train/ juntamente com os diretórios images/train/ do seu conjunto de dados. 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. Veja como corrigir a estrutura de diretórios.

O que o cls91to80 faz no convert_coco()?

O argumento cls91to80 O parâmetro controla como os valores category_id COCO são mapeados para IDs de classe YOLO. Quando True (padrão), ele usa uma tabela de consulta projetada para o COCO dataset padrão, que possui 80 classes com IDs não contíguos (1-90). Para custom datasets, defina sempre cls91to80=False — isso simplesmente subtrai 1 de cada category_id para criar IDs de classe indexados em zero.

Posso treinar o YOLO diretamente em 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 guide para organizar e treinar. Para mais informações sobre formatos suportados, veja 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 pontos-chave COCO para o formato YOLO?

Use use_keypoints=True para converter anotações de pontos-chave COCO para estimativa de pose treinamento:

from ultralytics.data.converter import convert_coco

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

Observe que se ambos use_segments e use_keypoints estiverem definidos como True, apenas os pontos-chave serão gravados nos arquivos de rótulo — os segmentos serão ignorados silenciosamente.

Comentários