YOLO Vision 2026:

COCO Anotasyonlarını YOLO Formatına Dönüştürme#

Ultralytics YOLO modellerini eğitmek için YOLO formatında anotasyonlar gerekir, ancak birçok popüler anotasyon aracı bunun yerine COCO JSON formatında dışa aktarım yapar. Bu kılavuz, COCO anotasyonlarını YOLO formatına nasıl dönüştüreceğini ve nesne algılama, örnek segmentasyonu ve poz tahmini modellerini eğitmeye nasıl başlayacağını gösterir.

Dönüştürmeyi atlamak mı istiyorsun?

.txt dosyaları oluşturmadan doğrudan COCO JSON üzerinde eğitim yapmak için Dönüştürme Olmadan COCO JSON Üzerinde YOLO Eğitimi bölümüne bak.

COCO'dan YOLO'ya Neden Dönüştürme Yapılır?#

COCO JSON formatı tüm anotasyonları tek bir dosyada saklarken YOLO, her görüntü için normalize edilmiş koordinatlara sahip bir metin dosyası kullanır. Dönüştürme şu nedenlerle gereklidir:

  • YOLO modelleri .txt etiket dosyaları gerektirir; her görüntü için bir dosyada, normalize edilmiş koordinatlarda class x_center y_center width height bulunur.
  • COCO JSON piksel koordinatlarını kullanır; tüm görüntüler için tek bir JSON dosyasıyla [x_min, y_min, width, height] formatındadır.
  • Sınıf kimlikleri farklıdır — COCO rastgele category_id değerleri kullanırken YOLO, sıfır tabanlı sınıf kimlikleri gerektirir.
ÖzellikCOCO JSONYOLO TXT
YapıTüm görüntüler için tek JSON dosyasıGörüntü başına bir .txt dosyası
BBox formatıPiksel cinsinden [x_min, y_min, width, height]Normalize edilmiş class x_center y_center width height (0-1)
Sınıf kimliklericategory_id (herhangi bir sayıdan başlayabilir)Sıfır tabanlı (0'dan başlar)
Segmentasyonsegmentation alanındaki çokgen dizileriSınıf kimliğinden sonra çokgen koordinatları
Anahtar noktalarPiksel cinsinden [x, y, visibility, ...]Normalize edilmiş [x, y, visibility, ...]

Hızlı Başlangıç#

COCO anotasyonlarını dönüştürüp eğitime başlamanın en hızlı yolu:

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

Dönüştürmeden sonra dizin yapını düzenle, bir dataset.yaml dosyası oluştur ve eğitime başla. Aşağıdaki tam adım adım kılavuza bak.

Özel veri kümeleri: her zaman `cls91to80=False` kullan

cls91to80=True varsayılanı, yalnızca 80 nesne sınıfına sahip standart COCO veri kümesi için tasarlanmıştır; 91 bitişik olmayan kategori kimliğini 80 bitişik sınıf kimliğine eşler. Herhangi bir özel veri kümesi için cls91to80=False değerini mutlaka ayarlamalısın — aksi takdirde sınıf kimliklerin sessizce yanlış eşlenir ve modelin yanlış sınıfları öğrenir.

Adım Adım Dönüştürme Kılavuzu#

1. COCO Veri Kümeni Hazırla#

Anotasyon araçlarından dışa aktarılan tipik bir COCO formatlı veri kümesi aşağıdaki yapıya sahiptir:

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

Her JSON dosyası, üç gerekli alan içeren COCO veri formatı belirtimini izler — images, annotations ve 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. Anotasyonları Dönüştür#

COCO JSON anotasyonlarını YOLO .txt formatına dönüştürmek için convert_coco() işlevini kullan:

COCO'yu YOLO formatına dönüştür
from ultralytics.data.converter import convert_coco

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

convert_coco(), her anotasyonlu görüntü için bir .txt dosyasını, her JSON dosyasının adını taşıyan labels/ alt dizinine yazar; instances_ öneki kaldırılır (böylece instances_train.json, labels/train/ oluşturur). Anotasyonu olmayan görüntüler atlanır ve etiket dosyası almaz; bu nedenle labels/ ağacı her görüntüyü yansıtmayabilir:

my_dataset/converted/
├── images/      # created but left empty
└── labels/
    ├── train/   # from instances_train.json
    │   ├── img_001.txt
    │   └── ...
    └── val/     # from instances_val.json
        └── ...
Yeniden çalıştırmak yeni bir çıktı klasörü oluşturur

convert_coco(), mevcut bir save_dir dosyasının üzerine asla yazmaz: my_dataset/converted/ zaten varsa yeniden çalıştırma bunun yerine my_dataset/converted-2/ konumuna yazar. Yeniden çalıştırmadan önce önceki çıktıyı sil veya save_dir değerini değiştir; aksi takdirde sonraki adımlar güncel olmayan etiketleri okur.

3. Dizin Yapısını Düzenle#

Dönüştürmeden sonra etiket dosyalarının görüntülerinin yanına yerleştirilmesi gerekir. YOLO, images/ dizinini yansıtan bir labels/ dizini bekler:

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

Son veri kümesi yapın şu şekilde görünmelidir:

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

4. dataset.yaml Dosyası Oluştur#

COCO kategorilerini YOLO sınıf adlarına eşleyen bir dataset.yaml yapılandırma dosyası oluştur. Bu dosya YOLO'ya verilerinin nerede olduğunu ve hangi sınıfları algılayacağını bildirir:

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)

