Skip to main content

كيفية تحويل تسميات COCO إلى تنسيق YOLO

تدريب نماذج Ultralytics YOLO يتطلب تسميات بتنسيق YOLO، ولكن العديد من أدوات التسمية الشائعة تصدر البيانات بتنسيق COCO JSON بدلاً من ذلك. يوضح هذا الدليل كيفية تحويل تسميات COCO الخاصة بك إلى تنسيق YOLO وبدء تدريب اكتشاف الكائنات, تجزئة النماذج (instance segmentation)، و تقدير الوضع (pose estimation) المدربة جيداً.

لماذا نقوم بالتحويل من COCO إلى YOLO؟

يخزن تنسيق COCO JSON جميع التسميات في ملف واحد، بينما يستخدم YOLO ملف نصي واحد لكل صورة بإحداثيات طبيعية. التحويل ضروري للأسباب التالية:

  • تتطلب نماذج YOLO ملفات .txt تسميات تحتوي على ملف واحد لكل صورة، متضمنة class x_center y_center width height بإحداثيات طبيعية.
  • يستخدم COCO JSON تنسيق إحداثيات البكسل في [x_min, y_min, width, height] مع ملف JSON واحد لجميع الصور.
  • تختلف معرفات الفئات (Class IDs) — يستخدم COCO قيم category_id عشوائية، بينما يتطلب YOLO معرفات فئات تبدأ من الصفر.
الميزةCOCO JSONYOLO TXT
الهيكلملف JSON واحد لجميع الصورملف .txt واحد لكل صورة
تنسيق Bbox[x_min, y_min, width, height] بالبكسلclass x_center y_center width height طبيعي (0-1)
معرفات الفئاتcategory_id (يمكن أن تبدأ من أي رقم)تبدأ من الصفر (Zero-indexed)
التجزئة (Segmentation)مصفوفات المضلعات في segmentation الحقلإحداثيات المضلع بعد معرف الفئة
Keypoints[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 الإعداد الافتراضي مصمم فقط لمعيار مجموعة بيانات COCO الذي يحتوي على 80 فئة كائنات، والذي يربط 91 معرف فئة غير متسلسل بـ 80 معرف فئة متسلسل. لأي مجموعة بيانات مخصصة، يجب عليك تعيين بشكل إلزامي اضبط cls91to80=False — وإلا سيتم ربط معرفات الفئات الخاصة بك بشكل غير صحيح تلقائياً وسيتعلم نموذجك فئات خاطئة.

دليل التحويل خطوة بخطوة

1. تجهيز مجموعة بيانات 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 مع ثلاثة حقول مطلوبة — images, annotations، و 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. تحويل التسميات

استخدم أمر 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,
)

3. تنظيم هيكل الدليل

بعد التحويل، يجب وضع ملفات التسميات بجانب صورك. يتوقع YOLO وجود دليل labels/ يعكس دليل images/ الخاص بك:

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

4. إنشاء dataset.yaml

إنشاء ملف dataset.yaml ملف تكوين يربط فئات COCO الخاصة بك بأسماء فئات YOLO. يخبر هذا الملف 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

لمزيد من التفاصيل حول تنسيق dataset YAML، راجع دليل تكوين مجموعة البيانات.

5. تدريب نموذج 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)

للحصول على نصائح التدريب وأفضل الممارسات، راجع دليل تدريب النماذج.

6. التحقق من عملية التحويل

قبل التدريب، تحقق من بعض ملفات التسميات للتأكد من صحة معرفات الفئات والإحداثيات:

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}"
تلميح

إذا رأيت معرفات فئات سالبة، فمن المحتمل أن ملف COCO JSON الخاص بك يستخدم category_id تبدأ من 0. أضف 1 إلى جميع قيم category_id في ملف JSON الخاص بك قبل تشغيل convert_coco()، حيث يقوم بتعيين معرفات الفئات كـ category_id - 1.

استكشاف المشكلات الشائعة وإصلاحها

معرفات فئات خاطئة بعد التحويل

إذا كان نموذجك يتدرب ولكنه يكتشف فئات كائنات خاطئة، فمن المحتمل أنك تستخدم cls91to80=True (افتراضي) على مجموعة بيانات مخصصة. هذا يربط قيم category_id الخاصة بك من خلال جدول البحث COCO 91-to-80، وهو صحيح فقط للمعايير مجموعة بيانات COCO.

الحل: استخدم دائماً cls91to80=False لمجموعات البيانات المخصصة.

لم يتم العثور على تسميات أثناء التدريب

إذا أظهر التدريب WARNING: No labels found أو 0 images, N backgrounds، فهذا يعني أن ملفات التسميات الخاصة بك ليست في الدليل المتوقع. convert_coco() يحفظ التسميات في دليل إخراج منفصل (على سبيل المثال، save_dir/labels/train/)، لكن YOLO يتوقع labels/ موازياً لـ images/ داخل دليل مجموعة البيانات الخاصة بك.

