המשימה 'MediaPipe Pose Scoreer' מאפשרת לזהות ציוני דרך של גופות אנושיות בתמונה או בסרטון. אפשר להשתמש במשימה כדי לזהות מיקומים מרכזיים בגוף, לנתח את היציבה ולסווג תנועות. במשימה הזו נעשה שימוש במודלים של למידת מכונה (ML) שעובדים עם תמונות או סרטונים בודדים. הפלט של המשימה מהגוף מייצג ציוני דרך בקואורדינטות של תמונה ובקואורדינטות בעולם תלת-ממדי.
דוגמת הקוד שמתוארת בהוראות האלו זמינה ב-GitHub. למידע נוסף על היכולות, המודלים ואפשרויות ההגדרה של המשימה הזו, קראו את הסקירה הכללית.
קוד לדוגמה
הקוד לדוגמה של משימות MediaPipe הוא יישום פשוט של אפליקציה של Pose שבהמשך. בדוגמה הזו, נעשה שימוש במצלמה במכשיר Android פיזי כדי לזהות תנוחות בשידור וידאו רציף. האפליקציה יכולה גם לזהות תנוחות בתמונות ובסרטונים מגלריית המכשיר.
ניתן לך להשתמש באפליקציה כנקודת התחלה של אפליקציה משלכם ל-Android, או להתייחס אליה כשמשנים אפליקציה קיימת. הקוד לדוגמה של Pose Scoreer מתארח ב-GitHub.
הורדת הקוד
בהוראות הבאות מוסבר איך ליצור עותק מקומי של הקוד לדוגמה באמצעות כלי שורת הפקודה git.
כדי להוריד את הקוד לדוגמה:
- משכפלים את מאגר ה-Git באמצעות הפקודה הבאה:
git clone https://github.com/google-ai-edge/mediapipe-samples
- לחלופין, אפשר להגדיר את מכונת ה-Git לשימוש בקופה עם נפח נתונים נמוך, כדי שיהיו לכם רק את הקבצים של האפליקציה לדוגמה של Pose שבהמשך:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/pose_landmarker/android
אחרי שיוצרים גרסה מקומית של הקוד לדוגמה, אפשר לייבא את הפרויקט אל Android Studio ולהפעיל את האפליקציה. לקבלת הוראות, אפשר לעיין במדריך ההגדרה ל-Android.
רכיבים עיקריים
הקבצים הבאים מכילים את הקוד החיוני לאפליקציה לדוגמה של ציון דרך:
- PoseLandmarkerHelper.kt – מפעיל את מנצימציית התנוחה ומטפל במודל ובבחירת הנציגים.
- CameraFragment.kt – שימוש במצלמת המכשיר ועיבוד של נתוני קלט התמונה והווידאו.
- GalleryFragment.kt – מקיים אינטראקציה עם
OverlayView
כדי להציג את התמונה או הסרטון בפלט. - OverlayView.kt – מיישמת את התצוגה לתנוחות שזוהו.
הגדרה
בקטע הזה מתוארים שלבי המפתח להגדרת סביבת הפיתוח ופרויקטים של קוד באופן ספציפי לשימוש ב-Pose Scoreer. במדריך ההגדרה ל-Android תוכלו לקרוא מידע כללי על הגדרת סביבת הפיתוח לשימוש במשימות של MediaPipe, כולל הדרישות לגבי גרסת הפלטפורמה.
יחסי תלות
המשימה 'Pose שבהמשך' משתמשת בספרייה com.google.mediapipe:tasks-vision
. מוסיפים את התלות הזו לקובץ build.gradle
באפליקציה ל-Android:
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
מודל
כדי לבצע את המשימה MediaPipe Pose Scoreer צריך חבילה מאומנת של מודלים, שתואמת למשימה הזו. למידע נוסף על המודלים הזמינים לאימון של Pose, אפשר לעיין בסקירה הכללית של המשימות בקטע Models.
בוחרים ומורידים את המודל, ומאחסנים אותו בספריית הפרויקט:
<dev-project-root>/src/main/assets
מציינים את הנתיב של המודל בתוך הפרמטר ModelAssetPath
. בקוד לדוגמה, המודל מוגדר בקובץ PoseLandmarkerHelper.kt
:
val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)
יצירת המשימה
כדי להגדיר את המשימה, MediaPipe Pose לעשות שימוש בפונקציה createFromOptions()
. הפונקציה createFromOptions()
מקבלת ערכים לאפשרויות התצורה. מידע נוסף על אפשרויות ההגדרה זמין במאמר אפשרויות תצורה.
Pose Lander תומך בסוגי הקלט הבאים: תמונות סטילס, קובצי וידאו וסטרימינג של וידאו בשידור חי. כשיוצרים את המשימה, צריך לציין את מצב הריצה שתואם לסוג נתוני הקלט. כדי לראות איך יוצרים את המשימה, צריך לבחור את הכרטיסייה בהתאם לסוג נתוני הקלט.
תמונה
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setRunningMode(RunningMode.IMAGE) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
וידאו
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setRunningMode(RunningMode.VIDEO) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
שידור חי
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setResultListener(this::returnLivestreamResult) .setErrorListener(this::returnLivestreamError) .setRunningMode(RunningMode.LIVE_STREAM) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
הטמעת הקוד לדוגמה של Pose Scoreer מאפשרת למשתמש לעבור בין מצבי עיבוד. הגישה הזו יוצרת את הקוד ליצירת משימה ועשויה לא להתאים לתרחיש שלכם לדוגמה. אפשר לראות את הקוד הזה בפונקציה setupPoseLandmarker()
בקובץ PoseLandmarkerHelper.kt
.
אפשרויות הגדרה
המשימה כוללת את אפשרויות ההגדרה הבאות לאפליקציות ל-Android:
שם האפשרות | תיאור | טווח ערכים | ערך ברירת מחדל |
---|---|---|---|
runningMode |
מגדיר את מצב הריצה של המשימה. יש שלושה
מצבים: IMAGE: המצב שבו ניתן להזין תמונה יחידה. וידאו: המצב של פריימים מפוענחים של סרטון. LIVE_STREAM: המצב עבור סטרימינג בשידור חי של נתוני קלט, למשל ממצלמה. במצב הזה, יש להפעיל את resultListener כדי להגדיר מאזין לקבלת תוצאות באופן אסינכרוני. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
numposes |
המספר המקסימלי של תנוחות ש-Pose Scoreer יכול לזהות. | Integer > 0 |
1 |
minPoseDetectionConfidence |
ציון המהימנות המינימלי שזיהוי התנוחה ייחשב כמוצלח. | Float [0.0,1.0] |
0.5 |
minPosePresenceConfidence |
ציון המהימנות המינימלי של ציון הנוכחות לתנוחה בזיהוי מיקום התנוחה. | Float [0.0,1.0] |
0.5 |
minTrackingConfidence |
ציון הסמך המינימלי שצריך לעמוד בו כדי לעקוב אחרי התנוחה כדי להיחשב בהצלחה. | Float [0.0,1.0] |
0.5 |
outputSegmentationMasks |
האם Pose לעשות פלט של מסכת פילוח לתנוחה שזוהתה. | Boolean |
False |
resultListener |
מגדיר את ה-listener כך שיקבל את התוצאות של ציוני הדרך
באופן אסינכרוני כש-Pose landmarker נמצא במצב שידור חי.
אפשר להשתמש רק כשמצב ריצה מוגדר ל-LIVE_STREAM |
ResultListener |
N/A |
errorListener |
מגדירה האזנה לשגיאות כאופציונלי. | ErrorListener |
N/A |
הכנת הנתונים
התכונה Pose Discoverer פועלת עם תמונות, קובצי וידאו וסטרימינג של סרטונים בשידור חי. המשימה מטפלת בעיבוד מראש של קלט הנתונים, כולל שינוי הגודל, סיבוב ונירמול הערכים.
הקוד הבא מדגים איך למסור נתונים לעיבוד. הדוגמאות האלה כוללות פרטים על הטיפול בנתונים מתמונות, מקובצי וידאו ומשידורים חיים.
תמונה
import com.google.mediapipe.framework.image.BitmapImageBuilder import com.google.mediapipe.framework.image.MPImage // Convert the input Bitmap object to an MPImage object to run inference val mpImage = BitmapImageBuilder(image).build()
וידאו
import com.google.mediapipe.framework.image.BitmapImageBuilder import com.google.mediapipe.framework.image.MPImage val argb8888Frame = if (frame.config == Bitmap.Config.ARGB_8888) frame else frame.copy(Bitmap.Config.ARGB_8888, false) // Convert the input Bitmap object to an MPImage object to run inference val mpImage = BitmapImageBuilder(argb8888Frame).build()
שידור חי
import com.google.mediapipe.framework.image.BitmapImageBuilder import com.google.mediapipe.framework.image.MPImage // Convert the input Bitmap object to an MPImage object to run inference val mpImage = BitmapImageBuilder(rotatedBitmap).build()
בקוד לדוגמה של Pose Scoreer, הכנת הנתונים מתבצעת בקובץ PoseLandmarkerHelper.kt
.
מריצים את המשימה.
בהתאם לסוג הנתונים שאתם עובדים איתם, צריך להשתמש בשיטה poseLandmarker.detect...()
שספציפית לסוג הנתונים הזה. צריך להשתמש ב-detect()
לתמונות בודדות, ב-detectForVideo()
לפריימים בקובצי וידאו וב-detectAsync()
לסטרימינג של וידאו. כשאתם מבצעים זיהוי בשידור וידאו, הקפידו להריץ את הזיהויים בשרשור נפרד כדי למנוע חסימה של שרשור התגובות של המשתמש.
דוגמאות הקוד הבאות מדגימות איך להפעיל את Pose Scoreer במצבי הנתונים השונים:
תמונה
val result = poseLandmarker.detect(mpImage)
וידאו
val timestampMs = i * inferenceIntervalMs poseLandmarker.detectForVideo(mpImage, timestampMs) .let { detectionResult -> resultList.add(detectionResult) }
שידור חי
val mpImage = BitmapImageBuilder(rotatedBitmap).build() val frameTime = SystemClock.uptimeMillis() poseLandmarker.detectAsync(mpImage, frameTime)
שימו לב לנקודות הבאות:
- כשמפעילים את התכונה במצב וידאו או בשידור חי, צריך לציין את חותמת הזמן של מסגרת הקלט למשימה של Pose לעשות
- כשמריצים את המשימה במצב תמונה או במצב וידאו, המשימה Pose שבהמשך חוסמת את ה-thread הנוכחי עד לסיום העיבוד של התמונה או המסגרת של הקלט. כדי למנוע חסימה של שילוב המשתמש, צריך לבצע את העיבוד ב-thread ברקע.
- כשהיא פועלת במצב של שידור חי, המשימה של Pose Looker חוזרת באופן מיידי ולא חוסמת את השרשור הנוכחי. בכל פעם שהוא יסיים לעבד פריים קלט, הוא יופעל עם מאזן התוצאות.
בקוד לדוגמה של Pose Targeter, הפונקציות detect
, detectForVideo
ו-detectAsync
מוגדרות בקובץ PoseLandmarkerHelper.kt
.
טיפול בתוצאות והצגתן
ה-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 Lander מדגים איך להציג את התוצאות שהוחזרו מהמשימה. פרטים נוספים זמינים בכיתה OverlayView
.