Ortaya çıkan YAML dosyası:

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

Veri kümesi YAML formatı hakkında daha fazla ayrıntı için veri kümesi yapılandırma kılavuzuna bak.

5. YOLO Modelini Eğit#

Dönüştürülmüş veri kümen hazır olduğunda bir YOLO modelini eğit:

Dönüştürülmüş COCO verileri üzerinde eğitim
from ultralytics import YOLO

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

Eğitim ipuçları ve en iyi uygulamalar için model eğitimi kılavuzuna bak.

6. Dönüştürmeni Doğrula#

Eğitimden önce, sınıf kimliklerinin ve koordinatların doğru olduğunu doğrulamak için birkaç etiket dosyasını rastgele kontrol et:

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}"
İpucu

Negatif sınıf kimlikleri görüyorsan COCO JSON dosyan muhtemelen 0'dan başlayan category_id değerlerini kullanıyordur. convert_coco() komutunu çalıştırmadan önce JSON dosyandaki tüm category_id değerlerine 1 ekle; çünkü bu komut sınıf kimliklerini category_id - 1 olarak eşler.

Yaygın Sorunları Giderme#

Dönüştürme Sonrası Yanlış Sınıf Kimlikleri#

Modelin eğitiliyor ancak yanlış nesne sınıflarını algılıyorsa özel bir veri kümesinde muhtemelen cls91to80=True (varsayılan) kullanıyorsun. Bu, category_id değerlerini yalnızca standart COCO veri kümesi için doğru olan COCO 91'den 80'e arama tablosu üzerinden eşler. COCO-80 karşılığı olmayan bir category_id, hiçbir şeye eşlenmez ve yanlış etiketler üretmek yerine dönüştürme sırasında TypeError: must be real number, not NoneType hatası verir.

Çözüm: Özel veri kümeleri için her zaman cls91to80=False kullan.

Eğitim Sırasında Etiket Bulunamadı#

Etiket taraması 0 images, N backgrounds bildiriyor ve eğitim ardından ValueError: train: No labels found in .../labels/train.cache ile duruyorsa etiket dosyaların beklenen dizinde değildir. convert_coco(), etiketleri ayrı bir çıktı dizinine (ör. save_dir/labels/train/) kaydeder, ancak YOLO veri kümesi dizinin içinde images/ dizinine paralel bir labels/ bekler.

Çözüm: Etiket dosyalarını beklenen dizin yapısına uyacak şekilde taşı. labels/train/ dizininin images/train/ diziniyle aynı seviyede olduğundan emin ol.

Dönüştürme Sırasında KeyError#

convert_coco() çalıştırılırken KeyError: 'bbox' veya benzeri hatalar alıyorsan labels_dir muhtemelen farklı bir anotasyon yapısına sahip örnek dışı JSON dosyaları (ör. captions_train2017.json) içeriyordur.

Çözüm: labels_dir içine yalnızca örnek anotasyonu JSON dosyaları (ör. instances_train2017.json) yerleştir.

Dönüştürme Sonrası Boş Etiket Dosyaları#

Dönüştürme tamamlandığında .txt dosyaları boş veya eksikse tüm anotasyonlarda iscrowd: 1 bulunuyor olabilir (SAM tarafından oluşturulan maskelerde yaygındır) ya da sınırlayıcı kutuların genişliği veya yüksekliği sıfırdır. use_keypoints=True ile yalnızca algılama içeren bir dışa aktarım üzerinde çalıştırmak da aynı sonucu verir; çünkü keypoints alanı olmayan anotasyonlar tamamen atlanır.

Çözüm: JSON anotasyonlarında iscrowd değerlerini incele. SAM maskeleri kullanıyorsan iscrowd: 0 değerini ayarlamak için JSON dosyasını önceden işle. use_keypoints=True ilettiysen anotasyonlarında gerçekten keypoints bulunduğunu doğrula.

Maske Anotasyonlarından Kutu Biçimli Çokgenler#

