COCO Açıklamalarını YOLO Biçimine Dönüştürme#
Ultralytics YOLO modellerini eğitmek için YOLO biçiminde açıklamalar gerekir; ancak birçok popüler açıklama aracı bunun yerine COCO JSON biçiminde dışa aktarım yapar. Bu kılavuz, COCO açıklamalarını YOLO biçimine 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.
.txt dosyaları oluşturmadan doğrudan COCO JSON ile eğitim yapmak için Dönüştürme Yapmadan COCO JSON ile YOLO Eğitimi sayfasına bak.
Neden COCO'dan YOLO'ya Dönüştürmeli?#
COCO JSON biçimi tüm açıklamaları tek bir dosyada saklarken YOLO, normalize edilmiş koordinatları içeren her görüntü için bir metin dosyası kullanır. Dönüştürme şu nedenlerle gereklidir:
- YOLO modelleri, normalize edilmiş koordinatlarda
class x_center y_center width heightiçeren ve her görüntü için bir dosyadan oluşan.txtetiket dosyalarını gerektirir. - COCO JSON, tüm görüntüler için tek bir JSON dosyası kullanarak
[x_min, y_min, width, height]biçiminde piksel koordinatları tutar. - Sınıf kimlikleri farklıdır — COCO rastgele
category_iddeğerleri kullanırken YOLO sıfır tabanlı sınıf kimlikleri gerektirir.
| Özellik | COCO JSON | YOLO TXT |
|---|---|---|
| Yapı | Tüm görüntüler için tek bir JSON dosyası | Her görüntü için bir .txt dosyası |
| BBox biçimi | Piksel cinsinden [x_min, y_min, width, height] | class x_center y_center width height normalize edildi (0-1) |
| Sınıf Kimlikleri | category_id (herhangi bir sayıdan başlayabilir) | Sıfır tabanlı (0'dan başlar) |
| Segmentasyon | segmentation alanındaki poligon dizileri | Sınıf kimliğinden sonraki poligon koordinatları |
| Anahtar Noktalar | Piksel cinsinden [x, y, visibility, ...] | [x, y, visibility, ...] normalize edildi |
Hızlı Başlangıç#
COCO açıklamalarını dönüştürmenin ve eğitime başlamanın en hızlı yolu:
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/", # JSON dosyalarını içeren dizin
save_dir="my_dataset/converted/", # Dönüştürülen etiketlerin kaydedileceği konum
cls91to80=False, # Özel veri kümeleri için False olarak ayarla (aşağıdaki uyarıya bak)
)Dönüştürme işleminden sonra dizin yapını düzenle, bir dataset.yaml oluştur ve eğitime başla. Aşağıdaki tüm adım adım kılavuza bak.
cls91to80=True varsayılanı, 91 kesintili kategori kimliğini 80 kesintisiz sınıf kimliğine eşleyen 80 nesne sınıflı standart COCO veri kümesi yalnızca bu veri kümesi için tasarlanmıştır. Herhangi bir özel veri kümesi için cls91to80=False ayarını mutlaka yapmalı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#
Açıklama araçlarından dışa aktarılan tipik bir COCO biçimli veri kümesi şu yapıya sahiptir:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ └── val/
│ ├── img_100.jpg
│ └── ...
└── annotations/
├── instances_train.json
└── instances_val.jsonHer JSON dosyası, üç zorunlu alanı — images, annotations ve categories — içeren COCO veri biçimi belirtimine uyar:
{
"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. Açıklamaları Dönüştür#
COCO JSON açıklamalarını YOLO .txt biçimine dönüştürmek için convert_coco() işlevini kullan:
from ultralytics.data.converter import convert_coco
convert_coco(
labels_dir="my_dataset/annotations/",
save_dir="my_dataset/converted/",
cls91to80=False,
)convert_coco(), açıklama içeren her görüntü için .txt dosyasını, her JSON dosyasının adını taşıyan ve instances_ öneki kaldırılmış bir labels/ alt dizinine yazar (yani instances_train.json, labels/train/ dosyasını oluşturur). Açıklaması olmayan görüntüler atlanır ve etiket dosyası oluşturulmaz; 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
└── ...convert_coco(), mevcut bir save_dir dosyasının üzerine asla yazmaz: my_dataset/converted/ zaten varsa, yeniden çalıştırma çıktıyı 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 eski etiketleri okur.
3. Dizin Yapısını Düzenle#
Dönüştürme işleminden sonra etiket dosyalarının görüntülerin 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 her alt dizine JSON dosyasının adını verir ("instances_" öneki çıkarılmış olarak),
# bu nedenle "train"/"val" varsaymak yerine mevcut alt dizinleri yinele.
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 şöyle görünmelidir:
my_dataset/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ └── ...
│ └── val/
│ └── ...
├── labels/
│ ├── train/
│ │ ├── img_001.txt
│ │ └── ...
│ └── val/
│ └── ...
└── dataset.yaml4. dataset.yaml Oluştur#
COCO kategorilerini YOLO sınıf adlarıyla eşleyen bir dataset.yaml yapılandırma dosyası oluştur. Bu dosya YOLO'ya verilerinin konumunu ve hangi sınıfları algılayacağını bildirir:
import json
from pathlib import Path
import yaml
# Kategorileri COCO JSON dosyanızdan oku
with open("my_dataset/annotations/instances_train.json") as f:
coco = json.load(f)
# convert_coco çıktısıyla eşleşen sınıf adlarını oluştur (category_id - 1)
categories = sorted(coco["categories"], key=lambda x: x["id"])
names = {cat["id"] - 1: cat["name"] for cat in categories}
# NOT: convert_coco, sınıf kimliklerini category_id - 1 olarak eşler; bu nedenle category_id şu değerden
# başlamalıdır: 1. Kategorilerin 0'dan başlıyorsa, önce her kimliğe 1 ekle.
# dataset.yaml oluştur
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: vestVeri kümesi YAML biçimiyle ilgili daha fazla bilgi 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ğuna göre bir YOLO modelini eğit:
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # önceden eğitilmiş bir modeli yükle
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ürme İşlemini Doğrula#
Eğitimden önce sınıf kimliklerinin ve koordinatların doğru olduğunu doğrulamak için birkaç etiket dosyasını 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}"Negatif sınıf kimlikleri görüyorsan COCO JSON dosyan muhtemelen 0'dan başlayan category_id kullanıyordur. convert_coco() dosyasını çalıştırmadan önce JSON dosyandaki tüm category_id değerlerine 1 ekle; çünkü sınıf kimliklerini category_id - 1 olarak eşler.
Yaygın Sorunları Giderme#
Dönüştürme Sonrasında Yanlış Sınıf Kimlikleri#
Modelin eğitiliyor ancak yanlış nesne sınıflarını algılıyorsa, özel bir veri kümesinde cls91to80=True (varsayılan) kullanıyor olabilirsin. Bu, category_id değerlerini COCO 91'den 80'e arama tablosuyla eşler; bu işlem yalnızca standart COCO veri kümesi için doğrudur. COCO-80'de karşılığı olmayan bir category_id, hiçbir değerle 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 hatasıyla 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 dizininin içinde images/ dizininin yanındaki labels/ dizinini bekler.
Çözüm: Etiket dosyalarını beklenen dizin yapısına uyacak şekilde taşı. labels/train/ ile images/train/ dizinlerinin aynı üst dizinde olduğundan emin ol.
Dönüştürme Sırasında KeyError#
convert_coco() çalıştırırken KeyError: 'bbox' veya benzer hatalar alıyorsan, labels_dir muhtemelen farklı bir açıklama yapısına sahip örnek olmayan JSON dosyaları (ör. captions_train2017.json) içeriyordur.
Çözüm: labels_dir içine yalnızca örnek açıklama JSON dosyalarını (ör. instances_train2017.json) koy.
Dönüştürme Sonrasında Boş Etiket Dosyaları#
Dönüştürme tamamlandığı hâlde .txt dosyaları boşsa veya eksikse, tüm açıklamalarda 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. Algılama amaçlı bir dışa aktarma üzerinde use_keypoints=True ile çalıştırmak da aynı sonucu verir; çünkü keypoints alanı olmayan açıklamalar tamamen atlanır.
Çözüm: JSON açıklamalarındaki iscrowd değerlerini incele. SAM maskeleri kullanıyorsan, iscrowd: 0 değerini ayarlamak için JSON'u ön işlemden geçir. use_keypoints=True kullandıysan, açıklamalarında gerçekten keypoints bulunduğunu doğrula.
Maske Açıklamalarından Oluşan Kutu Biçimli Poligonlar#
use_segments=True, annotations without a usable polygon kaydını tutuyorsa bazı açıklamalarda segmentation değeri yoktur veya bu değer en az üç koordinat çifti içeren bir liste değildir. Bunun yaygın nedenleri, alanı boş bırakan ya da içermeyen yalnızca algılama amaçlı dışa aktarımlar ve SAM gibi bit maskesi dışa aktarıcılarının yazdığı COCO çalışma uzunluğu kodlamasıdır ({"counts": ..., "size": ...}); çevresinde poligon listesi bulunmayan düz koordinat listeleri, bir veya iki noktalı dış hatlar ve diğer hatalı değerler de aynı şekilde işlenir. Bir açıklama, geçerli kalan poligonları kullanır; geçerli poligon yoksa sınırlayıcı kutusuyla aynı biçime sahip bir segment satırına geri döner. Böylece etiketler geçerliliğini korur ancak bu satırlarda maske ayrıntısı bulunmaz.
Çözüm: Açıklamaları poligon segmentasyonlarıyla yeniden dışa aktar, convert_coco() çalıştırmadan önce RLE maskelerini poligonlara dönüştür veya hatalı segmentation değerlerini düzelt.
Dönüştürülen Etiketlerdeki Sınıf Kimliği Boşlukları#
Etiket dosyalarındaki sınıf kimlikleri kesintisiz değilse (ör. 0, 1, 2 yerine 0, 4, 9), açıklama aracın kesintisiz 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 kesintisiz değerlere yeniden eşle.
Tüm API ayrıntıları ve parametre açıklamaları için convert_coco API referansına bak.
Sık Sorulan Sorular#
COCO JSON açıklamalarını YOLO
.txtbiçimine dönüştürmek için Ultralytics'tekiconvert_coco()işlevini kullan. Özel veri kümeleri içincls91to80=Falseayarını yap:from ultralytics.data.converter import convert_coco convert_coco(labels_dir="path/to/annotations/", save_dir="output/", cls91to80=False)Dönüştürme işleminden sonra etiket dosyalarını
labels/,images/dizinini yansıtacak şekilde yeniden düzenle ve ardından birdataset.yamldosyası oluştur. Tüm iş akışı için adım adım kılavuza bak.Bunun nedeni
convert_coco()dosyasının etiketleri doğrudan veri kümen içindekilabels/train/konumuna,images/train/dizininin yanına değil,save_dir/labels/içindeki bir alt dizine (ör.save_dir/labels/train/) kaydetmesidir. YOLO, etiketlerin görüntülerle aynı düzeyde olmasını bekler; örneğinimages/train/img.jpgiçinlabels/train/img.txtgerekir. Dönüştürülen etiketlerini bu yapıya uyacak şekilde taşı. Dizin yapısını düzeltme bölümüne bak.cls91to80parametresi, COCOcategory_iddeğerlerinin YOLO sınıf kimliklerine nasıl eşleneceğini belirler.True(varsayılan) olduğunda, 80 sınıfı ve kesintisiz olmayan kimlikleri (1-90) bulunan standart COCO veri kümesi için tasarlanmışcoco91_to_coco80_class()arama tablosunu uygular. Özel veri kümeleri için her zamancls91to80=Falseayarını yap; bu, sıfır tabanlı sınıf kimlikleri oluşturmak için hercategory_iddeğerinden yalnızca 1 çıkarır.Özel kod olmadan mümkün değil. Varsayılan eğitim iş akışı, her görüntü için bir dosya içeren YOLO
.txtetiketlerini bekler. Bu nedenleconvert_coco()komutunu çalıştırıp bu adım adım kılavuzu izle veya COCO JSON'u anında ayrıştırmak için veri kümesi sınıfını alt sınıflandır ve Dönüştürmeden YOLO'yu COCO JSON ile Eğit bölümüne bak. Desteklenen biçimler hakkında daha fazla bilgi için veri kümesi biçimlerine bak.Evet, dönüştürülen YOLO etiketlerine poligon segmentasyon maskelerini eklemek için
convert_coco()çağrısındause_segments=Truekullan. Böylece YOLO segmentasyon modelleri ile uyumlu etiket dosyaları oluşturulur: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 nokta açıklamalarını dönüştürmek üzere
use_keypoints=Truekullan:from ultralytics.data.converter import convert_coco convert_coco(labels_dir="annotations/", save_dir="output/", use_keypoints=True, cls91to80=False)Hem
use_segmentshem deuse_keypointsdeğeriTrueolarak ayarlanırsa etiket dosyalarına yalnızca anahtar noktaların yazılacağını, segmentlerin ise sessizce yok sayılacağını unutma.