งาน MediaPipe Pose Landinger จะช่วยให้คุณตรวจหาจุดสังเกตของร่างกายมนุษย์ในรูปภาพหรือวิดีโอได้ คุณสามารถใช้งานนี้เพื่อระบุตำแหน่งหลักของร่างกาย วิเคราะห์ท่าทาง และจัดหมวดหมู่การเคลื่อนไหว งานนี้ใช้โมเดลแมชชีนเลิร์นนิง (ML) ที่ใช้งานได้กับรูปภาพหรือวิดีโอรายการเดียว งานแสดงท่าทางร่างกายของจุดสังเกต ที่อยู่ในพิกัดรูปภาพและในพิกัดโลก 3 มิติ
ตัวอย่างโค้ดที่อธิบายในวิธีการเหล่านี้จะดูได้ใน GitHub ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ โมเดล และตัวเลือกการกำหนดค่าของงานนี้ได้ที่ภาพรวม
ตัวอย่างโค้ด
โค้ดตัวอย่างงาน MediaPipe Tasks เป็นการติดตั้งใช้งานแอป Pose Marker สำหรับ Android แบบง่ายๆ ตัวอย่างนี้ใช้กล้องบนอุปกรณ์ Android จริงเพื่อตรวจหาท่าทางในสตรีมวิดีโอแบบต่อเนื่อง แอปยังสามารถตรวจจับท่าทาง ในรูปภาพและวิดีโอจากแกลเลอรีของอุปกรณ์
คุณสามารถใช้แอปนี้เป็นจุดเริ่มต้นสำหรับแอป Android ของคุณเองหรือใช้อ้างอิงเมื่อแก้ไขแอปที่มีอยู่ โค้ดตัวอย่างของ Pose Marker นั้นโฮสต์อยู่ใน 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จุดสังเกตโดยเฉพาะ สำหรับข้อมูลทั่วไปเกี่ยวกับการตั้งค่าสภาพแวดล้อมการพัฒนาเพื่อใช้งาน MediaPipe รวมถึงข้อกำหนดเวอร์ชันแพลตฟอร์ม โปรดดูคู่มือการตั้งค่าสำหรับ Android
การอ้างอิง
งาน Pose Marker ใช้ไลบรารี com.google.mediapipe:tasks-vision
เพิ่มทรัพยากร Dependency นี้ไปยังไฟล์ build.gradle
ของแอป Android
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
รุ่น
งาน MediaPipe Pose Marker ต้องมีแพ็กเกจโมเดลที่ผ่านการฝึกแล้วซึ่งเข้ากันได้กับงานนี้ ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลที่ฝึกแล้วที่พร้อมใช้งานสำหรับจุดสังเกตของ Pose ได้ที่ภาพรวมงานส่วนโมเดล
เลือกและดาวน์โหลดโมเดล แล้วจัดเก็บไว้ในไดเรกทอรีโปรเจ็กต์ของคุณ ดังนี้
<dev-project-root>/src/main/assets
ระบุเส้นทางของโมเดลภายในพารามิเตอร์ ModelAssetPath
ในโค้ดตัวอย่าง โมเดลจะได้รับการกำหนดในไฟล์ PoseLandmarkerHelper.kt
ดังนี้
val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)
สร้างงาน
งาน MediaPipe Pose Marker จะใช้ฟังก์ชัน createFromOptions()
เพื่อตั้งค่างาน ฟังก์ชัน createFromOptions()
จะยอมรับค่าสำหรับตัวเลือกการกำหนดค่า ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการกำหนดค่าได้ที่ตัวเลือกการกำหนดค่า
Pose Landinger รองรับประเภทข้อมูลอินพุตต่อไปนี้ ซึ่งได้แก่ ภาพนิ่ง ไฟล์วิดีโอ และสตรีมวิดีโอสด คุณต้องระบุโหมดทำงานที่สอดคล้องกับประเภทข้อมูลอินพุตเมื่อสร้างงาน เลือกแท็บของประเภทข้อมูลอินพุตเพื่อดูวิธีสร้างงาน
รูปภาพ
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 Marker ช่วยให้ผู้ใช้เปลี่ยนโหมดการประมวลผลได้ วิธีนี้ทำให้โค้ดการสร้างงานซับซ้อนขึ้นและอาจไม่เหมาะกับกรณีการใช้งานของคุณ คุณดูโค้ดนี้ได้ในฟังก์ชัน setupPoseLandmarker()
ในไฟล์ PoseLandmarkerHelper.kt
ตัวเลือกการกำหนดค่า
งานมีตัวเลือกการกำหนดค่าต่อไปนี้สำหรับแอป Android
ชื่อตัวเลือก | คำอธิบาย | ช่วงของค่า | ค่าเริ่มต้น |
---|---|---|---|
runningMode |
ตั้งค่าโหมดการทำงาน มี 3 โหมดดังนี้ IMAGE: โหมดสำหรับการป้อนข้อมูลรูปภาพเดียว วิดีโอ: โหมดสำหรับเฟรมที่ถอดรหัสของวิดีโอ LIVE_Stream: โหมดสำหรับสตรีมแบบสดของข้อมูลอินพุต เช่น จากกล้อง ในโหมดนี้ ต้องมีการเรียกใช้ resultsListener เพื่อตั้งค่า Listener เพื่อรับผลลัพธ์แบบไม่พร้อมกัน |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
numposes |
จำนวนสูงสุดของท่าทางที่ตัวระบุตำแหน่ง จะตรวจจับได้ | 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 Marker อยู่ในโหมดสตรีมแบบสด
ใช้ได้เมื่อตั้งค่าโหมดการทำงานเป็น LIVE_STREAM เท่านั้น |
ResultListener |
N/A |
errorListener |
ตั้งค่า Listener ข้อผิดพลาดที่ไม่บังคับ | ErrorListener |
N/A |
เตรียมข้อมูล
วางจุดสังเกตที่ใช้ได้ทั้งกับรูปภาพ ไฟล์วิดีโอ และสตรีมวิดีโอสด งานนี้จะจัดการกับการประมวลผลอินพุตข้อมูลล่วงหน้า ซึ่งรวมถึงการปรับขนาด การหมุน และการปรับค่าให้เป็นมาตรฐาน
โค้ดต่อไปนี้แสดงวิธีส่งต่อข้อมูลเพื่อการประมวลผล ตัวอย่างเหล่านี้มีรายละเอียดเกี่ยวกับวิธีจัดการข้อมูลจากรูปภาพ ไฟล์วิดีโอ และสตรีมวิดีโอสด
รูปภาพ
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 Marker ระบบจะจัดการการเตรียมข้อมูลในไฟล์ PoseLandmarkerHelper.kt
เรียกใช้งาน
ใช้เมธอด poseLandmarker.detect...()
ที่เจาะจงสำหรับประเภทข้อมูลนั้น ทั้งนี้ขึ้นอยู่กับประเภทข้อมูลที่ใช้งานอยู่ ใช้ detect()
สำหรับรูปภาพแต่ละรูป ใช้ detectForVideo()
สำหรับเฟรมในไฟล์วิดีโอ และใช้ detectAsync()
สำหรับสตรีมวิดีโอ เมื่อตรวจหาสตรีมวิดีโอ ให้เรียกใช้การตรวจจับในเทรดแยกต่างหากเพื่อหลีกเลี่ยงการบล็อกชุดข้อความที่ผู้ใช้แทรกเข้ามา
ตัวอย่างโค้ดต่อไปนี้แสดงตัวอย่างง่ายๆ ของวิธีเรียกใช้จุดวางจุดสังเกตในโหมดข้อมูลต่างๆ เหล่านี้
รูปภาพ
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 Marker จะกลับมาทันทีและไม่บล็อกเทรดปัจจุบัน โดยจะเรียกใช้ Listener ผลลัพธ์พร้อมผลการตรวจจับทุกครั้งที่ประมวลผลเฟรมอินพุตเสร็จ
ในโค้ดตัวอย่าง Pose Marker ได้มีการระบุฟังก์ชัน detect
, detectForVideo
และ detectAsync
ไว้ในไฟล์ PoseLandmarkerHelper.kt
แฮนเดิลและแสดงผลลัพธ์
Pose Landinger จะแสดงผลออบเจ็กต์ 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
: พิกัด 3 มิติในชีวิตจริงในหน่วยเมตร โดยมีจุดกึ่งกลางของสะโพกเป็นต้นทางvisibility
: แนวโน้มที่จุดสังเกตจะปรากฏให้เห็นภายในรูปภาพ
รูปภาพต่อไปนี้แสดงภาพเอาต์พุตของงาน
มาสก์การแบ่งกลุ่ม (ไม่บังคับ) แสดงถึงความเป็นไปได้ที่พิกเซลแต่ละพิกเซลจะเป็นของบุคคลที่ตรวจพบ รูปภาพต่อไปนี้คือมาสก์การแบ่งกลุ่มของเอาต์พุตงาน
โค้ดตัวอย่าง Pose Marker จะสาธิตวิธีแสดงผลลัพธ์ที่ได้จากงาน ดูรายละเอียดเพิ่มเติมได้จากคลาส OverlayView