انتقل إلى المحتوى الرئيسي

الوحدة 1 — العائلات الثلاث لمهامّ الصور

قبل أيّ سطر من الكود، ينبغي حسم سؤال واحد: ما المهمّة التي نحلّها فعلًا؟ فالخطأ الأشيع في مشاريع الرؤية الحاسوبية ليس اختيار المعمارية الخاطئة، بل حلّ مشكلة غير المشكلة الحقيقية. لهذا نبدأ الخيط الأحمر لهذه الدورة — نظام عدّ السيّارات والمُشاة على تقاطع طرق — بترسيم دقيق للمهامّ.

التصنيف: ما الذي في الصورة؟

يُعطي التصنيف الصورةَ صنفًا واحدًا، أو توزيعًا احتماليًا على مجموعة أصناف. لا يعرف الموضع، ولا يعدّ الأجسام، ولا يفصل الملتصقات. صورة كاميرا التقاطع كلّها تصير مثلًا «تقاطع مزدحم» بدلًا من ثلاث سيّارات ومُشاة وحافلة.

ينفع التصنيف حين تستوي الصورة كلّها بجواب واحد: هل هذا سرطان جلد؟ هل هذه لوحة سيّارة عربية؟ لكنّه لا يكفي لعدّ الوحدات ولا لتحديد موضعها. ومحاولة إسقاط التصنيف على مشكلة كشف — بتقطيع الصورة إلى نوافذ منزلقة وتصنيف كلّ نافذة — هي بالضبط ما بدأت به عائلة R-CNN قبل أن تتخلّى عنه لأسباب سنراها في الوحدة 2.

الكشف: ماذا وأين؟

يُنتج الكشف قائمة من الأجسام، لكلّ منها صندوق محيط (bounding box) وصنف ودرجة ثقة. صندوق سيّارة، صندوق مُشاة، صندوق حافلة. هذا بالضبط ما يتطلّبه مشروعنا: لا يكفي أن نعرف أنّ في الصورة سيّارات؛ نحتاج إلى تعدادها وتتبّع كلّ واحدة على حدة.

الصندوق مستطيل موازٍ للمحاور، يُمثَّل عادةً بأربعة أعداد: (x,y,w,h)(x, y, w, h) للركن الأعلى الأيسر والعرض والارتفاع، أو (x1,y1,x2,y2)(x_1, y_1, x_2, y_2) للركنين. وهذا التمثيل المستطيلي هو نقطة قوّة وضعف في آن: قوّة لأنّه بسيط وسريع، وضعف لأنّه يحتوي على بكسلات خلفية كثيرة حول جسم غير مستطيل — تخيّل صندوقًا حول عمود إشارة مائل.

التقطيع: أيّ بكسل ينتمي إلى ماذا؟

حين لا تكفي الصناديق، ننتقل إلى التقطيع، الذي يُصنّف كلّ بكسل على حدة. ثلاثة أنواع متمايزة، ولا يجب الخلط بينها.

التقطيع الدلالي يُعطي كلّ بكسل صنفًا. في مشروعنا: بكسلات ممرّ السيّارة، بكسلات الرصيف، بكسلات السماء. لكنّه لا يفرّق بين سيّارتين ملتصقتين: بكسلات السيّارتين تحصلان على الصنف نفسه «سيّارة»، دون هويّة منفصلة.

تقطيع النُسَخ يذهب أبعد. لا يقول «سيّارة» فحسب، بل سيّارة رقم 1 وسيّارة رقم 2، بأقنعة منفصلة لكلّ واحدة. هذا ما نحتاجه لعدّ السيّارات بدقّة، وسيقوم به Mask R-CNN في الوحدة 7. لكن ينبغي الانتباه: تقطيع النُسَخ لا يُسمّي الخلفية، فبكسل السماء يبقى بلا صنف.

التقطيع الشامل (panoptique) يوحّد الاثنين: كلّ بكسل يحصل على صنف، والأجسام العدّية تحصل على معرّف نُسخة إضافةً إلى الصنف. فبكسلات «طريق» تشترك في صنف واحد بلا نُسخ (فالطريق ليس عدّيًا)، أمّا بكسلات «سيّارة» فتحصل على صنف ونُسخة. هذا التصنيف يُقارب أخيرًا ما يفعله الإنسان حين ينظر إلى مشهد.

المهمّةمُخرَج لكلّ جسم عدّيصنف الخلفيةتعقيد الحساب
تصنيفصنف واحد للصورةلامنخفض
كشفصندوق + صنف + ثقةلامتوسّط
تقطيع دلاليقناع مشترك بالصنفنعممرتفع
تقطيع نُسَخقناع لكلّ نُسخةلامرتفع
تقطيع شاملقناع صنف + قناع نُسخةنعممرتفع جدًّا

