מדריך לזיהוי תנועות ל-Python

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

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

קוד לדוגמה

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

אם אתם מטמיעים את מזהה התנועות ל-Raspberry Pi, עיינו דוגמה ל-Raspberry Pi app.

הגדרה

בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח פרויקטי קוד במיוחד לשימוש בזיהוי תנועות. למידע כללי על להגדיר את סביבת הפיתוח לשימוש במשימות של MediaPipe, כולל הדרישות לגרסאות הפלטפורמה זמינות במדריך ההגדרה עבור Python.

חבילות

למשימה של MediaPipe תנועות לזיהוי תנועות נדרשת חבילת ה-Mediapipe PyPI. אפשר להתקין את לייבא את יחסי התלות האלה באמצעות:

$ python -m pip install mediapipe

יבוא

כדי לגשת לפונקציות המשימה של מזהה התנועות, ניתן לייבא את המחלקות הבאות:

import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision

דגם

למשימה של מזהה התנועות של MediaPipe נדרשת חבילת מודלים מאומנת שתואמים ל- במשימה הזאת. למידע נוסף על המודלים הזמינים המאומנים לזיהוי תנועות, ראו את הקטע 'מודלים' בסקירה הכללית על המשימה.

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

model_path = '/absolute/path/to/gesture_recognizer.task'

מציינים את הנתיב של המודל בתוך הפרמטר 'שם המודל', כמו בדוגמה הבאה:

base_options = BaseOptions(model_asset_path=model_path)

יצירת המשימה

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

הקוד הבא מדגים איך יוצרים ומגדירים את המשימה הזו.

הדוגמאות האלה גם מראות את הווריאציות של מבנה המשימה עבור תמונות, קובצי וידאו וסטרימינג של וידאו בשידור חי.

תמונה

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
GestureRecognizer = mp.tasks.vision.GestureRecognizer
GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a gesture recognizer instance with the image mode:
options = GestureRecognizerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.IMAGE)
with GestureRecognizer.create_from_options(options) as recognizer:
  # The detector is initialized. Use it here.
  # ...
    

וידאו

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
GestureRecognizer = mp.tasks.vision.GestureRecognizer
GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a gesture recognizer instance with the video mode:
options = GestureRecognizerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.VIDEO)
with GestureRecognizer.create_from_options(options) as recognizer:
  # The detector is initialized. Use it here.
  # ...
    

שידור חי

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
GestureRecognizer = mp.tasks.vision.GestureRecognizer
GestureRecognizerOptions = mp.tasks.vision.GestureRecognizerOptions
GestureRecognizerResult = mp.tasks.vision.GestureRecognizerResult
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a gesture recognizer instance with the live stream mode:
def print_result(result: GestureRecognizerResult, output_image: mp.Image, timestamp_ms: int):
    print('gesture recognition result: {}'.format(result))

options = GestureRecognizerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.LIVE_STREAM,
    result_callback=print_result)
with GestureRecognizer.create_from_options(options) as recognizer:
  # The detector is initialized. Use it here.
  # ...
    

אפשרויות תצורה

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

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

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

סרטון: המצב של פריימים מפוענחים בסרטון.

LIVE_STREAM: המצב לשידור חי של קלט נתונים ממצלמה, במצב הזה, resultListener חייב להיות נשלחה קריאה כדי להגדיר אוזן כדי לקבל תוצאות באופן אסינכרוני.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
num_hands מספר הידיים המקסימלי שניתן לזהות GestureRecognizer. Any integer > 0 1
min_hand_detection_confidence ציון הסמך המינימלי שצריך להיות זיהוי היד נחשב למוצלח במודל זיהוי כף היד. 0.0 - 1.0 0.5
min_hand_presence_confidence ציון הסמך המינימלי של ציון הנוכחות בכף היד לזיהוי מאפיינים של ציוני דרך. במצב וידאו ובמצב שידור חי באמצעות הכלי לזיהוי תנועות, אם הציון המשוער של נוכחות היד מהמודל של יד הציון מוצג מתחת הסף הזה, הוא מפעיל את המודל לזיהוי כף היד. אחרת, נעשה שימוש באלגוריתם קל למעקב אחר תנועות הידיים כדי לקבוע את המיקום של את הידיים לזיהוי של ציוני הדרך הבאים. 0.0 - 1.0 0.5
min_tracking_confidence ציון הסמך המינימלי שצריך להביא בחשבון את המעקב אחר היד הפעולה הצליחה. זהו סף IoU של התיבה התוחמת בין הידיים הפריים הנוכחי והפריים האחרון. במצב וידאו ובמצב 'זרם' של הכלי לזיהוי תנועות, אם המעקב נכשל, הכלי לזיהוי תנועות מפעיל את היד זיהוי וזיהוי אובייקטים. אחרת, המערכת תדלג על זיהוי היד. 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
    • רשימת היתרים של קטגוריות: ריקה
    • רשימת הישויות שנחסמו: ריקה
    result_callback מגדיר את אוזן התוצאות לקבל את תוצאות הסיווג באופן אסינכרוני כשמזהה התנועה נמצא במצב השידור החי. אפשר להשתמש באפשרות הזו רק כשמצב הריצה מוגדר ל-LIVE_STREAM ResultListener לא רלוונטי לא רלוונטי

    הכנת נתונים

    מכינים את הקלט כקובץ תמונה או כמערך נומרי, ואז ממירים אותו אובייקט mediapipe.Image. אם הקלט הוא קובץ וידאו או שידור חי מצלמת אינטרנט, אפשר להשתמש בספרייה חיצונית כמו OpenCV לטעינת פריימים של קלט בתור numpy מערכים מגוונים.

    תמונה

    import mediapipe as mp
    
    # Load the input image from an image file.
    mp_image = mp.Image.create_from_file('/path/to/image')
    
    # Load the input image from a numpy array.
    mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=numpy_image)
        

    וידאו

    import mediapipe as mp
    
    # Use OpenCV’s VideoCapture to load the input video.
    
    # Load the frame rate of the video using OpenCV’s CV_CAP_PROP_FPS
    # You’ll need it to calculate the timestamp for each frame.
    
    # Loop through each frame in the video using VideoCapture#read()
    
    # Convert the frame received from OpenCV to a MediaPipe’s Image object.
    mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=numpy_frame_from_opencv)
        

    שידור חי

    import mediapipe as mp
    
    # Use OpenCV’s VideoCapture to start capturing from the webcam.
    
    # Create a loop to read the latest frame from the camera using VideoCapture#read()
    
    # Convert the frame received from OpenCV to a MediaPipe’s Image object.
    mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=numpy_frame_from_opencv)
        

    הרצת המשימה

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

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

    תמונה

    # Perform gesture recognition on the provided single image.
    # The gesture recognizer must be created with the image mode.
    gesture_recognition_result = recognizer.recognize(mp_image)
        

    וידאו

    # Perform gesture recognition on the provided single image.
    # The gesture recognizer must be created with the video mode.
    gesture_recognition_result = recognizer.recognize_for_video(mp_image, frame_timestamp_ms)
        

    שידור חי

    # Send live image data to perform gesture recognition.
    # The results are accessible via the `result_callback` provided in
    # the `GestureRecognizerOptions` object.
    # The gesture recognizer must be created with the live stream mode.
    recognizer.recognize_async(mp_image, frame_timestamp_ms)
        

    שימו לב לנקודות הבאות:

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

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

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

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

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

    התוצאה 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)
    

    בתמונות הבאות אפשר לראות את פלט המשימה:

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