use_segments=True, annotations without a usable polygon günlüğünü kaydediyorsa bazı anotasyonlarda segmentation değeri yoktur veya bu değer en az üç koordinat çifti içeren bir liste değildir. Bunun yaygın nedenleri, alanı eksik veya boş bırakan yalnızca algılama içeren dışa aktarımlar ile SAM gibi bit maskesi dışa aktarıcılarının yazdığı COCO çalışma uzunluğu kodlamasıdır ({"counts": ..., "size": ...}); çevreleyen çokgen listesi olmayan düz koordinat listeleri, bir ve iki noktalı ana hatlar ve diğer hatalı biçimlendirilmiş değerler de aynı şekilde işlenir. Bir anotasyon, geriye kalan çokgenleri korur ve hiçbiri kalmadığında sınırlayıcı kutusu şeklinde bir segment satırına geri döner; böylece etiketler geçerli kalır, ancak bu satırlarda maske ayrıntısı bulunmaz.

Çözüm: Anotasyonları çokgen segmentasyonlarıyla yeniden dışa aktar, convert_coco() komutunu çalıştırmadan önce RLE maskelerini çokgenlere dönüştür veya hatalı segmentation değerlerini düzelt.

Dönüştürülen Etiketlerde Sınıf Kimliği Boşlukları#

Etiket dosyalarındaki sınıf kimlikleri bitişik değilse (ör. 0, 1, 2 yerine 0, 4, 9), anotasyon aracın bitişik olmayan category_id değerleri kullanıyordur.

Çözüm: .txt dosyalarındaki sınıf kimliklerinin dataset.yaml içindeki names sözlüğüyle eşleştiğini doğrula. Gerekirse kimlikleri bitişik değerlere yeniden eşle.

Tam API ayrıntıları ve parametre açıklamaları için convert_coco API referansına bak.

SSS#

  • COCO JSON anotasyonlarını YOLO .txt formatına dönüştürmek için Ultralytics'teki convert_coco() işlevini kullan. Özel veri kümeleri için cls91to80=False değerini ayarla:

    from ultralytics.data.converter import convert_coco
    
    convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)

    Dönüştürmeden sonra etiket dosyalarını labels/, images/ dizinini yansıtacak şekilde yeniden düzenle ve ardından bir dataset.yaml dosyası oluştur. İş akışının tamamı için adım adım kılavuza bak.

  • Bunun nedeni convert_coco() etiketleri save_dir/labels/ içinde bir alt dizine (ör. save_dir/labels/train/) kaydederken bunları veri kümenin labels/train/ dizinine, images/train/ dizininin yanına doğrudan kaydetmemesidir. YOLO, etiketlerin görüntülere paralel olmasını bekler — örneğin images/train/img.jpg için labels/train/img.txt gerekir. Dönüştürülen etiketlerini bu yapıya uyacak şekilde taşı. Dizin yapısını düzeltme bölümüne bak.

  • cls91to80 parametresi, COCO category_id değerlerinin YOLO sınıf kimliklerine nasıl eşleneceğini denetler. True (varsayılan) olduğunda standart COCO veri kümesi için tasarlanmış coco91_to_coco80_class() arama tablosunu uygular; bu veri kümesinde bitişik olmayan kimliklere (1-90) sahip 80 sınıf bulunur. Özel veri kümeleri için her zaman cls91to80=False değerini ayarla — bu işlem, sıfır tabanlı sınıf kimlikleri oluşturmak için her category_id değerinden yalnızca 1 çıkarır.

  • Özel kod olmadan yapamazsın. Varsayılan eğitim işlem hattı, her görüntü için bir dosya olacak şekilde YOLO .txt etiketlerini bekler; bu nedenle ya convert_coco() komutunu çalıştırıp bu adım adım kılavuzu izle ya da COCO JSON dosyasını anında ayrıştırmak için veri kümesi sınıfını alt sınıflandır — Dönüştürme Olmadan COCO JSON Üzerinde YOLO Eğitimi bölümüne bak. Desteklenen formatlar hakkında daha fazla bilgi için veri kümesi formatlarına bak.

  • Evet, dönüştürülen YOLO etiketlerine çokgen segmentasyon maskelerini eklemek için convert_coco() çağrılırken use_segments=True kullan. Bu işlem YOLO segmentasyon modelleri ile uyumlu etiket dosyaları oluşturur:

    from ultralytics.data.converter import convert_coco
    
    convert_coco(labels_dir="annotations/", save_dir="output/", use_segments=True, cls91to80=False)
  • Poz tahmini eğitimi için COCO anahtar noktası anotasyonlarını dönüştürmek üzere use_keypoints=True kullan:

    from ultralytics.data.converter import convert_coco
    
    convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)

    Hem use_segments hem de use_keypoints True olarak ayarlanırsa etiket dosyalarına yalnızca anahtar noktaların yazılacağını unutma — segmentler sessizce yok sayılır.

Yorumlar