الحل: انقل ملفات التسميات لتطابق هيكل الدليل المتوقع. تأكد من labels/train/ هو شقيق لـ images/train/.

خطأ KeyError أثناء التحويل

إذا واجهت KeyError: 'bbox' أو أخطاء مشابهة عند تشغيل convert_coco()، فمن المحتمل أن يحتوي labels_dir الخاص بك على ملفات JSON لا تمثل حالات (مثلاً: captions_train2017.json) والتي تمتلك بنية توضيحية مختلفة.

الحل: ضع فقط ملفات JSON الخاصة بتوضيحات الحالات (مثلاً: instances_train2017.json) داخل labels_dir.

ملفات تصنيف فارغة بعد التحويل

إذا اكتمل التحويل ولكن ملفات .txt كانت فارغة أو مفقودة، فقد تكون جميع التوضيحات تمتلك iscrowd: 1 (أمر شائع مع الأقنعة الناتجة عن SAM)، أو أن صناديق التحديد (bounding boxes) تمتلك عرضاً أو ارتفاعاً يساوي صفراً.

الحل: افحص توضيحات JSON بحثاً عن قيم iscrowd. إذا كنت تستخدم أقنعة SAM، فقم بمعالجة JSON مسبقاً لتعيين iscrowd: 0.

فجوات في معرفات الفئات في الملصقات المحولة

إذا كانت معرفات الفئات في ملفات الملصقات غير متصلة (مثلاً: 0، 4، 9 بدلاً من 0، 1، 2)، فإن أداة التوضيح الخاصة بك تستخدم قيم category_id غير متصلة.

الحل: تحقق من أن معرفات الفئات في ملفات .txt الخاصة بك تطابق قاموس names في dataset.yaml. أعد تعيين المعرفات إلى قيم متصلة إذا لزم الأمر.

للحصول على تفاصيل API الكاملة وأوصاف المعلمات، راجع convert_coco مرجع API.

الأسئلة الشائعة

كيف يمكنني تحويل توضيحات COCO JSON إلى تنسيق YOLO؟

استخدم أمر convert_coco() دالة من Ultralytics لتحويل توضيحات 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. راجع الدليل التفصيلي لسير العمل الكامل.

لماذا يظهر تدريب YOLO رسالة "No labels found" بعد التحويل من COCO؟

يحدث هذا لأن convert_coco() يحفظ الملصقات في دليل فرعي داخل save_dir/labels/ (على سبيل المثال، save_dir/labels/train/) بدلاً من وضعها مباشرة في labels/train/ بجانب images/train/ الخاص بمجموعة بياناتك. يتوقع YOLO أن تكون الملصقات موازية للصور - على سبيل المثال، images/train/img.jpg يحتاج إلى labels/train/img.txt. انقل الملصقات المحولة لتطابق هذا الهيكل. راجع إصلاح هيكل الدليل.

ماذا يفعل cls91to80 في convert_coco()?

يمكن تهيئة الوسيط cls91to80 تتحكم المعلمة في كيفية تعيين قيم COCO category_id إلى معرفات فئات YOLO. عندما تكون True (الافتراضي)، فإنها تستخدم جدول بحث مصمماً لـ مجموعة بيانات COCO القياسي، والذي يحتوي على 80 فئة ذات معرفات غير متصلة (1-90). بالنسبة لـ مجموعات البيانات المخصصة، قم دائماً بتعيين cls91to80=False — هذا ببساطة يطرح 1 من كل category_id لإنشاء معرفات فئات تبدأ من الصفر.

هل يمكنني تدريب YOLO مباشرة على COCO JSON دون تحويل؟

ليس مع خط أنابيب تدريب YOLO الحالي — يجب أن تكون التوضيحات بتنسيق YOLO .txt مع ملف واحد لكل صورة. استخدم convert_coco() لتحويل COCO JSON أولاً، ثم اتبع هذا دليلنا للتنظيم والتدريب. للمزيد حول التنسيقات المدعومة، راجع تنسيقات مجموعات البيانات.

هل يمكنني تحويل توضيحات تجزئة COCO إلى تنسيق YOLO؟

نعم، استخدم use_segments=True عند استدعاء convert_coco() لتضمين أقنعة تجزئة المضلع في ملصقات YOLO المحولة. هذا ينتج ملفات ملصقات متوافقة مع نماذج تجزئة YOLO:

from ultralytics.data.converter import convert_coco

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

كيف يمكنني تحويل توضيحات النقاط الرئيسية لـ COCO إلى تنسيق YOLO؟

استخدم use_keypoints=True لتحويل توضيحات النقاط الرئيسية لـ COCO لتدريب تقدير الوضع (pose estimation):

from ultralytics.data.converter import convert_coco

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

لاحظ أنه إذا تم تعيين كلاً من use_segments و use_keypoints على True، فسيتم كتابة النقاط الرئيسية فقط في ملفات الملصقات — يتم تجاهل التجزئات بصمت.

التعليقات