Meet YOLO26: next-gen vision AI.

Link to this sectionكيفية تحويل تعليقات COCO التوضيحية إلى تنسيق YOLO#

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

هل تفضل تخطي عملية التحويل؟

للتدريب مباشرة على COCO JSON دون إنشاء ملفات .txt، راجع تدريب YOLO على COCO JSON دون تحويل.

Link to this sectionلماذا التحويل من 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 (يمكن أن تبدأ من أي رقم)مفهرسة من الصفر (تبدأ من 0)
التجزئة (Segmentation)مصفوفات مضلع في حقل segmentationإحداثيات المضلع بعد معرف الفئة
النقاط الرئيسية (Keypoints)[x, y, visibility, ...] بالبكسل[x, y, visibility, ...] مطبع

Link to this sectionبدء التشغيل السريع#

أسرع طريقة لتحويل تعليقات COCO التوضيحية وبدء التدريب:

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

بعد التحويل، نظم هيكل دليلك، وأنشئ ملف dataset.yaml، وابدأ التدريب. راجع دليل خطوة بخطوة الكامل أدناه.

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

الإعداد الافتراضي cls91to80=True مصمم فقط لـ مجموعة بيانات COCO القياسية التي تحتوي على 80 فئة كائنات، والتي تقوم بتعيين 91 معرف فئة غير متسلسل إلى 80 معرف فئة متسلسل. بالنسبة لأي مجموعة بيانات مخصصة، يجب عليك تعيين cls91to80=False — وإلا سيتم تعيين معرفات الفئات الخاصة بك بشكل غير صحيح ضمنياً وسيتعلم نموذجك فئات خاطئة.

Link to this sectionدليل التحويل خطوة بخطوة#

Link to this sectionجهز مجموعة بيانات 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" }
    ]
}

Link to this sectionتحويل التعليقات التوضيحية#

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

تقوم convert_coco() بكتابة ملف .txt واحد لكل صورة مصنفة داخل مجلد فرعي labels/ يحمل اسم ملف JSON المقابل، مع إزالة البادئة instances_ (لذا ينتج عن instances_train.json المجلد labels/train/). يتم تخطي الصور التي لا تحتوي على تصنيفات ولا يتم إنشاء ملف تسمية لها، لذلك قد لا تعكس شجرة labels/ كل صورة:

my_dataset/converted/
└── labels/
    ├── train/   # from instances_train.json
    │   ├── img_001.txt
    │   └── ...
    └── val/     # from instances_val.json
        └── ...
إعادة التشغيل تنشئ مجلد مخرجات جديداً

لا تقوم convert_coco() أبداً بالكتابة فوق save_dir موجود: إذا كان my_dataset/converted/ موجوداً بالفعل، فستكتب عملية إعادة التشغيل في my_dataset/converted-2/ بدلاً من ذلك. احذف المخرجات السابقة (أو قم بتغيير save_dir) قبل إعادة التشغيل، وإلا فإن الخطوات التالية ستقرأ تسميات قديمة.

Link to this sectionتنظيم هيكل الدليل#

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

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

يجب أن يبدو هيكل مجموعة البيانات النهائي الخاص بك كالتالي:

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

Link to this sectionإنشاء 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، راجع دليل تكوين مجموعة البيانات.

Link to this sectionتدريب نموذج 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)

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

Link to this sectionالتحقق من التحويل الخاص بك#

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

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.

Link to this sectionاستكشاف الأخطاء وإصلاحها الشائعة#

Link to this sectionمعرفات فئات خاطئة بعد التحويل#

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

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

Link to this sectionلم يتم العثور على تسميات أثناء التدريب#

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

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

Link to this sectionخطأ KeyError أثناء التحويل#

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

الحل: ضع فقط ملفات JSON لتعليقات المثيلات التوضيحية (على سبيل المثال، instances_train2017.json) في labels_dir.

Link to this sectionملفات تسمية فارغة بعد التحويل#

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

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

Link to this sectionفجوات في معرفات الفئات في التسميات المحولة#

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

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

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

Link to this sectionالأسئلة الشائعة#

Link to this sectionكيف يمكنني تحويل تعليقات 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. راجع دليل خطوة بخطوة لسير العمل الكامل.

Link to this sectionلماذا يُظهر تدريب YOLO "لم يتم العثور على تسميات" بعد تحويل COCO؟#

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

Link to this sectionماذا تفعل cls91to80 في convert_coco()؟#

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

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

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

Link to this sectionهل يمكنني تحويل تعليقات 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)

Link to this sectionكيف يمكنني تحويل تعليقات COCO التوضيحية للنقاط الرئيسية إلى تنسيق YOLO؟#

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

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، فسيتم كتابة النقاط الرئيسية فقط في ملفات التسمية — سيتم تجاهل القطاعات ضمناً.

التعليقات