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