5.5. المناطق والأقنعة

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

5.5.1. مناطق الاهتمام

منطقة الاهتمام هي مستطيل من البكسلات يُسمى بالرباعية (x, y, w, h) التي عُرّفت في صفحة الإحداثيات. وتقبل نحو ثلاثين طريقة على السطح وسيطة الكلمة المفتاحية roi؛ وعند وجودها، تعمل العملية فقط على البكسلات داخل ذلك المستطيل وتترك بقية الصورة دون مساس. وعندما تكون roi مساوية لـ None أو محذوفة، تعمل العملية فوق الصورة بأكملها -- تمامًا كما لو أنه قد تم تمرير roi=(0, 0, width, height).

في الشيفرة، تقع الكلمة المفتاحية إلى جانب أي وسائط أخرى تأخذها العملية:

# Compute a histogram over a centred crop of the image.
h = img.get_histogram(roi=(64, 64, 128, 128))

أول ما تحققه مناطق الاهتمام هو التحكم في الإيجابيات الكاذبة. فمتتبع الألوان الذي ينظر فقط إلى الطاولة لن يُطلَق أبدًا بسبب القميص المار بجانبها؛ وكاشف الحواف الذي يعمل فقط داخل منطقة العمل المحددة لن يبلّغ أبدًا عن حواف حامل الكاميرا نفسه. إن تقليص منطقة البحث إلى الجزء من المشهد الذي تهتم به الخوارزمية فعلًا هو أرخص تحسين يمكن لخط المعالجة أن يُدخله على موثوقيته الخاصة.

والشيء الثاني الذي تحققه هو خط المعالجة من الخشن إلى الدقيق. فكائنات نتائج الكشف -- blob و rect و apriltag وما إلى ذلك -- تكشف مربعات إحاطتها بوصفها نفس الرباعية (x, y, w, h) التي تقبلها roi. وهكذا يمكن لمرحلة أولى خشنة أن تعيد مربع إحاطة، فيسقط المربع مباشرة في roi الخاصة بالمرحلة التالية، فتعمل المرحلة الثانية فوق المنطقة الأضيق. وكل تضييق تدريجي يسرّع المرحلة التالية ويجعل نتائجها أكثر موثوقية في آن واحد، لأن فضاء البحث قد رُشّح بالفعل.

5.5.2. الأقنعة الثنائية

المستطيل هو الشكل الصحيح عندما تكون منطقة الاهتمام محاذية للمحاور. وعندما لا تكون كذلك -- منطقة منحنية، أو غير محدبة، أو البكسلات التي صنّفتها مرحلة سابقة على أنها "تطابقات" -- يجب أن تُخبَر العملية بأن تحصر نفسها في نمط اعتباطي من البكسلات بدلًا من ذلك. والآلية لذلك هي القناع الثنائي: كائن Image منفصل، بنفس أبعاد المصدر، يُستخدم كمفتاح تشغيل/إيقاف لكل بكسل. فالبكسل غير الصفري في القناع يقول "ضمّن البكسل المصدري المطابق"؛ والبكسل الصفري يقول "اترك البكسل المصدري وشأنه".

يكون القناع عادةً صورة BINARY -- التنسيق ذو البت الواحد لكل بكسل الذي وُجد لهذا الغرض بالضبط -- لكن أي صورة أحادية القناة ستعمل، لأن المستهلك يعامل أي قيمة غير صفرية على أنها تشغيل.

تقبل طرق الترشيح والعتبة والحساب وسيطة الكلمة المفتاحية mask. والشكل واحد في كلٍّ منها: صورة ثنائية مخصصة على حدة، بنفس أبعاد المصدر، تُمرَّر إليها.

مناطق الاهتمام والأقنعة تتركّب. مرّر كليهما، فتعمل العملية فقط على البكسلات التي تكون داخل منطقة الاهتمام و قيد التشغيل في القناع. تمنح الآليتان شيفرة التطبيق روافع مستقلة -- واحدة للمنطقة المستطيلة محل الاهتمام، وأخرى للنمط الاعتباطي داخلها -- دون أن يجعل أيٌّ من الشكلين يرث قيودًا من الآخر.

