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

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

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

קוד לדוגמה

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

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

הגדרה

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

חבילות

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

$ python -m pip install mediapipe

יבוא

כדי לגשת לפונקציות המשימות של Hand Lawer, מייבאים את המחלקות הבאות:

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

דגם

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

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

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

ה-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 מוסבר איך להציג את התוצאות שהוחזרו מהמשימה. פרטים נוספים זמינים בקוד לדוגמה.