5.31. مطابقة الإزاحة

تجيب مطابقة القالب عن أين تقع هذه الرقعة داخل الإطار؛ وتجيب درجة التشابه عن كم تتشابه هاتان الصورتان إجمالاً. وثمة سؤال مختلف يقع بينهما: يُظهر الإطاران المشهد نفسه، لكن الكاميرا (أو المشهد) تحركت بينهما -- بمقدار كم؟ تلك هي مشكلة الإزاحة، وتحلها وحدة image بدالة ارتباط طوري واحدة.

5.31.1. إزاحة الارتباط الطوري

تُقدِّر find_displacement() المحاذاة الصلبة بين صورتين بالحجم نفسه باستخدام الارتباط الطوري -- وهي طريقة في النطاق الترددي تُجري تحويل فورييه السريع (FFT) على كل صورة، وتُربِّط أطوارهما تبادلياً، وتحدد موقع الذروة في النتيجة. موضع الذروة هو الإزاحة التي تحاذي الصورتين:

d = img.find_displacement(template)

print("shift:", d.x_translation, d.y_translation,
      " response:", d.response)

يحمل كائن Displacement المُرجَع x_translation وy_translation -- الإزاحة بالبكسل في كل محور -- إضافة إلى response، وهي درجة ثقة من 0.0 إلى 1.0 حيث 1.0 ذروة مثالية. تصفية الكشوف الأدنى من response > 0.3 يتخلص من النتائج الزائفة التي لم يجد فيها الارتباط الطوري ذروة نظيفة قط.

كل من rotation وscale يساوي 0.0 و1.0 على التوالي في الوضع الافتراضي؛ ولا يأخذان قيماً حقيقية إلا عندما يكون logpolar=True (انظر أدناه).

تحمل الدالة قيدين عمليين. الأول هو أبعاد من قوى الاثنين: تحويل FFT في صميم الارتباط الطوري هو الأسرع -- وعلى الكاميرا، مدعوم بالكامل فقط -- عند أحجام مثل 32 في 32، و64 في 64، و128 في 128. الإعداد الأنظف هو الالتقاط بأحد تلك الأحجام مباشرة، بتمرير الدقة إلى framesize() كصف (tuple):

csi0.framesize((64, 64))

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

والثاني هو دخل بالحجم نفسه: يجب أن يختار roi وtemplate_roi عرضين وارتفاعين متطابقين، وإلا رفض المطابِق الاستدعاء. التقاطان من الكاميرا نفسها بالتهيئة نفسها يحققان هذا تلقائياً؛ أما إطار ملتقط مقارَن بمرجع محمَّل فيحتاج إلى اقتصاص كليهما إلى رقعتين متطابقتين من قوى الاثنين أولاً.

5.31.2. الدوران والقياس عبر اللوغاريتمي القطبي

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

d = img.find_displacement(template, logpolar=True)

print("rotation rad:", d.rotation,
      " scale:", d.scale,
      " response:", d.response)

مع logpolar=True، تُشغِّل الدالة خط أنابيب المطابقة نفسه على الصور المُسقَطة لوغاريتمياً قطبياً بدلاً من الأصلية. ويعود حقلا rotation وscale من النتيجة معبَّأين: rotation هي الزاوية بالراديان بين الإطارين، وscale هو معامل القياس بينهما. ويصبح x_translation وy_translation بلا معنى في هذا الوضع (الإزاحة على المحاور اللوغاريتمية القطبية لا تقابل إزاحة خطية في المصدر).

تغطي الكلمة المفتاحية fix_rotation_scale=True الحالة الوسطى: تختلف الصورتان في كلٍّ من الإزاحة والدوران/القياس، ويحتاج التطبيق إلى الإزاحة فقط بعد تصحيح الدوران والقياس. يُشغّل المطابِق التمريرة اللوغاريتمية القطبية أولاً لاسترجاع الدوران والقياس، ويطبق المعكوس على إحدى الصورتين، ثم يُشغّل تمريرة الإزاحة لاسترجاع الإزاحة المتبقية. وللعَلَم معنى فقط عندما يكون logpolar=False -- فهو يطلب من مطابِق وضع الإزاحة أن يجرِّد الدوران/القياس أولاً.

النمط من تحويلات Polar -- ديكارتي ← قطبي ← مطابقة -- هو ما تفعله find_displacement() مع logpolar=True في استدعاء واحد. يخزن التطبيق رقعة لوغاريتمية قطبية مرجعية عند بدء التشغيل، ويلتقط كل إطار حي ويحوّله لوغاريتمياً قطبياً، وتسترجع الدالة فرق الدوران والقياس بينهما. وبالنسبة للتطبيقات التي تحتاج متتبِّعاً ثابتاً تجاه الدوران والقياس -- روبوت إرساء تميل كاميرته وتُكبِّر وهو يقترب من هدف، أو منصة محورية مثبَّتة تحتاج إلى معرفة كيف تدور الصورة بالنسبة إلى مرجع -- فهذا هو البناء القياسي.

5.31.3. الاستخدام الكلاسيكي

أكثر استخدامات find_displacement() شيوعاً هو تقدير الحركة من إطار إلى إطار في خط أنابيب يعالج كاميرا متحركة. تلتقط الكاميرا رقعة صغيرة من قوى الاثنين عند الإطار N، وتلتقط الرقعة بالحجم نفسه عند الإطار N+1، وتُشغِّل find_displacement() على الاثنتين، وتقرأ الإزاحة بالبكسل بينهما. الإزاحة هي الحركة المقدَّرة للكاميرا (أو للمشهد، تبعاً لإطار من المرجعي الذي يهم) بين الالتقاطين، وهي مفيدة لـ:

  • الاستشعار بأسلوب التدفق البصري -- طائرة مسيّرة محلِّقة بكاميرا موجهة للأسفل تستخدم الإزاحة لكل إطار لتقدير حركتها الجانبية وإعادة تغذيتها إلى متحكم الطيران.

  • تثبيت الصورة -- تُطرح الإزاحة بين الإطارات المتتالية من الصورة الملتقطة قبل تسجيلها أو إرسالها، مما يُنتج دفق فيديو أكثر سلاسة.

  • محاذاة الفحص -- كاميرا ماسحة تتحرك على طول ناقل تستخدم الإزاحة لكل إطار لمطابقة كل إطار مع التالي وبناء عرض مُجمَّع للقطعة بأكملها.

يأخذ كل من تلك التطبيقات الشكل نفسه: التقاط، إزاحة، تراكم في تقدير جارٍ، ثم التقاط مرة أخرى.