מדריך לזיהוי ציוני דרך בכף יד ב-Python

המשימה 'זיהוי ציוני דרך של ידיים' ב-MediaPipe מאפשרת לזהות את ציוני הדרך של הידיים בתמונה. בהוראות הבאות מוסבר איך להשתמש ב-Hand Landmarker עם Python. דוגמת הקוד שמתוארת בהוראות האלה זמינה ב-GitHub.

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

קוד לדוגמה

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

אם אתם מטמיעים את Hand Landmarker ל-Raspberry Pi, תוכלו לעיין באפליקציית הדוגמה ל-Raspberry Pi.

הגדרה

בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח ופרויקטי הקוד, באופן ספציפי לשימוש ב-Hand Landmarker. מידע כללי על הגדרת סביבת הפיתוח לשימוש במשימות של 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, נדרש מודל מאומן שתואם למשימה הזו. מידע נוסף על המודלים המאומנים הזמינים ל-Hand Landmarker זמין בקטע 'מודלים' בסקירה הכללית של המשימה.

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

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

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

יצירת המשימה

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

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

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

תמונה

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HandLandmarker = mp.tasks.vision.HandLandmarker
HandLandmarkerOptions = mp.tasks.vision.HandLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a hand landmarker instance with the image mode:
options = HandLandmarkerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.IMAGE)
with HandLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

וידאו

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HandLandmarker = mp.tasks.vision.HandLandmarker
HandLandmarkerOptions = mp.tasks.vision.HandLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a hand landmarker instance with the video mode:
options = HandLandmarkerOptions(
    base_options=BaseOptions(model_asset_path='/path/to/model.task'),
    running_mode=VisionRunningMode.VIDEO)
with HandLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

שידור חי

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
HandLandmarker = mp.tasks.vision.HandLandmarker
HandLandmarkerOptions = mp.tasks.vision.HandLandmarkerOptions
HandLandmarkerResult = mp.tasks.vision.HandLandmarkerResult
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a hand landmarker instance with the live stream mode:
def print_result(result: HandLandmarkerResult, output_image: mp.Image, timestamp_ms: int):
    print('hand landmarker result: {}'.format(result))

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

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

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

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

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

IMAGE: המצב להזנת תמונה אחת.

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

LIVE_STREAM: המצב של סטרימינג בשידור חי של נתוני קלט, למשל ממצלמה. במצב הזה, צריך להפעיל את resultListener כדי להגדיר מאזין שיקבל את התוצאות באופן אסינכרוני.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
num_hands המספר המקסימלי של ידיים שזוהו על ידי הגלאי של נקודות ציון ביד. 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 של תיבת ההיקף בין הידיים בפריים הנוכחי לבין הפריים האחרון. במצב וידאו ובמצב סטרימינג של Hand Landmarker, אם המעקב נכשל, התכונה Hand Landmarker מפעילה זיהוי של היד. אחרת, המערכת תדלג על זיהוי היד. 0.0 - 1.0 0.5
result_callback מגדיר את מאזין התוצאות כך שיקבל את תוצאות הזיהוי באופן אסינכרוני כשכלי הסימון של כף היד נמצא במצב של שידור חי. רלוונטי רק כשמצב ההפעלה מוגדר כ-LIVE_STREAM לא רלוונטי לא רלוונטי

הכנת הנתונים

מכינים את הקלט כקובץ תמונה או כמערך numpy, ואז ממירים אותו לאובייקט 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)
    

הרצת המשימה

ה-Hand Landmarker משתמש בפונקציות detect, ‏ detect_for_video ו-detect_async כדי להפעיל מסקנות. בתהליך זיהוי ציוני הדרך של היד, המערכת מבצעת עיבוד מקדים של נתוני הקלט, זיהוי ידיים בתמונה וזיהוי ציוני הדרך של היד.

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

תמונה

# Perform hand landmarks detection on the provided single image.
# The hand landmarker must be created with the image mode.
hand_landmarker_result = landmarker.detect(mp_image)
    

וידאו

# Perform hand landmarks detection on the provided single image.
# The hand landmarker must be created with the video mode.
hand_landmarker_result = landmarker.detect_for_video(mp_image, frame_timestamp_ms)
    

שידור חי

# Send live image data to perform hand landmarks detection.
# The results are accessible via the `result_callback` provided in
# the `HandLandmarkerOptions` object.
# The hand landmarker must be created with the live stream mode.
landmarker.detect_async(mp_image, frame_timestamp_ms)
    

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

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

דוגמה מלאה להפעלת Hand Landmarker בתמונה מפורטת בדוגמת הקוד.

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

ה-Hand Landmarker יוצר אובייקט תוצאה של Hand Landmarker לכל הפעלה של זיהוי. אובייקט התוצאה מכיל ציוני ציון של היד בקואורדינטות התמונה, ציוני ציון של היד בקואורדינטות העולם ואת היד הדומיננטית(יד ימין/יד שמאל) של הידיים שזוהו.

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

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

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

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

  • ציוני דרך

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

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

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

HandLandmarkerResult:
  Handedness:
    Categories #0:
      index        : 0
      score        : 0.98396
      categoryName : Left
  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)

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

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

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