5.31. התאמת היסט

התאמת תבנית עונה על השאלה היכן הטלאי הזה נמצא בתוך הפריים; ניקוד דמיון עונה על כמה שתי התמונות האלה דומות בסך הכול. שאלה שונה יושבת ביניהן: שני הפריימים מציגים את אותה סצנה, אך המצלמה (או הסצנה) זזה ביניהם – בכמה? זוהי בעיית ה-היסט (displacement), ומודול image פותר אותה במתודת מתאם-פאזה (phase-correlation) יחידה.

5.31.1. היסט באמצעות מתאם פאזה

find_displacement() מעריך את היישור הקשיח בין שתי תמונות בעלות אותו גודל באמצעות מתאם פאזה (phase correlation) – שיטה בתחום התדר המריצה התמרת פורייה מהירה (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. סיבוב וקנה מידה באמצעות log-polar

מצב ברירת המחדל מוצא הזזה בלבד. כאשר שני הפריימים נבדלים גם ב-סיבוב סביב מרכז נבחר או ב-קנה מידה סביב אותו מרכז, הרצת מתאם הפאזה על ההיטל-מחדש ה-log-polar של כל תמונה הופכת את הפרמטרים האלה להזזה במערכת הצירים של log-polar – אותה אותו מתאם-פאזה יכול לשחזר:

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

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

עם logpolar=True, המתודה מריצה את אותו צינור התאמה מול התמונות המוטלות-log-polar במקום המקוריות. השדות rotation ו-scale של התוצאה חוזרים מלאים: rotation הוא הזווית ברדיאנים בין שני הפריימים, scale הוא גורם קנה המידה ביניהם. x_translation ו-y_translation הופכים חסרי משמעות במצב זה (ההזזה לאורך צירי log-polar אינה מתאימה להזזה לינארית במקור).

מילת המפתח fix_rotation_scale=True מכסה את המקרה הביניימי: שתי התמונות נבדלות גם בהזזה וגם בסיבוב/קנה מידה, והיישום זקוק ל-הזזה בלבד לאחר תיקון הסיבוב וקנה המידה. המתאים מריץ תחילה את מעבר log-polar כדי לשחזר את הסיבוב וקנה המידה, מיישם את ההופכי על אחת התמונות, ואז מריץ את מעבר ההזזה כדי לשחזר את ההיסט הנותר. הדגל בעל משמעות רק כאשר logpolar=False – הוא מבקש ממתאים מצב-ההזזה להפשיט תחילה את הסיבוב/קנה המידה.

הדפוס מתוך התמרות Polar – קרטזי ← פולרי ← התאמה – הוא מה ש-find_displacement() עם logpolar=True עושה בקריאה אחת. היישום מאחסן טלאי log-polar עזר בעת ההפעלה, לוכד וממיר-log-polar כל פריים חי, והמתודה משחזרת את הפרש הסיבוב-וקנה-המידה ביניהם. עבור יישומים הזקוקים לעוקב בלתי-תלוי-סיבוב-וקנה-מידה – רובוט עגינה שמצלמתו מתנדנדת ומתקרבת תוך זום אל מטרה, גימבל מיוצב הזקוק לדעת כיצד התמונה מסתובבת ביחס לעזר – זוהי הבנייה הסטנדרטית.

5.31.3. השימוש הקלאסי

השימוש הנפוץ ביותר ב-find_displacement() הוא הערכת תנועה מפריים-לפריים בצינור המעבד מצלמה נעה. המצלמה לוכדת טלאי קטן בחזקת 2 בפריים N, לוכדת את הטלאי בעל אותו גודל בפריים N+1, מריצה את find_displacement() על השניים, וקוראת את היסט הפיקסלים ביניהם. ההיסט הוא התנועה המוערכת של המצלמה (או של הסצנה, תלוי באיזו מערכת ייחוס חשובה) בין שתי הלכידות, שימושית עבור:

  • חישה בסגנון Optical-flow – רחפן ריחוף עם מצלמה מצביעה כלפי מטה משתמש בהיסט לכל פריים כדי להעריך את תנועתו הצידית ולהזין אותה חזרה אל בקר הטיסה.

  • ייצוב תמונה – ההיסט בין פריימים עוקבים מוחסר מהתמונה שנלכדה לפני שהיא מוקלטת או משודרת, מה שמייצר זרם וידאו חלק יותר.

  • יישור בדיקה – מצלמת סריקה הנעה לאורך מסוע משתמשת בהיסט לכל פריים כדי לרשום כל פריים מול הבא ולבנות תצוגה מאוחה של החלק כולו.

כל אחד מהיישומים האלה לובש את אותה צורה: ללכוד, להזיז, לצבור לתוך הערכה מתגלגלת, ללכוד שוב.