מדריך לזיהוי תנועות לאינטרנט

המשימה MediaPipe Gesture Recognizer מאפשרת לזהות תנועות ידיים בזמן אמת, ומספקת את התוצאות של תנועות הידיים שזוהו ואת נקודות הציון של הידיים שזוהו. בהוראות האלה מוסבר איך להשתמש בכלי לזיהוי תנועות באפליקציות אינטרנט ובאפליקציות JavaScript.

אפשר לראות את המשימה הזו בפעולה על ידי צפייה בהדגמה. מידע נוסף על היכולות, המודלים ואפשרויות ההגדרה של המשימה הזו זמין במאמר סקירה כללית.

קוד לדוגמה

קוד לדוגמה של Gesture Recognizer מספק הטמעה מלאה של המשימה הזו ב-JavaScript לעיונכם. הקוד הזה עוזר לכם לבדוק את המשימה הזו ולהתחיל ליצור אפליקציה משלכם לזיהוי תנועות. אתם יכולים להציג, להריץ ולערוך את הדוגמה של הכלי לזיהוי תנועות באמצעות דפדפן האינטרנט בלבד.

הגדרה

בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח במיוחד לשימוש ב-Gesture Recognizer. מידע כללי על הגדרת סביבת הפיתוח לאתרים ול-JavaScript, כולל דרישות לגבי גרסת הפלטפורמה, זמין במדריך ההגדרה לאתרים.

חבילות JavaScript

הקוד של Gesture Recognizer זמין דרך חבילת MediaPipe @mediapipe/tasks-vision NPM. אפשר למצוא ולהוריד את הספריות האלה לפי ההוראות במדריך ההגדרה של הפלטפורמה.

אפשר להתקין את החבילות הנדרשות דרך NPM באמצעות הפקודה הבאה:

npm install @mediapipe/tasks-vision

אם רוצים לייבא את קוד המשימה דרך שירות של רשת להעברת תוכן (CDN), מוסיפים את הקוד הבא לתג <head> בקובץ ה-HTML:

<!-- You can replace JSDeliver with another CDN if you prefer to -->
<head>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/vision_bundle.mjs"
    crossorigin="anonymous"></script>
</head>

דגם

כדי להשתמש במשימה MediaPipe Gesture Recognizer, צריך מודל מאומן שתואם למשימה הזו. מידע נוסף על מודלים מאומנים זמינים לזיהוי תנועות מופיע בקטע Models בסקירה הכללית של המשימה.

בוחרים את המודל, מורידים אותו ושומרים אותו בספריית הפרויקט:

<dev-project-root>/app/shared/models/

יצירת המשימה

משתמשים באחת מהפונקציות של Gesture Recognizer createFrom...() כדי להכין את המשימה להפעלת מסקנות. משתמשים בפונקציה createFromModelPath() עם נתיב יחסי או מוחלט לקובץ המודל שעבר אימון. אם המודל כבר נטען לזיכרון, אפשר להשתמש בשיטה createFromModelBuffer().

בדוגמת הקוד הבאה מוצג שימוש בפונקציה createFromOptions() כדי להגדיר את המשימה. הפונקציה createFromOptions מאפשרת לכם להתאים אישית את Gesture Recognizer באמצעות אפשרויות הגדרה. מידע נוסף על אפשרויות ההגדרה זמין במאמר אפשרויות הגדרה.

בדוגמת הקוד הבאה אפשר לראות איך יוצרים ומגדירים את המשימה עם אפשרויות מותאמות אישית:

// Create task for image file processing:
const vision = await FilesetResolver.forVisionTasks(
  // path/to/wasm/root
  "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm "
);
const gestureRecognizer = await GestureRecognizer.createFromOptions(vision, {
  baseOptions: {
    modelAssetPath: "https://storage.googleapis.com/mediapipe-tasks/gesture_recognizer/gesture_recognizer.task"
  },
  numHands: 2
});

אפשרויות הגדרה

למשימה הזו יש את אפשרויות ההגדרה הבאות לאפליקציות אינטרנט:

שם האפשרות תיאור טווח ערכים ערך ברירת מחדל
runningMode הגדרת מצב ההפעלה של המשימה. יש שני מצבים:

IMAGE: המצב לקלט של תמונה אחת.

