انتقل إلى المحتوى

عزل كائنات التجزئة

بعد تنفيذ مهمة المقطع ، من المستحسن أحيانا استخراج الكائنات المعزولة من نتائج الاستدلال. يقدم هذا الدليل وصفة عامة حول كيفية تحقيق ذلك باستخدام Ultralytics وضع التنبؤ.

مثال على تجزئة الكائن المعزول

وصفة المشي من خلال

  1. ابدأ بالواردات الضرورية

    from pathlib import Path
    
    import cv2
    import numpy as np
    from ultralytics import YOLO
    
    Ultralytics أقام

    انظر Ultralytics التشغيل السريع قسم التثبيت للحصول على إرشادات سريعة حول تثبيت المكتبات المطلوبة.


  2. تحميل نموذج وتشغيله predict() طريقة على مصدر.

    from ultralytics import YOLO
    
    # Load a model
    model = YOLO('yolov8n-seg.pt')
    
    # Run inference
    results = model.predict()
    

    لا توجد حجج تنبؤ؟

    بدون تحديد مصدر ، سيتم استخدام الصور النموذجية من المكتبة:

    'ultralytics/assets/bus.jpg'
    'ultralytics/assets/zidane.jpg'
    

    هذا مفيد للاختبار السريع باستخدام predict() أسلوب.

    للحصول على معلومات إضافية حول نماذج التجزئة، تفضل بزيارة مهمة الشريحة صفحة. لمعرفة المزيد عن predict() الطريقة، انظر وضع التنبؤ من الوثائق.


  3. الآن كرر على النتائج والخطوط. بالنسبة لمهام سير العمل التي تريد حفظ صورة في ملف، فإن الصورة المصدر base-name والكشف class-label يتم استردادها لاستخدامها لاحقا (اختياري).

    # (2) Iterate detection results (helpful for multiple images)
    for r in res:
        img = np.copy(r.orig_img)
        img_name = Path(r.path).stem # source image base-name
    
        # Iterate each object contour (multiple detections)
        for ci,c in enumerate(r):
            # (1) Get detection class name
            label = c.names[c.boxes.cls.tolist().pop()]
    
    1. لمعرفة المزيد حول العمل مع نتائج الكشف، راجع قسم المربعات لوضع التنبؤ.
    2. لمعرفة المزيد عن predict() النتائج انظر العمل مع النتائج لوضع التنبؤ
    لحلقة

    ستكرر صورة واحدة الحلقة الأولى مرة واحدة فقط. صورة واحدة مع اكتشاف واحد فقط ستكرر كل حلقة مرة واحدة فقط .


  4. ابدأ بتوليد قناع ثنائي من الصورة المصدر ثم ارسم محيطا معبأ على القناع. سيسمح ذلك بعزل الكائن عن الأجزاء الأخرى من الصورة. مثال من bus.jpg لأحد المكتشفة person يتم عرض كائنات الفئة على اليمين.

    صورة القناع الثنائي

    # Create binary mask
    b_mask = np.zeros(img.shape[:2], np.uint8)
    
    # (1) Extract contour result
    contour = c.masks.xy.pop()
    # (2) Changing the type
    contour = contour.astype(np.int32)
    # (3) Reshaping
    contour = contour.reshape(-1, 1, 2)
    
    
    # Draw contour onto mask
    _ = cv2.drawContours(b_mask,
                        [contour],
                        -1,
                        (255, 255, 255),
                        cv2.FILLED)
    
    1. لمزيد من المعلومات حول c.masks.xy رأى قسم الأقنعة من وضع التنبؤ.

    2. هنا يتم صب القيم هنا في np.int32 للتوافق مع drawContours() وظيفة من OpenCV.

    3. السيرة الذاتية المفتوحة drawContours() تتوقع الدالة أن يكون للخطوط شكل [N, 1, 2] قم بتوسيع القسم أدناه لمزيد من التفاصيل.

    قم بالتوسع لفهم ما يحدث عند تعريف contour متغير.

    • c.masks.xy :: يوفر إحداثيات نقاط كفاف القناع بالتنسيق (x, y). لمزيد من التفاصيل، يرجى الرجوع إلى قسم الأقنعة من وضع التنبؤ.

    • .pop() ::مثل masks.xy هي قائمة تحتوي على عنصر واحد ، يتم استخراج هذا العنصر باستخدام pop() أسلوب.

    • .astype(np.int32) ::استخدام masks.xy سيعود مع نوع بيانات float32، ولكن هذا لن يكون متوافقا مع OpenCV drawContours() ، لذلك سيؤدي ذلك إلى تغيير نوع البيانات إلى int32 للتوافق.

    • .reshape(-1, 1, 2) :: إعادة تنسيق البيانات إلى الشكل المطلوب ل [N, 1, 2] أين N هو عدد النقاط الكنتورية، مع تمثيل كل نقطة بإدخال واحد 1، ويتكون الإدخال من 2 القيم. ال -1 يشير إلى أن عدد القيم على طول هذا البعد مرن.

    قم بالتوسيع للحصول على شرح ل drawContours() تكوين.

    • تغليف contour متغير بين قوسين معقوفين ، [contour]، لتوليد قناع الكنتور المطلوب بشكل فعال أثناء الاختبار.

    • القيمة -1 المحدد ل drawContours() ترشد المعلمة الدالة لرسم جميع الخطوط الموجودة في الصورة.

    • ال tuple (255, 255, 255) يمثل اللون الأبيض ، وهو اللون المطلوب لرسم الكفاف في هذا القناع الثنائي.

    • إضافة cv2.FILLED سوف يلون جميع وحدات البكسل المحاطة بحدود الكنتور بنفس الطريقة ، وفي هذه الحالة ، ستكون جميع وحدات البكسل المغلقة بيضاء.

    • رأى وثائق OpenCV على drawContours() لمزيد من المعلومات.


  5. بعد ذلك هناك خياران لكيفية المضي قدمًا بالصورة من هذه النقطة وخيار لاحق لكل منهما.

    خيارات عزل الكائن

    # Create 3-channel mask
    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    
    # Isolate object with binary mask
    isolated = cv2.bitwise_and(mask3ch, img)
    
    كيف يعمل هذا؟
    • أولا ، يتم تحويل القناع الثنائي أولا من صورة أحادية القناة إلى صورة ثلاثية القنوات. هذا التحويل ضروري للخطوة التالية حيث يتم الجمع بين القناع والصورة الأصلية. يجب أن تحتوي كلتا الصورتين على نفس عدد القنوات لتكون متوافقة مع عملية المزج.

    • يتم دمج الصورة الأصلية والقناع الثنائي ثلاثي القنوات باستخدام وظيفة OpenCV bitwise_and(). تحتفظ هذه العملية فقط قيم البكسل الأكبر من الصفر (> 0) من كلتا الصورتين. نظرا لأن وحدات بكسل القناع أكبر من الصفر (> 0) فقط ضمن منطقة المحيط، البيكسلات المتبقية من الصورة الأصلية هي تلك التي تتداخل مع المحيط.

    عزل باستخدام وحدات البكسل السوداء: خيارات فرعية

    صورة بالحجم الكامل

    لا توجد خطوات إضافية مطلوبة في حالة الاحتفاظ بالصورة بالحجم الكامل.

    مثال على صورة كائن معزول بالحجم الكامل خلفية سوداء
    مثال على الإخراج بالحجم الكامل

    صورة كائن تم اقتصاصه

    الخطوات الإضافية المطلوبة لاقتصاص الصورة لتضمين منطقة الكائن فقط.

    مثال على اقتصاص صورة كائن معزول خلفية سوداء

    # (1) Bounding box coordinates
    x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
    # Crop image to object region
    iso_crop = isolated[y1:y2, x1:x2]
    

    1. لمزيد من المعلومات حول نتائج المربع المحيط، راجع قسم المربعات من وضع التنبؤ
    ماذا يفعل هذا الرمز؟
    • ال c.boxes.xyxy.cpu().numpy() يسترد call المربعات المحيطة كصفيف NumPy في xyxy التنسيق ، حيث xmin, ymin, xmaxو ymax تمثيل إحداثيات مستطيل المربع المحيط. رأى قسم المربعات من وضع التنبؤ لمزيد من التفاصيل.

    • ال squeeze() تزيل العملية أي أبعاد غير ضرورية من صفيف NumPy ، مما يضمن أن لها الشكل المتوقع.

    • تحويل قيم الإحداثيات باستخدام .astype(np.int32) تغيير المربع إحداثيات نوع البيانات من float32 ل int32، مما يجعلها متوافقة مع اقتصاص الصور باستخدام شرائح الفهرس.

    • أخيرا، يتم اقتصاص منطقة المربع المحيط من الصورة باستخدام تقطيع الفهرس. يتم تحديد الحدود بواسطة [ymin:ymax, xmin:xmax] إحداثيات المربع المحيط بالكشف.

    # Isolate object with transparent background (when saved as PNG)
    isolated = np.dstack([img, b_mask])
    
    كيف يعمل هذا؟
    • باستخدام NumPy dstack() وظيفة (تكديس الصفيف على طول محور العمق) بالتزامن مع القناع الثنائي الذي تم إنشاؤه ، ستنشئ صورة بأربع قنوات. يسمح ذلك لجميع وحدات البكسل خارج محيط الكائن أن تكون شفافة عند الحفظ على هيئة PNG ملف.

    عزل باستخدام وحدات بكسل شفافة: خيارات فرعية

    صورة بالحجم الكامل

    لا توجد خطوات إضافية مطلوبة في حالة الاحتفاظ بالصورة بالحجم الكامل.

    مثال على صورة كائن معزول بالحجم الكامل بدون خلفية
    مثال على إخراج بالحجم الكامل + خلفية شفافة

    صورة كائن تم اقتصاصه

    الخطوات الإضافية المطلوبة لاقتصاص الصورة لتضمين منطقة الكائن فقط.

    مثال على اقتصاص صورة كائن معزول بدون خلفية

    # (1) Bounding box coordinates
    x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
    # Crop image to object region
    iso_crop = isolated[y1:y2, x1:x2]
    

    1. لمزيد من المعلومات حول نتائج المربع المحيط، راجع قسم المربعات من وضع التنبؤ
    ماذا يفعل هذا الرمز؟
    • عند استخدام c.boxes.xyxy.cpu().numpy()، يتم إرجاع المربعات المحيطة كصفيف NumPy ، باستخدام xyxy تنسيق إحداثيات المربع ، والذي يتوافق مع النقاط xmin, ymin, xmax, ymax للمربع المحيط (المستطيل)، راجع قسم المربعات من وضع التنبؤ لمزيد من المعلومات.

    • اضافه squeeze() يضمن إزالة أي أبعاد غريبة من صفيف NumPy.

    • تحويل قيم الإحداثيات باستخدام .astype(np.int32) تغيير المربع إحداثيات نوع البيانات من float32 ل int32 والتي ستكون متوافقة عند اقتصاص الصورة باستخدام شرائح الفهرس.

    • أخيرا ، يتم اقتصاص منطقة الصورة للمربع المحيط باستخدام تقطيع الفهرس ، حيث يتم تعيين الحدود باستخدام [ymin:ymax, xmin:xmax] إحداثيات المربع المحيط بالكشف.

    ماذا لو أردت الكائن الذي تم اقتصاصه بما في ذلك الخلفية؟

    هذه ميزة مضمنة ل Ultralytics مكتبة. انظر save_crop حجة ل وسيطات الاستدلال في وضع التنبؤ للتفاصيل.


  6. ما يجب القيام به بعد ذلك متروك لك تماما كمطور. يتم عرض مثال أساسي لخطوة تالية محتملة (حفظ الصورة في ملف للاستخدام في المستقبل).

    • ملاحظة: هذه الخطوة اختيارية ويمكن تخطيها إذا لم تكن مطلوبة لحالة الاستخدام الخاصة بك.
    مثال على الخطوة النهائية
    # Save isolated object to file
    _ = cv2.imwrite(f'{img_name}_{label}-{ci}.png', iso_crop)
    
    • في هذا المثال، img_name هو الاسم الأساسي لملف الصورة المصدر ، label هو اسم الفئة المكتشفة، و ci هو فهرس اكتشاف الكائن (في حالة وجود مثيلات متعددة بنفس اسم الفئة).

