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 çokgen dizileri veya RLE maskeleri | 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
from ultralytics.utils 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,
}
YAML.save("my_dataset/dataset.yaml", dataset)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ğitimi tamamlanıyor ancak yanlış nesne sınıflarını algılıyorsa özel bir veri kümesinde muhtemelen cls91to80=True (varsayılan) kullanıyorsun. Bu ayar, category_id değerlerini COCO 91'den 80'e eşleme tablosuyla dönüştürür; bu tablo yalnızca standart COCO veri kümesi için doğrudur. COCO-80'de karşılığı olmayan bir category_id hiçbir şeye eşlenmez ve dönüştürme sırasında yanlış etiketler üretmek yerine TypeError: must be real number, not NoneType hatasına yol açar.
Çö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 tamamlanmasına rağmen .txt dosyaları boşsa veya eksikse, tüm açıklamalarda iscrowd: 1 bulunabilir ve convert_coco() bunları atlar (örneğin CVAT, maske açıklamalarını kalabalık bölgeleri olarak dışa aktarır) ya da sınırlayıcı kutuların genişliği veya yüksekliği sıfır olabilir. Yalnızca algılama içeren 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. CVAT maske dışa aktarımlarında olduğu gibi, kalabalık olarak işaretlenmiş her maske tek bir nesnenin dış çizgisini gösteriyorsa iscrowd: 0 değerini ayarla; böylece use_segments=True RLE maskesini dönüştürür. Birden çok nesneyi kapsayan gerçek kalabalık bölgelerini işaretli bırak. use_keypoints=True değerini ilettiysen 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 değerini günlüğe kaydediyorsa bazı açıklamalarda segmentation değeri yoktur; bazılarında COCO ardışık tekrar kodlaması ({"counts": ..., "size": ...}) vardır ancak bu kodlamanın size değeri görüntünün [height, width] değeriyle eşleşmez ya da maske boştur veya üç noktayla dış çizgisi oluşturulamayacak kadar küçük ya da ince bölgeler içerir; bazılarında ise RLE olmayan ve en az üç koordinat çiftinden oluşan bir liste de olmayan bir değer bulunur. Bunun olağan nedeni, alanı eksik veya boş bırakan yalnızca algılama içeren bir dışa aktarmadır; çevreleyen çokgen listesi olmayan düz bir koordinat listesi, bir veya iki noktalı dış çizgiler ve diğer hatalı değerler de aynı şekilde işlenir. Bir açıklamada kalan çokgenler korunur; hiçbiri kalmazsa sınırlayıcı kutusuyla aynı biçimde bir segment satırı kullanılır. Böylece etiketler geçerli kalır, ancak bu satırlarda maske ayrıntısı bulunmaz.
counts değerleri eksik olan veya çözümlenemeyen RLE değerleri (örneğin, kesilmiş bir dize ya da toplamı size değerine ulaşmayan çalışma uzunlukları) yedek yönteme başvurmak yerine dönüştürmeyi hatayla durdurur.
Çözüm: Açıklamaları çokgen veya RLE segmentasyonlarıyla yeniden dışa aktar ya da 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 segmentasyon maskelerini dahil etmek için
convert_coco()çağrılırkenuse_segments=Truekullan. Çokgen segmentasyonları doğrudan dönüştürülür; sıkıştırılmış veya sıkıştırılmamış ardışık tekrar kodlamasıyla (RLE) kodlanmış maskeler ise, JSON dosyasında bu maskeler bulunduğunda otomatik olarak yüklenenfaster-coco-evalile çözümlenerek bölgelerin dış çizgilerine dönüştürülür. Birden çok çokgene veya maske bölgesine ayrılmış bir nesne tek bir çokgen satırında birleştirilir; YOLO çokgenlerinde delik bulunamadığından maske delikleri doldurulur. Kalabalık açıklamaları (iscrowd: 1) atlanır. 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.
Yorumlar
Bir soru sor, sonuçlarını paylaş veya başka birine yardım et.