Meet YOLO26: next-gen vision AI.

Link to this sectionComo converter anotações COCO para o formato YOLO#

O treinamento de modelos Ultralytics YOLO exige anotações no formato YOLO, mas muitas ferramentas de anotação populares exportam em 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.

Prefere ignorar a conversão?

Para treinar diretamente no COCO JSON sem gerar arquivos .txt, consulte Treinar YOLO no COCO JSON sem conversão.

Link to this sectionPor 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:

  • Os modelos YOLO exigem arquivos de rótulo .txt com um arquivo por imagem, contendo class x_center y_center width height em coordenadas normalizadas.
  • O 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 — o COCO usa valores de category_id arbitrários, enquanto o YOLO exige IDs de classe indexados em zero.
FuncionalidadeCOCO JSONYOLO TXT
EstruturaArquivo JSON único para todas as imagensUm arquivo .txt por imagem
Formato de Bbox[x_min, y_min, width, height] em pixelsclass x_center y_center width height normalizado (0-1)
IDs de classecategory_id (pode começar de qualquer número)Indexado em zero (começa de 0)
SegmentaçãoMatrizes de polígonos no campo segmentationCoordenadas de polígono após o ID da classe
Keypoints[x, y, visibility, ...] em pixels[x, y, visibility, ...] normalizado

Link to this sectionInício Rápido#

A maneira mais rápida de converter anotações COCO e iniciar o treinamento:

from ultralytics.data.converter import convert_coco

convert_coco(
    labels_dir="my_dataset/annotations/",  # directory containing your JSON files
    save_dir="my_dataset/converted/",  # where to save converted labels
    cls91to80=False,  # set False for custom datasets (see warning below)
)

Após a conversão, organize a estrutura do seu diretório, crie um dataset.yaml e inicie o treinamento. Veja o guia passo a passo completo abaixo.

Datasets personalizados: sempre use `cls91to80=False`

O padrão cls91to80=True foi projetado apenas para o dataset COCO 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, 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.

Link to this sectionGuia de conversão passo a passo#

Link to this section1. Prepare seu 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 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" }
    ]
}

Link to this section2. Converter anotações#

Use a função convert_coco() para converter suas anotações COCO JSON para o formato YOLO .txt:

Converter COCO para o formato YOLO
from ultralytics.data.converter import convert_coco

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

convert_coco() escreve um arquivo .txt por imagem anotada em um subdiretório labels/ nomeado após cada arquivo JSON, com o prefixo instances_ removido (portanto, instances_train.json produz labels/train/). Imagens sem anotações são ignoradas e não recebem arquivo de rótulo, então a árvore labels/ pode não espelhar todas as imagens:

my_dataset/converted/
└── labels/
    ├── train/   # from instances_train.json
    │   ├── img_001.txt
    │   └── ...
    └── val/     # from instances_val.json
        └── ...
Executar novamente cria uma nova pasta de saída

convert_coco() nunca sobrescreve um save_dir existente: se my_dataset/converted/ já existir, uma nova execução escreve em my_dataset/converted-2/ em vez disso. Exclua a saída anterior (ou altere o save_dir) antes de executar novamente, ou os próximos passos lerão rótulos obsoletos.

Link to this section3. Organizar a estrutura de diretórios#

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

converted_dir = Path("my_dataset/converted/labels")
dataset_dir = Path("my_dataset")

# convert_coco names each subdirectory after its JSON file (minus the "instances_" prefix),
# so iterate the actual subdirectories instead of assuming "train"/"val".
for src in converted_dir.iterdir():
    if not src.is_dir():
        continue
    dst = dataset_dir / "labels" / src.name
    dst.mkdir(parents=True, exist_ok=True)
    for f in src.glob("*.txt"):
        shutil.move(str(f), str(dst / f.name))

A estrutura final do seu dataset deve ser assim:

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

Link to this section4. Criar dataset.yaml#

Crie um arquivo de configuração dataset.yaml que mapeie suas categorias COCO para nomes de classe YOLO. Este arquivo diz 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: vest

Para mais detalhes sobre o formato YAML do dataset, consulte o guia de configuração de dataset.

Link to this section5. Treine seu modelo YOLO#

Com seu dataset convertido pronto, treine um modelo YOLO:

Treinar 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, consulte o guia de treinamento de modelos.

Link to this section6. Verifique 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}"
Dica

Se você vir IDs de classe negativos, é provável que seu COCO JSON use category_id começando de 0. Adicione 1 a todos os valores de category_id em seu JSON antes de executar convert_coco(), já que ele mapeia os IDs de classe como category_id - 1.

Link to this sectionSolução de problemas comuns#

Link to this sectionIDs de classe errados após a conversão#

Se o seu modelo treina, mas detecta classes de objetos erradas, você provavelmente está usando cls91to80=True (padrão) em um dataset personalizado. Isso mapeia seus valores de category_id através da tabela de consulta COCO 91-para-80, que só é correta para o dataset COCO padrão.

Solução: Sempre use cls91to80=False para datasets personalizados.

Link to this sectionNenhum 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. O convert_coco() salva os 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 dataset.

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/.

Link to this sectionKeyError durante a conversão#

Se você receber 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 têm 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.

Link to this sectionArquivos 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 bounding boxes com largura ou altura zero.

Soluçã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.

Link to this sectionLacunas nos IDs de classe nos 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 de 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.

Link to this sectionFAQ#

Link to this sectionComo 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 datasets 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.

Link to this sectionPor que o treinamento YOLO mostra "Nenhum rótulo encontrado" após a conversão COCO?#

Isso acontece porque o 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/ do seu dataset 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. Veja como corrigir a estrutura de diretórios.

Link to this sectionO que o cls91to80 faz no convert_coco()?#

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

Link to this sectionPosso treinar o 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 e, em seguida, siga este guia para organizar e treinar. Para mais informações sobre os formatos suportados, consulte formatos de dataset.

Link to this sectionPosso 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)

Link to this sectionComo 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 use_segments e use_keypoints forem definidos como True, apenas os keypoints serão gravados nos arquivos de rótulo — os segmentos serão ignorados silenciosamente.

Comentários