عزل كائنات التجزئة
بعد تنفيذ مهمة المقطع ، من المستحسن أحيانا استخراج الكائنات المعزولة من نتائج الاستدلال. يقدم هذا الدليل وصفة عامة حول كيفية تحقيق ذلك باستخدام Ultralytics وضع التنبؤ.
وصفة المشي من خلال
-
ابدأ بالواردات الضرورية
Ultralytics أقام
انظر Ultralytics التشغيل السريع قسم التثبيت للحصول على إرشادات سريعة حول تثبيت المكتبات المطلوبة.
-
تحميل نموذج وتشغيله
predict()
طريقة على مصدر.from ultralytics import YOLO # Load a model model = YOLO('yolov8n-seg.pt') # Run inference results = model.predict()
لا توجد حجج تنبؤ؟
بدون تحديد مصدر ، سيتم استخدام الصور النموذجية من المكتبة:
هذا مفيد للاختبار السريع باستخدام
predict()
أسلوب.للحصول على معلومات إضافية حول نماذج التجزئة، تفضل بزيارة مهمة الشريحة صفحة. لمعرفة المزيد عن
predict()
الطريقة، انظر وضع التنبؤ من الوثائق.
-
الآن كرر على النتائج والخطوط. بالنسبة لمهام سير العمل التي تريد حفظ صورة في ملف، فإن الصورة المصدر
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()]
- لمعرفة المزيد حول العمل مع نتائج الكشف، راجع قسم المربعات لوضع التنبؤ.
- لمعرفة المزيد عن
predict()
النتائج انظر العمل مع النتائج لوضع التنبؤ
لحلقة
ستكرر صورة واحدة الحلقة الأولى مرة واحدة فقط. صورة واحدة مع اكتشاف واحد فقط ستكرر كل حلقة مرة واحدة فقط .
-
ابدأ بتوليد قناع ثنائي من الصورة المصدر ثم ارسم محيطا معبأ على القناع. سيسمح ذلك بعزل الكائن عن الأجزاء الأخرى من الصورة. مثال من
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)
-
لمزيد من المعلومات حول
c.masks.xy
رأى قسم الأقنعة من وضع التنبؤ. -
هنا يتم صب القيم هنا في
np.int32
للتوافق معdrawContours()
وظيفة من OpenCV. -
السيرة الذاتية المفتوحة
drawContours()
تتوقع الدالة أن يكون للخطوط شكل[N, 1, 2]
قم بتوسيع القسم أدناه لمزيد من التفاصيل.
قم بالتوسع لفهم ما يحدث عند تعريف
contour
متغير.-
c.masks.xy
:: يوفر إحداثيات نقاط كفاف القناع بالتنسيق(x, y)
. لمزيد من التفاصيل، يرجى الرجوع إلى قسم الأقنعة من وضع التنبؤ. -
.pop()
::مثلmasks.xy
هي قائمة تحتوي على عنصر واحد ، يتم استخراج هذا العنصر باستخدامpop()
أسلوب. -
.astype(np.int32)
::استخدامmasks.xy
سيعود مع نوع بياناتfloat32
، ولكن هذا لن يكون متوافقا مع OpenCVdrawContours()
، لذلك سيؤدي ذلك إلى تغيير نوع البيانات إلى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()
لمزيد من المعلومات.
-
-
بعد ذلك هناك خياران لكيفية المضي قدمًا بالصورة من هذه النقطة وخيار لاحق لكل منهما.
خيارات عزل الكائن
# 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]
- لمزيد من المعلومات حول نتائج المربع المحيط، راجع قسم المربعات من وضع التنبؤ
ماذا يفعل هذا الرمز؟
-
ال
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]
- لمزيد من المعلومات حول نتائج المربع المحيط، راجع قسم المربعات من وضع التنبؤ
ماذا يفعل هذا الرمز؟
-
عند استخدام
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
حجة ل وسيطات الاستدلال في وضع التنبؤ للتفاصيل.
-
-
ما يجب القيام به بعد ذلك متروك لك تماما كمطور. يتم عرض مثال أساسي لخطوة تالية محتملة (حفظ الصورة في ملف للاستخدام في المستقبل).
- ملاحظة: هذه الخطوة اختيارية ويمكن تخطيها إذا لم تكن مطلوبة لحالة الاستخدام الخاصة بك.
رمز المثال الكامل
هنا ، يتم دمج جميع الخطوات من القسم السابق في كتلة واحدة من التعليمات البرمجية. للاستخدام المتكرر ، سيكون من الأفضل تحديد وظيفة للقيام ببعض أو كل الأوامر الواردة في 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)
- الخط الذي يملأ
contour
في سطر واحد هنا ، حيث تم تقسيمه إلى عدة أعلاه. - ما يذهب هنا متروك لك!
- راجع وضع التنبؤ للحصول على معلومات إضافية.
- راجع تقسيم المهمة لمزيد من المعلومات.
- تعرف على المزيد حول العمل مع النتائج
- تعرف على المزيد حول نتائج قناع التجزئة