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

המשימה 'MediaPipe Pose Scoreer' מאפשרת לזהות ציוני דרך של גופות אנושיות בתמונה או בסרטון. אפשר להשתמש במשימה כדי לזהות מיקומים מרכזיים בגוף, לנתח את היציבה ולסווג תנועות. במשימה הזו נעשה שימוש במודלים של למידת מכונה (ML) שעובדים עם תמונות או סרטונים בודדים. הפלט של המשימה מהגוף מייצג ציוני דרך בקואורדינטות של תמונה ובקואורדינטות בעולם תלת-ממדי.

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

קוד לדוגמה

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

אם אתם מטמיעים את Pose Scoreer עבור Raspberry Pi, עיינו באפליקציה לדוגמה של Raspberry Pi.

הגדרה

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

חבילות

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

$ python -m pip install mediapipe

יבוא

מייבאים את המחלקות הבאות כדי לגשת לפונקציות המשימה של Pose Scoreer:

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

מודל

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

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

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

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

יצירת המשימה

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

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

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

תמונה

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
PoseLandmarker = mp.tasks.vision.PoseLandmarker
PoseLandmarkerOptions = mp.tasks.vision.PoseLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

options = PoseLandmarkerOptions(
    base_options=BaseOptions(model_asset_path=model_path),
    running_mode=VisionRunningMode.IMAGE)

with PoseLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

וידאו

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
PoseLandmarker = mp.tasks.vision.PoseLandmarker
PoseLandmarkerOptions = mp.tasks.vision.PoseLandmarkerOptions
VisionRunningMode = mp.tasks.vision.RunningMode

# Create a pose landmarker instance with the video mode:
options = PoseLandmarkerOptions(
    base_options=BaseOptions(model_asset_path=model_path),
    running_mode=VisionRunningMode.VIDEO)

with PoseLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

שידור חי

import mediapipe as mp

BaseOptions = mp.tasks.BaseOptions
PoseLandmarker = mp.tasks.vision.PoseLandmarker
PoseLandmarkerOptions = mp.tasks.vision.PoseLandmarkerOptions
PoseLandmarkerResult = mp.tasks.vision.PoseLandmarkerResult
VisionRunningMode = mp.tasks.vision.RunningMode

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

options = PoseLandmarkerOptions(
    base_options=BaseOptions(model_asset_path=model_path),
    running_mode=VisionRunningMode.LIVE_STREAM,
    result_callback=print_result)

with PoseLandmarker.create_from_options(options) as landmarker:
  # The landmarker is initialized. Use it here.
  # ...
    

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

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

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

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

IMAGE: המצב שבו ניתן להזין תמונה יחידה.

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

LIVE_STREAM: המצב עבור סטרימינג בשידור חי של נתוני קלט, למשל ממצלמה. במצב הזה, יש להפעיל את resultListener כדי להגדיר מאזין לקבלת תוצאות באופן אסינכרוני.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
num_poses המספר המקסימלי של תנוחות ש-Pose Scoreer יכול לזהות. Integer > 0 1
min_pose_detection_confidence ציון המהימנות המינימלי שזיהוי התנוחה ייחשב כמוצלח. Float [0.0,1.0] 0.5
min_pose_presence_confidence ציון המהימנות המינימלי של ציון הנוכחות לתנוחה בזיהוי מיקום התנוחה. Float [0.0,1.0] 0.5
min_tracking_confidence ציון הסמך המינימלי שצריך לעמוד בו כדי לעקוב אחרי התנוחה כדי להיחשב בהצלחה. Float [0.0,1.0] 0.5
output_segmentation_masks האם Pose לעשות פלט של מסכת פילוח לתנוחה שזוהתה. Boolean False
result_callback מגדיר את ה-listener כך שיקבל את התוצאות של ציוני הדרך באופן אסינכרוני כש-Pose landmarker נמצא במצב שידור חי. אפשר להשתמש רק כשמצב ריצה מוגדר ל-LIVE_STREAM ResultListener N/A

הכנת הנתונים

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

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

ה-Pose Discoverer משתמש בפונקציות detect, detect_for_video ו-detect_async כדי להוציא מסקנות. כדי לסמן תנוחה, התהליך כולל עיבוד מראש של נתוני קלט וזיהוי תנוחות בתמונה.

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

תמונה

# Perform pose landmarking on the provided single image.
# The pose landmarker must be created with the image mode.
pose_landmarker_result = landmarker.detect(mp_image)
    

וידאו

# Perform pose landmarking on the provided single image.
# The pose landmarker must be created with the video mode.
pose_landmarker_result = landmarker.detect_for_video(mp_image, frame_timestamp_ms)
    

שידור חי

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

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

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

כדי לראות דוגמה מלאה להרצת Pose Scoreer בתמונה, עיינו בקוד לדוגמה.

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

ה-Pose Scoreer מחזיר אובייקט poseLandmarkerResult בכל הרצת זיהוי. אובייקט התוצאה מכיל קואורדינטות עבור כל ציון דרך של תנוחה.

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

PoseLandmarkerResult:
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : 0.129959
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
      visibility   : 0.999909
      presence     : 0.999958
    ... (33 landmarks per pose)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
      visibility   : 0.999976
      presence     : 0.999998
    ... (33 world landmarks per pose)
  SegmentationMasks:
    ... (pictured below)

הפלט מכיל גם קואורדינטות מנורמלות (Landmarks) וגם קואורדינטות עולמיות (WorldLandmarks) לכל ציון דרך.

הפלט מכיל את הקואורדינטות המנורמלות הבאות (Landmarks):

  • x ו-y: קואורדינטות של ציוני דרך מנורמלות בין 0.0 ל-1.0 ברוחב התמונה (x) ובגובה (y).

  • z: העומק לציון דרך, כשהעומק בנקודת האמצע של הירכיים הוא המקור. ככל שהערך קטן יותר, ציון הדרך קרוב יותר למצלמה. הגודל של z משתמש בערך באותו קנה מידה כמו x.

  • visibility: הסבירות שציון הדרך גלוי בתמונה.

הפלט מכיל את הקואורדינטות הבאות מהעולם (WorldLandmarks):

  • x, y ו-z: קואורדינטות תלת-ממדיות בעולם האמיתי במטרים, עם נקודת האמצע של מותניים.

  • visibility: הסבירות שציון הדרך גלוי בתמונה.

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

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

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