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

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

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

קוד לדוגמה

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

הגדרה

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

חבילות

המשימה MediaPipe Hand landmarker שלנו מחייבת את חבילת mediapipe PyPI. אפשר להתקין ולייבא את יחסי התלות האלה בעזרת הדברים הבאים:

$ python -m pip install mediapipe

יבוא

ייבא את המחלקות הבאות כדי לגשת לפונקציות המשימה של Hand שבהמשך.

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

מודל

כדי לבצע את המשימה MediaPipe Hand Scoreer נדרש מודל מאומן שתואם למשימה הזו. למידע נוסף על המודלים הזמינים המאומנים לשימוש ב-Hand Unlocker, עיינו בסקירה הכללית על המשימות בקטע המודלים.

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

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

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

יצירת המשימה

המשימה 'ציון דרך של MediaPipe' משתמשת בפונקציה 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: המצב שבו ניתן להזין תמונה יחידה.

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

LIVE_STREAM: המצב עבור סטרימינג בשידור חי של נתוני קלט, למשל ממצלמה. במצב הזה, יש להפעיל את resultListener כדי להגדיר מאזין לקבלת תוצאות באופן אסינכרוני.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
num_hands מספר הידיים המקסימלי שזוהה על ידי מזהה המקום של Hand. Any integer > 0 1
min_hand_detection_confidence ציון המהימנות המינימלי שזיהוי היד ייחשב כמוצלח במודל של זיהוי כף היד. 0.0 - 1.0 0.5
min_hand_presence_confidence ציון המהימנות המינימלי של ציון הנוכחות של היד במודל הזיהוי של ציון הדרך. במצב וידאו ובמצב שידור חי, אם דירוג המהימנות של הנוכחות של היד של המודל של ציון הדרך במכשיר נמוך מהסף הזה, ה-hand המצבer מפעיל את המודל לזיהוי כף היד. אחרת, נעשה שימוש באלגוריתם קליל למעקב אחר הידיים כדי לקבוע את המיקום של הידיים כדי לזהות ציוני דרך עתידיים. 0.0 - 1.0 0.5
min_tracking_confidence ציון הסמך המינימלי שצריך לעמוד בו כדי שהמעקב אחרי היד ייחשבו בהצלחה. זהו סף ה-IoU של התיבה התוחמת בין הידיים במסגרת הנוכחית לפריים האחרון. במצב וידאו ובמצב 'סטרימינג' של Hand שבהמשך יהיה, אם המעקב ייכשל, ה-Handhander יפעיל את זיהוי היד. אחרת, יתבצע דילוג על זיהוי היד. 0.0 - 1.0 0.5
result_callback מגדיר את הכלי להאזנה לתוצאות כך שיקבל את תוצאות הזיהוי באופן אסינכרוני כאשר ה-placeholder של היד נמצא במצב שידור חי. רלוונטי רק כשמצב ריצה מוגדר ל-LIVE_STREAM לא רלוונטי לא רלוונטי

הכנת הנתונים

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

תמונה

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)
    

מריצים את המשימה.

ה-Handhander משתמש בפונקציות זיהוי, מזהה_for_video ו-identifier_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)
    

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

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

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

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

ה-Handhander יוצר אובייקט תוצאה של placeholder של יד לכל הרצה של זיהוי. אובייקט התוצאה מכיל ציוני דרך של ידיים בקואורדינטות של תמונות, סימנים לציון ידיים בקואורדינטות בעולם והידיות השמאלית/ימנית של הידיים שזוהו.

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

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