صيغ التوسيم: COCO وPascal VOC وYOLO

المعمارية تقبل بيانات بصيغة محدّدة، ومعرفة الصيغ الثلاث السائدة يُوفّر ساعات من إعادة الكتابة.

صيغة COCO ملفّ JSON واحد يجمع الصور والأصناف والتوسيمات، بصناديق (x,y,w,h)(x, y, w, h) بالبكسلات المطلقة، وأقنعة تُخزَّن إمّا كقوائم مضلّعات وإمّا بضغط RLE. وهي معيار البحث، وكلّ التقارير التقييمية تُقاس عليها.

صيغة Pascal VOC ملفّ XML لكلّ صورة، بصناديق (xmin,ymin,xmax,ymax)(x_{\min}, y_{\min}, x_{\max}, y_{\max}) بالبكسلات. وهي أقدم، لكنّها لا تزال تُقابَل كثيرًا في التطبيقات الطبّية.

صيغة YOLO ملفّ نصّي لكلّ صورة، بسطر لكلّ جسم: class_id x_center y_center width height، حيث الإحداثيات مُسوّاة بين 0 و1 نسبةً إلى أبعاد الصورة. هذا يجعلها مستقلّة عن الحجم ومناسبة لتغيير المقاس أثناء التدريب.

import json

# قراءة توسيمات COCO لصورة واحدة
with open("annotations/instances_train.json", "r", encoding="utf-8") as f:
coco = json.load(f)

images = {img["id"]: img for img in coco["images"]}
categories = {cat["id"]: cat["name"] for cat in coco["categories"]}

# جميع الصناديق للصورة رقم 42
image_id = 42
boxes = [
{
"class": categories[ann["category_id"]],
"bbox": ann["bbox"], # [x, y, w, h] بكسلات مطلقة
"area": ann["area"],
}
for ann in coco["annotations"] if ann["image_id"] == image_id
]
print(f"عدد الأجسام في الصورة {image_id}: {len(boxes)}")

كلفة التوسيم: القرار الاقتصادي الأهمّ

تختلف كلفة التوسيم اختلافًا حادًّا بين المهامّ، وهذه غالبًا العقبة الأولى أمام أيّ مشروع.

  • صندوق يستغرق قرابة 7 ثوانٍ لكلّ جسم بواسطة موسّم مدرَّب
  • قناع دلالي يحتاج قرابة 60 إلى 90 ثانية لكلّ جسم
  • قناع نُسخة أعلى من ذلك، خصوصًا للأجسام ذات الحدود الدقيقة

المعنى العملي: مجموعة من 10 آلاف صورة بمعدّل خمسة أجسام لكلّ صورة تتطلّب قرابة 100 ساعة توسيم بالصناديق، وقد تتجاوز 1000 ساعة بالأقنعة. هذا ما يجعل الأدوات نصف الآلية — كـSegment Anything التي سنراها في الوحدة 7 — عاملًا حاسمًا في اقتصاديات المشروع.

اختر المهمّة الدنيا الكافية

يُغرى المهندس المبتدئ باختيار المهمّة «الأغنى»: إذا أمكن التقطيع فلمَ نكتفي بالكشف؟ الجواب هو الكلفة. لعدّ السيّارات على تقاطع طرق، الصناديق تكفي تمامًا وتُوفّر عشرات الآلاف من الساعات مقارنةً بالأقنعة. لا تختر التقطيع إلّا حين تفرضه المشكلة صراحةً: قياس المساحة الحقيقية للجسم، أو التمييز بين ملتصقين، أو حساب شكل غير مستطيل.

في الخلاصة

  • التصنيف يُعطي صنفًا للصورة، والكشف يُنتج صناديق مع أصناف وثقة، والتقطيع يُصنّف كلّ بكسل.
  • التقطيع ثلاثة أنواع: دلالي بلا نُسخ، نُسَخ بأقنعة منفصلة، وشامل يجمعهما ويسمّي الخلفية.
  • الصيغ الثلاث السائدة COCO بJSON، وPascal VOC بXML، وYOLO بنصّ مُسوّى؛ ومعرفتها تختصر ساعات إعادة الكتابة.
  • كلفة التوسيم تختلف بأمر مقدار بين الصندوق (7 ثوانٍ) والقناع (90 ثانية)؛ فاختر المهمّة الدنيا التي تكفي مشكلتك الفعلية.

الوحدة التالية: أوّل عائلة من الكواشف، R-CNN وأخواتها، حيث نفهم لماذا لا يكفي تصنيف نوافذ منزلقة.