Ultralytics YOLO27:
Get Started

كيفية عزل الكائنات المُجزّأة باستخدام Ultralytics YOLO#

ينتج تقسيم الكائنات قناعًا دقيقًا على مستوى البكسل لكل كائن مكتشف، ما يتيح لك استخراج كل كائن منفردًا من الصورة. يوضح هذا الدليل كيفية تحويل نتائج تقسيم Ultralytics YOLO إلى كائنات معزولة باستخدام وضع التنبؤ وOpenCV، مع خلفية سوداء مصمتة أو خلفية شفافة لحفظ الصور بصيغة PNG.



شاهد: كيفية إزالة الخلفية وعزل الكائنات باستخدام تقسيم Ultralytics YOLO وOpenCV في Python 🚀

لماذا نعزل الكائنات المُجزّأة؟#

يفتح استخراج الكائنات الفردية من الصورة المجال أمام مجموعة من مهام المعالجة اللاحقة:

  • إزالة الخلفية لصور المنتجات أو الكتالوجات أو التحرير الإبداعي.
  • قصاصات لكل كائن لإنشاء مجموعات بيانات التصنيف من نتائج الكشف.
  • المعالجة المركزة كي لا ترى الخطوات اللاحقة، مثل OCR أو تحليل الألوان أو القياس، سوى الكائن دون المشهد المحيط به.
  • تصدير PNG بخلفية شفافة لتركيب الكائنات على خلفيات جديدة.

تعمل هذه الطريقة مع أي نموذج لتقسيم الصور من Ultralytics YOLO وتتبع أربع مراحل: تشغيل الاستدلال → استخراج كل محيط → عزل الكائن → حفظ النتيجة.

تشغيل استدلال التقسيم#

ثبّت المكتبات المطلوبة، ثم حمّل نموذجًا للتقسيم (اللاحقة -seg مطلوبة لإنتاج الأقنعة) وشغّل التنبؤ على الصورة المصدر:

from ultralytics import YOLO

# ⁨تحميل نموذج للتقسيم⁩
model = YOLO("yolo26n-seg.pt")

# ⁨تشغيل الاستدلال على مصدر⁩
results = model.predict(source="path/to/image.jpg")
ليس لديك مصدر؟ يستخدم YOLO صور العينات المرفقة

إذا استدعيت model.predict() دون تحديد source، فسيستخدم Ultralytics صور الأمثلة المرفقة مع الحزمة (bus.jpg وzidane.jpg)، وهو أمر مفيد لاختبار سير العمل بسرعة.

استخراج محيطات الكائنات#

يتوافق كل عنصر في results مع صورة واحدة، ويؤدي التكرار على النتيجة إلى إرجاع كشف واحد في كل مرة. لكل كشف، انسخ الصورة الأصلية، واقرأ تسمية الفئة، وارسم محيط قناع الكائن على قناع ثنائي فارغ. تحدد المنطقة البيضاء في هذا القناع بدقة البكسلات التي تنتمي إلى الكائن.

تُنفذ المقاطع البرمجية في هذا القسم والقسم التالي داخل حلقة الكشف أدناه؛ أما الشيفرة الكاملة الجاهزة للنسخ واللصق فتجدها في المثال الكامل.

Binary Mask Image
from pathlib import Path

import cv2
import numpy as np

for r in results:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem  # ⁨الاسم الأساسي للصورة المصدر⁩

    # ⁨التكرار على كل كائن مكتشف في الصورة⁩
    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]  # ⁨اسم الفئة⁩

        # ⁨إنشاء قناع ثنائي ورسم محيط الكائن عليه⁩
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
ما وظيفة `c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)`؟
  • يعيد c.masks.xy[0] محيط القناع على هيئة إحداثيات نقاط (x, y) للكائن في نتيجة الكشف المنفردة هذه.
  • يحوّل .astype(np.int32) النقاط من float32، إذ لا يقبل drawContours() في OpenCV تلك النقاط.
  • يعيد .reshape(-1, 1, 2) تشكيل النقاط وفق تخطيط [N, 1, 2] الذي يتوقعه drawContours()، حيث يشير N إلى عدد نقاط المحيط.

يؤدي تمرير [contour] مع الفهرس -1 إلى رسم جميع نقاط المحيط المحدد، بينما يملأ cv2.FILLED كل بكسل محاط باللون الأبيض.

عزل الكائن#

بعد تجهيز القناع الثنائي، ادمجه مع الصورة الأصلية. ثمة طريقتان شائعتان، بحسب الخلفية التي تريدها:

اختيار نمط العزل

حوّل القناع إلى ثلاثة قنوات واحتفظ بالبكسلات المتداخلة مع الكائن فقط. ستصبح كل المنطقة الواقعة خارج المحيط سوداء:

# ⁨عزل الكائن بخلفية سوداء⁩
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Example Full size Isolated Object Image Black Background
كائن بالحجم الكامل على خلفية سوداء
القص وفق مربع الإحاطة

للاحتفاظ بمنطقة الكائن وحدها بدلًا من الصورة كاملة الحجم، قصّ الصورة وفق مربع الإحاطة للكشف:

# ⁨إحداثيات مربع الإحاطة⁩
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# ⁨قص الصورة المعزولة لتقتصر على منطقة الكائن⁩
iso_crop = isolated[y1:y2, x1:x2]
Example Crop Isolated Object Image Black Background
كائن مقصوص إلى المربع المحيط به
هل تحتاج إلى القصاصة بخلفيتها الأصلية؟

هذه الوظيفة مدمجة. مرّر save_crop=True إلى predict()، وسيحفظ Ultralytics قصاصات مربعات الإحاطة تلقائيًا دون الحاجة إلى أقنعة.

حفظ النتيجة (اختياري)#

يمكنك اختيار ما تفعله بكل كائن معزول. ومن الخطوات التالية الشائعة حفظه على القرص لاستخدامه لاحقًا:

# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

هنا، يمثّل img_name الاسم الأساسي للصورة المصدر، ويمثّل label اسم الفئة، ويمثّل ci فهرس الكشف؛ وبذلك تحصل المثيلات المتعددة من الفئة نفسها على أسماء ملفات فريدة. استبدل isolated بـ iso_crop إذا طبّقت القص الاختياري أعلاه.

المثال الكامل#

يجمع البرنامج النصي أدناه جميع الخطوات في كتلة واحدة قابلة للتشغيل. ويستخدم خلفية سوداء افتراضيًا؛ بدّل السطر المحدد وحده إلى np.dstack([img, b_mask]) للحصول على PNG بخلفية شفافة بدلًا من ذلك:

from pathlib import Path

import cv2
import numpy as np

from ultralytics import YOLO

model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/image.jpg")

for r in results:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem

    for ci, c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]

        # Build a binary mask from the object contour
        b_mask = np.zeros(img.shape[:2], np.uint8)
        contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
        cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)

        # Isolate the object (black background)
        mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
        isolated = cv2.bitwise_and(mask3ch, img)  # transparent PNG: isolated = np.dstack([img, b_mask])

        # Save or add your custom post-processing here
        cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)

        # Optional: crop to the bounding box before saving
        # x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
        # cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated[y1:y2, x1:x2])

للاستخدام المتكرر، ضع محتوى الحلقة داخل دالة لتتمكن من استدعائها على صور عديدة.

الخلاصة#

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

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

  • حمّل نموذجًا للتقسيم، وشغّل الاستدلال، وأنشئ قناعًا ثنائيًا من محيط كل كشف، ثم ادمجه مع الصورة الأصلية:

    import cv2
    import numpy as np
    
    from ultralytics import YOLO
    
    model = YOLO("yolo26n-seg.pt")
    results = model.predict(source="path/to/your/image.jpg")
    
    img = np.copy(results[0].orig_img)
    b_mask = np.zeros(img.shape[:2], np.uint8)
    contour = results[0].masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
    cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
    
    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)

    راجع المثال الكامل للاطلاع على حلقة المعالجة الكاملة لكل كشف.

  • هناك نمطان أساسيان. للحصول على خلفية سوداء، حوّل القناع إلى ثلاثة قنوات واستخدم cv2.bitwise_and(). وللحصول على خلفية شفافة (عند الحفظ بصيغة PNG)، أضف القناع بوصفه قناة ألفا رابعة باستخدام np.dstack([img, b_mask]). ويُشرح كلا النمطين في عزل الكائن.

  • اقرأ إحداثيات مربع الإحاطة من الكشف، ثم قص الصورة المعزولة:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    iso_crop = isolated[y1:y2, x1:x2]

    تعرّف على المزيد حول نتائج مربعات الإحاطة في وثائق وضع التنبؤ.

  • يوفر Ultralytics YOLO تجزئةً سريعةً وفوريةً للكائنات مع إنشاء أقنعة ومربعات إحاطة دقيقة، بالإضافة إلى واجهة Python API بسيطة تحوّل نتائج الاستدلال إلى كائنات معزولة باستخدام بضعة أسطر من شيفرة OpenCV.

  • نعم. استخدم الوسيط save_crop في predict() لحفظ قصاصات مربعات الإحاطة مع خلفيتها الأصلية:

    results = model.predict(source="path/to/your/image.jpg", save_crop=True)

    اقرأ المزيد في قسم وسيطات الاستدلال في وضع التنبؤ.

التعليقات