A small grid representing an image. A dashed rectangle drawn across the upper-middle portion of the grid labels the ROI: only pixels inside this rectangle are considered. Inside the ROI, a roughly circular set of filled cells labels the mask: only those filled cells are actually modified. The remaining cells are shaded lightly to indicate they are untouched.

تحصر منطقة الاهتمام العملية في مستطيل محاذٍ للمحاور. ويضيّقها القناع أكثر إلى نمط اعتباطي من البكسلات. وهما تتركّبان: فقط البكسلات داخل منطقة الاهتمام و قيد التشغيل في القناع تُعدَّل.

5.5.3. بناء الأقنعة

تبني ثلاث طرق من Image هندسات أقنعة شائعة في مكانها عبر تصفير البكسلات خارج المنطقة المختارة:

تأخذ كل واحدة منها (x, y, w, h) (للمستطيل والقطع الناقص) أو (x, y, radius) (للدائرة). واستدعاء أيٍّ منها دون وسائط يجعل الشكل الهندسي في المركز ويحجّمه ليملأ الصورة، وهو الشكل الذي يلجأ إليه التطبيق عندما يكون الهدف بيضاوية أو دائرة بسيطة تملأ الصورة بأكملها ولا تخفي شيئًا سوى الزوايا.

mask = image.Image(img.width(), img.height(), image.BINARY)
mask.clear()              # start from all zeros
mask.mask_ellipse()       # centred, full-size oval

نادرًا ما تأتي الأقنعة المثيرة للاهتمام من طرق mask_* وحدها. بل تأتي من مراحل سابقة في خط المعالجة: فمرور العتبة يُنتج صورة ثنائية تشير بكسلاتها غير الصفرية إلى التطابقات، وهو الشكل الصحيح تمامًا لتغذيته إلى وسيطة mask= الخاصة بالمرحلة التالية. ومرور التنظيف المورفولوجي يصقل ذلك القناع دون تغيير شكله. وأي شيء ينتهي به الأمر صورةً أحادية القناة هو في حد ذاته قناع صالح.

5.5.4. كيف تعدّل العمليات الصورة

ثمة نمط ظاهر في كل مقتطف شيفرة في الصفحات القليلة الأخيرة -- العملية تعيد نفس img للتسلسل -- يستحق أن يُستخرج صراحةً حتى لا يلزم إعادة ذكره في كل مرة تُقدَّم فيها طريقة جديدة. تظهر ثلاث عائلات من الطرق على سطح Image، تعامل كلٌّ منها الصورة المصدرية بشكل مختلف:

  • الطرق العاملة تعدّل بكسلات المصدر في مكانها وتعيد نفس الصورة للتسلسل. وتتصرف عائلات الرسم والحساب والعتبة والترشيح جميعها بهذه الطريقة. فـ img.gaussian(1) تُموّه img وتعيد نفس img؛ وإعادة الإسناد -- img = img.gaussian(1) -- غير ضارة لكنها غير ضرورية.

  • طرق التحويل تعمل في مكانها افتراضيًا بنفس طريقة الطرق العاملة، لكنها تقبل copy=True و copy_to_fb=True لتخصيص صورة نتيجة منفصلة عندما يحتاج المصدر إلى الحفاظ عليه. وتحويلات التنسيق والنسخ الهندسية هي الأعضاء الرئيسية في هذه العائلة.

  • طرق الفحص تقرأ البكسلات وتعيد كائن نتيجة -- قائمة بالميزات المكتشفة، أو مدرجًا تكراريًا، أو مجموعة من الإحصائيات -- دون تعديل الصورة المصدرية على الإطلاق.

هذا التقسيم الثلاثي متسق عبر السطح بأكمله. ومعرفة العائلة التي تنتمي إليها طريقة ما تُخبر التطبيق بما يتوقعه من الاستدعاء: هل ستبقى بكسلات المصدر سليمة، وهل ستُخصَّص صورة نتيجة منفصلة، وهل قيمة الإرجاع هي المصدر نفسه أم شيء آخر.