‫VIDEO: המצב של פריים מפוענח של סרטון או של שידור חי של נתוני קלט, כמו ממצלמה.
{IMAGE, VIDEO} IMAGE
num_hands המספר המקסימלי של ידיים שאפשר לזהות באמצעות GestureRecognizer. Any integer > 0 1
min_hand_detection_confidence ציון הסמך המינימלי לזיהוי היד כדי שהזיהוי ייחשב מוצלח במודל לזיהוי כף היד. 0.0 - 1.0 0.5
min_hand_presence_confidence ציון המהימנות המינימלי של ציון הנוכחות של היד במודל לזיהוי נקודות ציון של היד. במצב וידאו ובמצב שידור חי של Gesture Recognizer, אם ציון הסמך של נוכחות היד מהמודל של נקודות הציון של היד נמוך מהסף הזה, מופעל המודל של זיהוי כף היד. אחרת, נעשה שימוש באלגוריתם קל משקל למעקב ידיים כדי לקבוע את המיקום של הידיים לצורך זיהוי נקודות ציון בהמשך. 0.0 - 1.0 0.5
min_tracking_confidence ציון הסמך המינימלי שנדרש כדי שהמעקב אחרי הידיים ייחשב כמוצלח. זהו סף ה-IoU של תיבת התוחמת בין הידיים בפריים הנוכחי ובפריים האחרון. במצב וידאו ובמצב סטרימינג של Gesture Recognizer, אם המעקב נכשל, Gesture Recognizer מפעיל זיהוי של היד. אחרת, המערכת תדלג על זיהוי היד. 0.0 - 1.0 0.5
canned_gestures_classifier_options אפשרויות להגדרת אופן הפעולה של מסווג המחוות המוכנות. התנועות המוכנות מראש הן ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • הלוקאל של השמות המוצגים: הלוקאל שבו יש להשתמש לשמות המוצגים שצוינו באמצעות מטא-נתונים של מודל TFLite, אם יש כאלה.
  • מספר התוצאות המקסימלי: המספר המקסימלי של תוצאות הסיווג עם הדירוג הכי גבוה שיוחזרו. אם הערך הוא < 0, כל התוצאות הזמינות יוחזרו.
  • סף הציון: הציון שמתחתיו התוצאות נדחות. אם הערך הוא 0, כל התוצאות הזמינות יוחזרו.
  • רשימת ההיתרים של קטגוריות: רשימת ההיתרים של שמות הקטגוריות. אם המאפיין לא ריק, תוצאות הסיווג שהקטגוריה שלהן לא נכללת בקבוצה הזו יסוננו. אי אפשר להשתמש בו יחד עם רשימת חסימה.
  • רשימת ישויות שנחסמו לפי קטגוריה: רשימת שמות הקטגוריות שנחסמו. אם המאפיין לא ריק, תוצאות הסיווג שהקטגוריה שלהן נמצאת בקבוצה הזו יסוננו. אי אפשר להשתמש בהם ביחד עם רשימת ההיתרים.
    • הלוקאל של השמות המוצגים: any string
    • מספר התוצאות המקסימלי: any integer
    • סף הניקוד: 0.0-1.0
    • רשימת ההיתרים לקטגוריות: vector of strings
    • רשימת קטגוריות שנחסמו: vector of strings
    • הלוקאל של השמות המוצגים: "en"
    • מספר התוצאות המקסימלי: -1
    • סף הניקוד: 0
    • רשימת ההיתרים לקטגוריות: ריקה
    • רשימת קטגוריות שנחסמו: ריקה
    custom_gestures_classifier_options אפשרויות להגדרת אופן הפעולה של מסווג מחוות מותאם אישית.
  • הלוקאל של השמות המוצגים: הלוקאל שבו יש להשתמש לשמות המוצגים שצוינו באמצעות מטא-נתונים של מודל TFLite, אם יש כאלה.
  • מספר התוצאות המקסימלי: המספר המקסימלי של תוצאות הסיווג עם הדירוג הכי גבוה שיוחזרו. אם הערך הוא < 0, כל התוצאות הזמינות יוחזרו.
  • סף הציון: הציון שמתחתיו התוצאות נדחות. אם הערך הוא 0, כל התוצאות הזמינות יוחזרו.
  • רשימת ההיתרים של קטגוריות: רשימת ההיתרים של שמות הקטגוריות. אם המאפיין לא ריק, תוצאות הסיווג שהקטגוריה שלהן לא נכללת בקבוצה הזו יסוננו. אי אפשר להשתמש בו יחד עם רשימת חסימה.
  • רשימת ישויות שנחסמו לפי קטגוריה: רשימת שמות הקטגוריות שנחסמו. אם המאפיין לא ריק, תוצאות הסיווג שהקטגוריה שלהן נמצאת בקבוצה הזו יסוננו. אי אפשר להשתמש בהם ביחד עם רשימת ההיתרים.
    • הלוקאל של השמות המוצגים: any string
    • מספר התוצאות המקסימלי: any integer
    • סף הניקוד: 0.0-1.0
    • רשימת ההיתרים לקטגוריות: vector of strings
    • רשימת קטגוריות שנחסמו: vector of strings
    • הלוקאל של השמות המוצגים: "en"
    • מספר התוצאות המקסימלי: -1
    • סף הניקוד: 0
    • רשימת ההיתרים לקטגוריות: ריקה
    • רשימת קטגוריות שנחסמו: ריקה

    הכנת הנתונים

    המודל Gesture Recognizer יכול לזהות תנועות בתמונות בכל פורמט שנתמך בדפדפן המארח. בנוסף, המשימה מטפלת בעיבוד מקדים של נתוני הקלט, כולל שינוי גודל, סיבוב ונרמול ערכים. כדי לזהות תנועות בסרטונים, אפשר להשתמש ב-API כדי לעבד במהירות פריים אחד בכל פעם, ולהשתמש בחותמת הזמן של הפריים כדי לקבוע מתי התנועות מתרחשות בסרטון.

    הרצת המשימה

    הכלי לזיהוי תנועות משתמש בשיטות recognize() (עם מצב הפעלה 'image') ו-recognizeForVideo() (עם מצב הפעלה 'video') כדי להפעיל מסקנות. המשימה מעבדת את הנתונים, מנסה לזהות תנועות ידיים ואז מדווחת על התוצאות.

    בדוגמה הבאה אפשר לראות איך להריץ את העיבוד באמצעות מודל המשימות:

    תמונה

    const image = document.getElementById("image") as HTMLImageElement;
    const gestureRecognitionResult = gestureRecognizer.recognize(image);

    וידאו

    await gestureRecognizer.setOptions({ runningMode: "video" });
    
    let lastVideoTime = -1;
    function renderLoop(): void {
      const video = document.getElementById("video");
    
      if (video.currentTime !== lastVideoTime) {
        const gestureRecognitionResult = gestureRecognizer.recognizeForVideo(video);
        processResult(gestureRecognitionResult);
        lastVideoTime = video.currentTime;
      }
    
      requestAnimationFrame(() => {
        renderLoop();
      });
    }

    הקריאות לשיטות Gesture Recognizer recognize() ו-recognizeForVideo() מופעלות באופן סינכרוני וחוסמות את השרשור של ממשק המשתמש. אם אתם מזהים תנועות במסגרות של סרטון מהמצלמה של המכשיר, כל זיהוי יחסום את השרשור הראשי. כדי למנוע את זה, אפשר להטמיע web workers כדי להריץ את השיטות recognize() ו-recognizeForVideo() בשרשור אחר.

    כדי לראות הטמעה מלאה יותר של הרצת משימה של זיהוי תנועות, אפשר לעיין בדוגמה.

    טיפול בתוצאות והצגתן

    ה-Gesture Recognizer יוצר אובייקט של תוצאת זיהוי תנועה לכל הפעלה של זיהוי. אובייקט התוצאה מכיל ציוני דרך של הידיים בקואורדינטות של התמונה, ציוני דרך של הידיים בקואורדינטות של העולם, את היד הדומיננטית(יד ימין או יד שמאל) וקטגוריות של תנועות הידיים שזוהו.

    בדוגמה הבאה מוצגים נתוני הפלט של המשימה הזו:

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

    • יד דומיננטית

      היד הדומיננטית מייצגת אם הידיים שזוהו הן יד שמאל או יד ימין.

    • תנועות

      קטגוריות התנועות המזוהות של הידיים שזוהו.

    • ציוני דרך

      יש 21 נקודות ציון של הידיים, שכל אחת מהן מורכבת מקואורדינטות x, y ו-z. הקואורדינטות x ו-y מנורמלות לערכים שבין [0.0, 1.0] לפי הרוחב והגובה של התמונה, בהתאמה. קואורדינטת z מייצגת את עומק נקודת הציון, כאשר העומק בפרק כף היד הוא נקודת המוצא. ככל שהערך קטן יותר, כך נקודת הציון קרובה יותר למצלמה. הגודל של z דומה לזה של x.

    • אתרים חשובים בעולם

      21 נקודות הציון של היד מוצגות גם בקואורדינטות עולמיות. כל נקודת ציון מורכבת מ-x, ‏ y ו-z, שמייצגים קואורדינטות תלת-ממדיות בעולם האמיתי במטרים, עם נקודת המוצא במרכז הגיאומטרי של היד.

    GestureRecognizerResult:
      Handedness:
        Categories #0:
          index        : 0
          score        : 0.98396
          categoryName : Left
      Gestures:
        Categories #0:
          score        : 0.76893
          categoryName : Thumb_Up
      Landmarks:
        Landmark #0:
          x            : 0.638852
          y            : 0.671197
          z            : -3.41E-7
        Landmark #1:
          x            : 0.634599
          y            : 0.536441
          z            : -0.06984
        ... (21 landmarks for a hand)
      WorldLandmarks:
        Landmark #0:
          x            : 0.067485
          y            : 0.031084
          z            : 0.055223
        Landmark #1:
          x            : 0.063209
          y            : -0.00382
          z            : 0.020920
        ... (21 world landmarks for a hand)
    

    בתמונות הבאות מוצגת ויזואליזציה של פלט המשימה:

    יד בתנועת אגודל למעלה עם מיפוי של מבנה השלד של היד

    לדוגמה מלאה יותר להטמעה של יצירת משימה של זיהוי תנועות, אפשר לעיין בדוגמה.