Meet YOLO26: next-gen vision AI.

COCOアノテーションをYOLOフォーマットに変換する方法

Ultralytics YOLOモデルのトレーニングにはYOLOフォーマットのアノテーションが必要ですが、一般的なアノテーションツールの多くはCOCO JSONフォーマットでエクスポートします。本ガイドでは、COCOアノテーションをYOLOフォーマットに変換し、物体検出インスタンスセグメンテーション、および姿勢推定モデルのトレーニングを開始する方法を説明します。

なぜCOCOからYOLOへ変換するのか?

COCO JSONフォーマットはすべてのアノテーションを単一のファイルに格納しますが、YOLOは正規化された座標を持つ画像ごとに1つのテキストファイルを使用します。変換が必要な理由は以下の通りです。

  • YOLOモデルには.txtラベルファイルが必要です。画像ごとに1つのファイルが必要であり、正規化された座標でclass x_center y_center width heightを含みます。
  • COCO JSONはピクセル座標を使用します[x_min, y_min, width, height]フォーマットで、すべての画像に対して単一のJSONファイルを使用します。
  • クラスIDが異なります。COCOは任意のcategory_id値を使用しますが、YOLOは0から始まるクラスIDを必要とします。
機能COCO JSONYOLO TXT
構造全画像に対して単一のJSONファイル画像ごとに1つの.txtファイル
Bboxフォーマット[x_min, y_min, width, height](ピクセル単位)class x_center y_center width height(正規化、0-1)
クラスIDcategory_id(任意の数字から開始可能)0ベース(0から開始)
セグメンテーションsegmentationフィールド内のポリゴン配列クラスID後のポリゴン座標
キーポイント[x, y, visibility, ...](ピクセル単位)[x, y, visibility, ...](正規化)

クイックスタート

COCOアノテーションを変換してトレーニングを開始するための最速の方法:

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
)

変換後、ディレクトリ構造を整理し、dataset.yamlを作成し、トレーニングを開始してください。詳細は以下の完全なステップバイステップガイドを参照してください。

カスタムデータセット:常に`cls91to80=False`を使用してください

cls91to80=Trueというデフォルト設定は、80個のオブジェクトクラスを持つ標準のCOCOデータセット専用に設計されており、連続していない91個のカテゴリIDを80個の連続したクラスIDにマップします。カスタムデータセットの場合、必ずcls91to80=Falseに設定する必要があります。そうしないと、クラスIDが誤ってマップされ、モデルが間違ったクラスを学習してしまいます。

ステップバイステップ変換ガイド

COCOデータセットの準備

アノテーションツールからエクスポートされた一般的なCOCOフォーマットのデータセットは、以下の構造になっています。

my_dataset/
├── images/
│   ├── train/
│   │   ├── img_001.jpg
│   │   ├── img_002.jpg
│   │   └── ...
│   └── val/
│       ├── img_100.jpg
│       └── ...
└── annotations/
    ├── instances_train.json
    └── instances_val.json

各JSONファイルはCOCOデータフォーマット仕様に従い、imagesannotationscategoriesという3つの必須フィールドを持ちます。

{
    "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" }
    ]
}

アノテーションの変換

convert_coco()関数を使用して、COCO JSONアノテーションをYOLOの.txtフォーマットに変換します。

COCOからYOLOフォーマットへの変換
from ultralytics.data.converter import convert_coco

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

ディレクトリ構造の整理

After conversion, label files need to be placed alongside your images. YOLO expects a labels/ directory that mirrors the images/ directory:

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

最終的なデータセット構造は以下のようになります。

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

dataset.yamlの作成

COCOカテゴリをYOLOクラス名にマップするdataset.yaml設定ファイルを作成します。このファイルは、データがどこにあり、どのクラスを検出するかをYOLOに伝えます。

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)

結果として得られるYAMLファイル:

path: /absolute/path/to/my_dataset
train: images/train
val: images/val
names:
    0: helmet
    1: vest

データセットYAMLフォーマットの詳細については、データセット設定ガイドを参照してください。

YOLOモデルのトレーニング

変換済みデータセットの準備ができたら、YOLOモデルをトレーニングします。

変換済みCOCOデータでのトレーニング
from ultralytics import YOLO

model = YOLO("yolo26n.pt")  # load a pretrained model
results = model.train(data="my_dataset/dataset.yaml", epochs=100, imgsz=640)

トレーニングのヒントとベストプラクティスについては、モデルトレーニングガイドを参照してください。

変換の検証

トレーニングの前に、いくつかのラベルファイルをスポットチェックし、クラスIDと座標が正しいことを確認します。

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}"
ヒント

If you see negative class IDs, your COCO JSON likely uses category_id starting from 0. Add 1 to all category_id values in your JSON before running convert_coco(), since it maps class IDs as category_id - 1.