رمز المثال الكامل

هنا ، يتم دمج جميع الخطوات من القسم السابق في كتلة واحدة من التعليمات البرمجية. للاستخدام المتكرر ، سيكون من الأفضل تحديد وظيفة للقيام ببعض أو كل الأوامر الواردة في for-الحلقات ، لكن هذا تمرين متروك للقارئ.

from pathlib import Path

import cv2
import numpy as np
from ultralytics import YOLO

m = YOLO('yolov8n-seg.pt')#(4)!
res = m.predict()#(3)!

# iterate detection results (5)
for r in res:
    img = np.copy(r.orig_img)
    img_name = Path(r.path).stem

    # iterate each object contour (6)
    for ci,c in enumerate(r):
        label = c.names[c.boxes.cls.tolist().pop()]

        b_mask = np.zeros(img.shape[:2], np.uint8)

        # Create contour mask (1)
        contour = c.masks.xy.pop().astype(np.int32).reshape(-1, 1, 2)
        _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)

        # Choose one:

        # OPTION-1: Isolate object with black background
        mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
        isolated = cv2.bitwise_and(mask3ch, img)

        # OPTION-2: Isolate object with transparent background (when saved as PNG)
        isolated = np.dstack([img, b_mask])

        # OPTIONAL: detection crop (from either OPT1 or OPT2)
        x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
        iso_crop = isolated[y1:y2, x1:x2]

        # TODO your actions go here (2)
  1. الخط الذي يملأ contour في سطر واحد هنا ، حيث تم تقسيمه إلى عدة أعلاه.
  2. ما يذهب هنا متروك لك!
  3. راجع وضع التنبؤ للحصول على معلومات إضافية.
  4. راجع تقسيم المهمة لمزيد من المعلومات.
  5. تعرف على المزيد حول العمل مع النتائج
  6. تعرف على المزيد حول نتائج قناع التجزئة


تم الإنشاء 2023-11-27، تم التحديث 2024-04-27
المؤلفون: جلين-جوتشر (6)، رضوان منور (1)، برهان-ق (1)

التعليقات