Como converter COCO para YOLO
Formação Ultralytics YOLO requerem anotações no YOLO , mas muitas ferramentas de anotação populares exportam no formato COCO . Este guia mostra-lhe como converter COCO suas COCO para YOLO e começar a treinar modelos de deteção de objetos, segmentação de instâncias e estimativa de poses.
Por que converter de COCO YOLO?
O formato COCO armazena todas as anotações num único ficheiro, enquanto YOLO utiliza um ficheiro de texto por imagem com coordenadas normalizadas. A conversão é necessária porque:
- YOLO requerem
.txtficheiros de etiquetas com um ficheiro por imagem, contendoclass x_center y_center width heightem coordenadas normalizadas. - O COCO utiliza coordenadas de píxeis em
[x_min, y_min, width, height]formato com um único ficheiro JSON para todas as imagens. - Os IDs de classe são diferentes — COCO valores arbitrários
category_idvalores, enquanto YOLO IDs de classe indexadas a partir de zero.
| Funcionalidade | COCO | YOLO |
|---|---|---|
| Estrutura | Um único ficheiro JSON para todas as imagens | Um .txt um ficheiro 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 por qualquer número) | Indexação a partir do zero (começa em 0) |
| Segmentação | Matrizes de polígonos em segmentation campo | 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 forma mais rápida de converter COCO e começar o treino:
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 sua estrutura de diretórios, crie um ficheiro dataset.yaml e inicie o treino. Consulte o guia passo a passo completo abaixo.
Conjuntos de dados personalizados: utilizar sempre cls91to80=False
O cls91to80=True O padrão foi concebido apenas para a norma Conjunto de dados COCO com 80 classes de objetos, que mapeia 91 IDs de categorias não contíguas para 80 IDs de classes contíguas. Para qualquer conjunto de dados personalizado, você tem de conjunto cls91to80=False — caso contrário, os seus IDs de classe serão mapeados incorretamente sem aviso prévio e o seu modelo irá aprender classes erradas.
Guia passo a passo para a conversão
1. Prepare o seu COCO
Um conjunto de dados típico COCO exportado a partir 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 ficheiro JSON segue o Formato COCO especificação 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 o comando convert_coco() função para converter as suas anotações COCO para YOLO .txt formato:
Converter COCO YOLO
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
cls91to80=False,
)
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
use_segments=True,
cls91to80=False,
)
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
use_keypoints=True,
cls91to80=False,
)
3. Organizar a estrutura de diretórios
Após a conversão, os ficheiros de etiquetas devem ser colocados junto com as imagens. YOLO um labels/ diretório que espelha 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))
A estrutura final do seu conjunto de dados deverá ser semelhante a esta:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ └── ...
│ └── val/
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img_001.txt
│ │ └── ...
│ └── val/
│ └── ...
└── dataset.yaml
4. Criar o ficheiro dataset.yaml
Criar um dataset.yaml ficheiro de configuração que mapeia COCO suas COCO para os nomes YOLO . Este ficheiro indica YOLO se encontram os seus dados e quais as classes a detect:
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 ficheiro YAML resultante:
path: /absolute/path/to/my_dataset
train: images/train
val: images/val
names:
0: helmet
1: vest
Para mais informações sobre o formato YAML do conjunto de dados, consulte o guia de configuração do conjunto de dados.
5. Treine o seu YOLO
Com o seu conjunto de dados convertido pronto, treine um YOLO :
Treinar com 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)
yolo detect train model=yolo26n.pt data=my_dataset/dataset.yaml epochs=100 imgsz=640
Para obter dicas de treino e melhores práticas, consulte o guia de treino do modelo.
6. Verifique a sua conversão
Antes do treino, verifique aleatoriamente alguns ficheiros de etiquetas para confirmar se os IDs das classes 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 vir IDs de classe negativas, é provável que o seu COCO utilize category_id começando por 0. Somar 1 a todos category_id valores no seu JSON antes de executar convert_coco(), uma vez que mapeia os IDs das classes como category_id - 1.
Resolução de problemas comuns
IDs de classe incorretas após a conversão
Se o seu modelo funciona, mas deteta classes de objetos erradas, é provável que esteja a utilizar cls91to80=True (padrão) num conjunto de dados personalizado. Isto mapeia o seu category_id valores através da tabela de conversão COCO , que só é correta para o padrão Conjunto de dados COCO.
Solução: Utilize sempre cls91to80=False para conjuntos de dados personalizados.
Não foram encontradas etiquetas durante a formação
Se os treinos revelarem WARNING: No labels found ou 0 images, N backgrounds, os seus ficheiros de etiquetas não se encontram no diretório esperado. convert_coco() guarda as etiquetas num diretório de saída separado (por exemplo, save_dir/labels/train/), mas o YOLO labels/ paralelamente a images/ dentro do diretório do seu conjunto de dados.
Solução: Mover os ficheiros de etiquetas para corresponderem ao esperado estrutura de diretórios. Certifique-se de que labels/train/ é um irmão de images/train/.
Erro KeyError durante a conversão
Se você receber KeyError: 'bbox' ou erros semelhantes ao executar convert_coco(), o seu labels_dir provavelmente contém ficheiros JSON que não são de instância (por exemplo, captions_train2017.json) que apresentam uma estrutura de anotação diferente.
Solução: Coloque apenas ficheiros JSON de anotação de instâncias (por exemplo, instances_train2017.json) no labels_dir.
Ficheiros de etiquetas vazios após a conversão
Se a conversão for concluída, mas .txt os ficheiros estão vazios ou faltam, todas as anotações podem ter iscrowd: 1 (comum em SAM-máscaras geradas), ou bounding boxes têm largura ou altura nula.
Solução: Verifique as suas anotações JSON para iscrowd valores. Se estiver a utilizar SAM , pré-processe o JSON para definir iscrowd: 0.
Lacunas no ID de classe em etiquetas convertidas
Se os IDs de classe nos ficheiros de etiquetas não forem contíguos (por exemplo, 0, 4, 9 em vez de 0, 1, 2), a sua ferramenta de anotação utiliza IDs não contíguos category_id valores.
Solução: Verifique os IDs das classes no seu .txt os ficheiros correspondem ao names dicionário em dataset.yaml. Remapeie os IDs para valores contíguos, se necessário.
Para obter todos os detalhes da API e as descrições dos parâmetros, consulte o convert_coco Referência da API.
FAQ
Como posso converter as anotações COCO para YOLO ?
Use o comando convert_coco() função da Ultralytics converter anotações COCO para YOLO .txt formato. Definir 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 os seus ficheiros de etiquetas de modo a que labels/ reflete o images/ diretório, e depois crie um dataset.yaml ficheiro. Consulte o guia passo a passo para o fluxo de trabalho completo.
Por que é que YOLO apresenta a mensagem «Não foram encontrados rótulos» após COCO ?
Isto acontece porque convert_coco() guarda as etiquetas num subdiretório dentro de save_dir/labels/ (e.g., save_dir/labels/train/) em vez de diretamente no seu conjunto de dados labels/train/ juntamente com images/train/. YOLO que as etiquetas fiquem paralelas às imagens — por exemplo, images/train/img.jpg necessidades labels/train/img.txt. Adapte as suas etiquetas convertidas para que correspondam a esta estrutura. Consulte definir a estrutura de diretórios.
O que significa cls91to80 fazer em convert_coco()?
O cls91to80 O parâmetro controla como COCO category_id os valores são mapeados para os IDs YOLO . Quando True (por predefinição), utiliza uma tabela de consulta concebida para o padrão Conjunto de dados COCO, que tem 80 classes com IDs não contíguos (1-90). Para conjuntos de dados personalizados, sempre definido cls91to80=False — isto simplesmente subtrai 1 de cada um category_id para criar IDs de classe com indexação a partir de zero.
Posso treinar YOLO no COCO sem precisar de converter?
Não com o atual fluxo de trabalho YOLO — as anotações têm de estar no YOLO .txt formato com um ficheiro por imagem. Utilize convert_coco() Primeiro, converta o seu ficheiro COCO e, em seguida, siga estas instruções guia para organizar e dar formação. Para mais informações sobre os formatos suportados, consulte formatos de conjuntos de dados.
É possível converter as anotações COCO para YOLO ?
Sim, use use_segments=True ao ligar convert_coco() para incluir máscaras de segmentação de polígonos nas YOLO convertidas. Isto produz ficheiros de etiquetas compatíveis com Modelos YOLO:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_segments=True, cls91to80=False)
Como posso converter as anotações COCO para YOLO ?
Use use_keypoints=True para converter anotações COCO para estimativa de pose formação:
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)
Note que se ambos use_segments e use_keypoints estão definidos para True, apenas os pontos-chave serão gravados nos ficheiros de etiquetas — os segmentos serão ignorados sem aviso prévio.