一般的な問題のトラブルシューティング

変換後のクラスIDが間違っている

モデルがトレーニングされても間違ったオブジェクトクラスを検出する場合、カスタムデータセットに対して(デフォルトの)cls91to80=Trueを使用している可能性があります。これは、COCOの91から80へのルックアップテーブルを介してcategory_id値をマップしますが、これは標準のCOCOデータセットに対してのみ正しいものです。

解決策:カスタムデータセットには必ずcls91to80=Falseを使用してください。

トレーニング中にラベルが見つからない

If training shows WARNING: No labels found or 0 images, N backgrounds, your label files are not in the expected directory. convert_coco() saves labels to a separate output directory (e.g., save_dir/labels/train/), but YOLO expects labels/ parallel to images/ inside your dataset directory.

解決策:期待されるディレクトリ構造に合わせてラベルファイルを移動してください。labels/train/images/train/の兄弟ディレクトリであることを確認してください。

変換中のKeyError

If you get KeyError: 'bbox' or similar errors when running convert_coco(), your labels_dir likely contains non-instance JSON files (e.g., captions_train2017.json) that have a different annotation structure.

Solution: Only place instance annotation JSON files (e.g., instances_train2017.json) in the labels_dir.

変換後のラベルファイルが空

変換が完了しても.txtファイルが空または欠落している場合、すべてのアノテーションがiscrowd: 1SAM生成マスクで一般的)であるか、バウンディングボックスの幅または高さがゼロである可能性があります。

解決策:JSONアノテーションのiscrowd値を確認してください。SAMマスクを使用している場合は、iscrowd: 0になるようにJSONを前処理してください。

変換後のラベルにおけるクラスIDの欠落

ラベルファイルのクラスIDが連続していない場合(例:0, 1, 2ではなく0, 4, 9)、アノテーションツールが連続していないcategory_id値を使用しています。

Solution: Verify the class IDs in your .txt files match the names dictionary in dataset.yaml. Remap IDs to contiguous values if needed.

APIの詳細とパラメータの説明については、convert_coco APIリファレンスを参照してください。

FAQ

COCO JSONアノテーションをYOLOフォーマットに変換するにはどうすればよいですか?

Ultralyticsのconvert_coco()関数を使用して、COCO JSONアノテーションをYOLOの.txtフォーマットに変換します。カスタムデータセットの場合はcls91to80=Falseに設定してください。

from ultralytics.data.converter import convert_coco

convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)

変換後、ラベルファイルを整理してlabels/images/ディレクトリを反映するようにし、dataset.yamlファイルを作成します。完全なワークフローについては、ステップバイステップガイドを参照してください。

なぜCOCO変換後にYOLOトレーニングで「No labels found」と表示されるのですか?

This happens because convert_coco() saves labels to a subdirectory inside save_dir/labels/ (e.g., save_dir/labels/train/) rather than directly into your dataset's labels/train/ alongside images/train/. YOLO expects labels to sit parallel to images — for example, images/train/img.jpg needs labels/train/img.txt. Move your converted labels to match this structure. See fixing the directory structure.

What does cls91to80 do in convert_coco()?

cls91to80パラメータは、COCOのcategory_id値をYOLOのクラスIDにどのようにマップするかを制御します。True(デフォルト)の場合、80クラスを持ち、連続していないID(1-90)を持つ標準のCOCOデータセット向けに設計されたルックアップテーブルを使用します。カスタムデータセットの場合は、常にcls91to80=Falseに設定してください。これは、各category_idから1を引いて0から始まるクラスIDを作成するだけです。

COCO JSONを変換せずに直接YOLOでトレーニングできますか?

現在のYOLOトレーニングパイプラインではできません。アノテーションは画像ごとに1つのファイルを持つYOLOの.txtフォーマットである必要があります。まずconvert_coco()を使用してCOCO JSONを変換し、このガイドに従って整理とトレーニングを行ってください。サポートされているフォーマットの詳細については、データセットフォーマットを参照してください。

COCOセグメンテーションアノテーションをYOLOフォーマットに変換できますか?

Yes, use use_segments=True when calling convert_coco() to include polygon segmentation masks in the converted YOLO labels. This produces label files compatible with YOLO segmentation models:

from ultralytics.data.converter import convert_coco

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

COCOキーポイントアノテーションをYOLOフォーマットに変換するにはどうすればよいですか?

Use use_keypoints=True to convert COCO keypoint annotations for pose estimation training:

from ultralytics.data.converter import convert_coco

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

use_segmentsuse_keypointsの両方をTrueに設定した場合、ラベルファイルにはキーポイントのみが書き込まれ、セグメントは無視されることに注意してください。

コメント