งานตัวจดจำท่าทางด้วยมือของ MediaPipe ช่วยให้คุณจดจำท่าทางด้วยมือแบบเรียลไทม์ รวมถึงแสดงผลลัพธ์ท่าทางด้วยมือที่จดจำและจุดสังเกตของมือที่ตรวจพบ วิธีการเหล่านี้แสดงวิธีใช้โปรแกรมจดจำท่าทางร่วมกับแอป Android ตัวอย่างโค้ดที่อธิบายในวิธีการเหล่านี้มีอยู่ใน GitHub
คุณสามารถดูการทํางานของงานนี้ได้โดยดูเดโมบนเว็บ ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ รูปแบบ และตัวเลือกการกําหนดค่าของงานนี้ได้ที่ภาพรวม
ตัวอย่างโค้ด
โค้ดตัวอย่างของ MediaPipe Tasks คือการใช้งานแอปโปรแกรมจดจำท่าทางสัมผัสสำหรับ Android ที่เรียบง่าย ตัวอย่างนี้ใช้กล้องในอุปกรณ์ Android จริงเพื่อตรวจจับท่าทางมืออย่างต่อเนื่อง รวมถึงใช้รูปภาพและวิดีโอจากแกลเลอรีของอุปกรณ์เพื่อตรวจจับท่าทางแบบคงที่ได้ด้วย
คุณสามารถใช้แอปนี้เป็นจุดเริ่มต้นสําหรับแอป Android ของคุณเอง หรือใช้อ้างอิงเมื่อแก้ไขแอปที่มีอยู่ โค้ดตัวอย่าง Gesture Recognizer โฮสต์อยู่ใน GitHub
ดาวน์โหลดรหัส
วิธีการต่อไปนี้แสดงวิธีสร้างสำเนาโค้ดตัวอย่างในเครื่องโดยใช้เครื่องมือบรรทัดคำสั่ง git
วิธีดาวน์โหลดโค้ดตัวอย่าง
- โคลนที่เก็บ Git โดยใช้คําสั่งต่อไปนี้
git clone https://github.com/google-ai-edge/mediapipe-samples
- (ไม่บังคับ) กำหนดค่าอินสแตนซ์ git ให้ใช้การตรวจสอบแบบเบาเพื่อมีเฉพาะไฟล์สำหรับแอปตัวอย่างโปรแกรมจดจำท่าทางเท่านั้น โดยทำดังนี้
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/gesture_recognizer/android
หลังจากสร้างโค้ดตัวอย่างเวอร์ชันในเครื่องแล้ว คุณสามารถนําเข้าโปรเจ็กต์ไปยัง Android Studio และเรียกใช้แอปได้ ดูวิธีการได้ที่คู่มือการตั้งค่าสําหรับ Android
คอมโพเนนต์หลัก
ไฟล์ต่อไปนี้มีโค้ดสําคัญสําหรับแอปพลิเคชันตัวอย่างการจดจําท่าทางมือนี้
- GestureRecognizerHelper.kt - เริ่มต้นโปรแกรมรู้จำท่าทางสัมผัส รวมถึงจัดการโมเดลและการเลือกตัวแทน
- MainActivity.kt - ใช้แอปพลิเคชัน ซึ่งรวมถึงการเรียกใช้
GestureRecognizerHelper
และGestureRecognizerResultsAdapter
- GestureRecognizerResultsAdapter.kt - จัดการและจัดรูปแบบผลลัพธ์
ตั้งค่า
ส่วนนี้จะอธิบายขั้นตอนสำคัญในการตั้งค่าสภาพแวดล้อมการพัฒนาและโปรเจ็กต์โค้ดเพื่อใช้ Gesture Recognizer โดยเฉพาะ ดูข้อมูลทั่วไปเกี่ยวกับการตั้งค่าสภาพแวดล้อมการพัฒนาเพื่อใช้งาน MediaPipe รวมถึงข้อกำหนดเวอร์ชันแพลตฟอร์มได้ที่คู่มือการตั้งค่าสำหรับ Android
การอ้างอิง
งาน Gesture Recognizer ใช้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
ในโค้ดตัวอย่าง ระบบจะกำหนดโมเดลไว้ในไฟล์ GestureRecognizerHelper.kt
ดังนี้
baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)
สร้างงาน
งาน MediaPipe Gesture Recognizer ใช้ฟังก์ชัน createFromOptions()
เพื่อตั้งค่างาน ฟังก์ชัน createFromOptions()
ยอมรับค่าสำหรับตัวเลือกการกําหนดค่า ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือกการกําหนดค่าได้ที่ตัวเลือกการกําหนดค่า
ตัวจดจำท่าทางสัมผัสรองรับข้อมูลอินพุต 3 ประเภท ได้แก่ ภาพนิ่ง ไฟล์วิดีโอ และสตรีมวิดีโอสด คุณต้องระบุโหมดการทํางานที่สอดคล้องกับประเภทข้อมูลอินพุตเมื่อสร้างงาน เลือกแท็บที่สอดคล้องกับประเภทข้อมูลอินพุตเพื่อดูวิธีสร้างงานและเรียกใช้การอนุมาน
รูปภาพ
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = GestureRecognizer.GestureRecognizerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setRunningMode(RunningMode.IMAGE) val options = optionsBuilder.build() gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
วิดีโอ
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = GestureRecognizer.GestureRecognizerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setRunningMode(RunningMode.VIDEO) val options = optionsBuilder.build() gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
ไลฟ์สด
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(MP_RECOGNIZER_TASK) val baseOptions = baseOptionBuilder.build() val optionsBuilder = GestureRecognizer.GestureRecognizerOptions.builder() .setBaseOptions(baseOptions) .setMinHandDetectionConfidence(minHandDetectionConfidence) .setMinTrackingConfidence(minHandTrackingConfidence) .setMinHandPresenceConfidence(minHandPresenceConfidence) .setResultListener(this::returnLivestreamResult) .setErrorListener(this::returnLivestreamError) .setRunningMode(RunningMode.LIVE_STREAM) val options = optionsBuilder.build() gestureRecognizer = GestureRecognizer.createFromOptions(context, options)
การใช้โค้ดตัวอย่างโปรแกรมจดจำท่าทางสัมผัสช่วยให้ผู้ใช้สลับระหว่างโหมดการประมวลผลได้ แนวทางนี้ทําให้โค้ดการสร้างงานซับซ้อนขึ้นและอาจไม่เหมาะกับกรณีการใช้งานของคุณ คุณจะเห็นโค้ดนี้ในไฟล์ GestureRecognizerHelper.kt
ของฟังก์ชัน setupGestureRecognizer()
ตัวเลือกการกำหนดค่า
งานนี้มีตัวเลือกการกำหนดค่าต่อไปนี้สำหรับแอป Android
ชื่อตัวเลือก | คำอธิบาย | ช่วงของค่า | ค่าเริ่มต้น | |
---|---|---|---|---|
runningMode |
ตั้งค่าโหมดการทํางานสําหรับงาน โดยโหมดมี 3 แบบ ดังนี้ รูปภาพ: โหมดสำหรับอินพุตรูปภาพเดียว วิดีโอ: โหมดสำหรับเฟรมที่ถอดรหัสของวิดีโอ LIVE_STREAM: โหมดสตรีมแบบสดของข้อมูลอินพุต เช่น จากกล้อง ในโหมดนี้ คุณต้องเรียกใช้ resultListener เพื่อตั้งค่า Listener เพื่อรับผลลัพธ์แบบไม่พร้อมกัน |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
|
numHands |
GestureRecognizer ตรวจจับจำนวนมือได้สูงสุด
|
Any integer > 0 |
1 |
|
minHandDetectionConfidence |
คะแนนความน่าเชื่อถือขั้นต่ำที่การตรวจจับมือจะถือว่าประสบความสำเร็จในโมเดลการตรวจจับฝ่ามือ | 0.0 - 1.0 |
0.5 |
|
minHandPresenceConfidence |
คะแนนความเชื่อมั่นขั้นต่ำของคะแนนการมีอยู่ของมือในโมเดลการตรวจหาจุดสังเกตของมือ ในโหมดวิดีโอและโหมดสตรีมแบบสดของตัวจดจำท่าทาง หากคะแนนความเชื่อมั่นของมือที่ปรากฏจากโมเดลจุดสังเกตของมือต่ำกว่าเกณฑ์นี้ ระบบจะเรียกใช้โมเดลการตรวจจับฝ่ามือ หรือจะใช้อัลกอริทึมการติดตามมือแบบเบาเพื่อระบุตำแหน่งของมือเพื่อการตรวจหาจุดสังเกตในภายหลัง | 0.0 - 1.0 |
0.5 |
|
minTrackingConfidence |
คะแนนความเชื่อมั่นขั้นต่ำสำหรับการติดตามมือที่ถือว่าสำเร็จ นี่คือเกณฑ์ IoU ของขอบเขตระหว่างมือในเฟรมปัจจุบันกับเฟรมสุดท้าย ในโหมดวิดีโอและโหมดสตรีมของโปรแกรมจดจำท่าทางสัมผัส หากการติดตามไม่สำเร็จ โปรแกรมจดจำท่าทางสัมผัสจะเรียกให้ระบบตรวจจับมือ มิฉะนั้น ระบบจะข้ามการตรวจจับมือ | 0.0 - 1.0 |
0.5 |
|
cannedGesturesClassifierOptions |
ตัวเลือกในการกําหนดค่าลักษณะการทํางานของตัวแยกประเภทท่าทางสัมผัสที่บันทึกไว้ ท่าทางสัมผัสสำเร็จรูปคือ ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"] |
|
|
|
customGesturesClassifierOptions |
ตัวเลือกในการกําหนดค่าลักษณะการทํางานของตัวแยกประเภทท่าทางสัมผัสที่กําหนดเอง |
|
|
|
resultListener |
ตั้งค่าตัวรับผลลัพธ์ให้รับผลการจัดประเภทแบบไม่พร้อมกันเมื่อโปรแกรมจดจำท่าทางอยู่ในโหมดสตรีมแบบสด
ใช้ได้เมื่อตั้งค่าโหมดการทํางานเป็น LIVE_STREAM เท่านั้น |
ResultListener |
ไม่มี | ไม่มี |
errorListener |
ตั้งค่าโปรแกรมรับฟังข้อผิดพลาด (ไม่บังคับ) | ErrorListener |
ไม่มี | ไม่มี |
เตรียมข้อมูล
ตัวจดจำท่าทางทำงานร่วมกับรูปภาพ ไฟล์วิดีโอ และวิดีโอสตรีมแบบสดได้ งานจะจัดการการประมวลผลข้อมูลอินพุตก่อนการประมวลผล ซึ่งรวมถึงการปรับขนาด การหมุน และการปรับค่าให้เป็นไปตามมาตรฐาน
โค้ดต่อไปนี้แสดงวิธีส่งต่อข้อมูลเพื่อประมวลผล ตัวอย่างเหล่านี้มีรายละเอียดเกี่ยวกับวิธีจัดการข้อมูลจากรูปภาพ ไฟล์วิดีโอ และสตรีมวิดีโอสด
รูปภาพ
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()
ในโค้ดตัวอย่าง Gesture Recognizer ระบบจะจัดการการเตรียมข้อมูลในไฟล์ GestureRecognizerHelper.kt
เรียกใช้งาน
ตัวจดจำท่าทางสัมผัสใช้ฟังก์ชัน recognize
, recognizeForVideo
และ recognizeAsync
เพื่อทริกเกอร์การอนุมาน สําหรับการจดจําท่าทางสัมผัส ขั้นตอนนี้เกี่ยวข้องกับการประมวลผลข้อมูลอินพุตเบื้องต้น การตรวจจับมือในรูปภาพ การตรวจหาจุดสังเกตของมือ และการจดจําท่าทางสัมผัสของมือจากจุดสังเกต
โค้ดต่อไปนี้แสดงวิธีดำเนินการประมวลผลด้วยโมเดลงาน ตัวอย่างเหล่านี้มีรายละเอียดเกี่ยวกับวิธีจัดการข้อมูลจากรูปภาพ ไฟล์วิดีโอ และวิดีโอสตรีมแบบสด
รูปภาพ
val result = gestureRecognizer?.recognize(mpImage)
วิดีโอ
val timestampMs = i * inferenceIntervalMs gestureRecognizer?.recognizeForVideo(mpImage, timestampMs) ?.let { recognizerResult -> resultList.add(recognizerResult) }
ไลฟ์สด
val mpImage = BitmapImageBuilder(rotatedBitmap).build() val frameTime = SystemClock.uptimeMillis() gestureRecognizer?.recognizeAsync(mpImage, frameTime)
โปรดทราบดังต่อไปนี้
- เมื่อทำงานในโหมดวิดีโอหรือโหมดสตรีมแบบสด คุณต้องระบุการประทับเวลาของเฟรมอินพุตให้กับงานตัวจดจำท่าทางด้วย
- เมื่อทำงานในโหมดรูปภาพหรือวิดีโอ งานโปรแกรมจดจำท่าทางสัมผัสจะบล็อกเธรดปัจจุบันจนกว่าจะประมวลผลรูปภาพหรือเฟรมอินพุตเสร็จ ดำเนินการประมวลผลในเธรดแบ็กกราวด์เพื่อหลีกเลี่ยงการบล็อกอินเทอร์เฟซผู้ใช้
- เมื่อทำงานในโหมดสตรีมแบบสด งานตัวจดจำท่าทางสัมผัสจะไม่บล็อกเธรดปัจจุบัน แต่จะแสดงผลทันที โดยจะเรียกใช้โปรแกรมรับฟังผลลัพธ์พร้อมผลการตรวจหาทุกครั้งที่ประมวลผลเฟรมอินพุตเสร็จแล้ว หากมีการเรียกใช้ฟังก์ชันการจดจำเมื่องานตัวจดจำท่าทางมือไม่ว่างประมวลผลเฟรมอื่น งานจะละเว้นเฟรมอินพุตใหม่
ในโค้ดตัวอย่าง Gesture Recognizer จะมีการกําหนดฟังก์ชัน recognize
, recognizeForVideo
และ recognizeAsync
ในไฟล์ GestureRecognizerHelper.kt
จัดการและแสดงผลลัพธ์
ตัวจดจำท่าทางสัมผัสจะสร้างออบเจ็กต์ผลลัพธ์การตรวจจับท่าทางสัมผัสสําหรับการเรียกใช้การตรวจจับแต่ละครั้ง ออบเจ็กต์ผลลัพธ์ประกอบด้วยจุดสังเกตของมือในพิกัดรูปภาพ, จุดสังเกตของมือในพิกัดโลก, ลักษณะการจับถือ(มือซ้าย/ขวา) และหมวดหมู่ท่าทางมือของมือที่ตรวจพบ
ต่อไปนี้เป็นตัวอย่างข้อมูลเอาต์พุตจากงานนี้
GestureRecognizerResult
ที่ได้จะมีคอมโพเนนต์ 4 รายการ และแต่ละคอมโพเนนต์จะเป็นอาร์เรย์ โดยแต่ละองค์ประกอบจะมีผลลัพธ์ที่ตรวจพบจากมือที่ตรวจพบ 1 ข้าง
ความถนัดของมือ
ลักษณะการจับถือแสดงว่ามือที่ตรวจพบเป็นมือซ้ายหรือมือขวา
ท่าทางสัมผัส
หมวดหมู่ท่าทางสัมผัสที่รู้จักของมือที่ตรวจพบ
จุดสังเกต
มีจุดสังเกตบนมือ 21 จุด โดยแต่ละจุดประกอบด้วยพิกัด
x
,y
และz
ระบบจะปรับพิกัดx
และy
เป็น [0.0, 1.0] ตามความกว้างและความสูงของรูปภาพตามลำดับ พิกัดz
แสดงถึงระดับความลึกของจุดสังเกต โดยที่ระดับความลึกที่ข้อมือคือจุดเริ่มต้น ยิ่งค่านี้เล็ก สถานที่สำคัญก็จะยิ่งอยู่ใกล้กับกล้อง ขนาดของz
ใช้มาตราส่วนเดียวกับx
โดยประมาณสถานที่สำคัญของโลก
นอกจากนี้ สถานที่สำคัญ 21 แห่งบนมือจะแสดงเป็นพิกัดโลกด้วย จุดสังเกตแต่ละจุดประกอบด้วย
x
,y
และz
ซึ่งแสดงพิกัด 3 มิติในชีวิตจริงเป็นเมตร โดยจุดเริ่มต้นอยู่ที่จุดศูนย์กลางเชิงเรขาคณิตของมือ
GestureRecognizerResult:
Handedness:
Categories #0:
index : 0
score : 0.98396
categoryName : Left
Gestures:
Categories #0:
score : 0.76893
categoryName : Thumb_Up
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)
รูปภาพต่อไปนี้แสดงการแสดงภาพผลลัพธ์ของงาน
ในโค้ดตัวอย่าง Gesture Recognizer คลาส GestureRecognizerResultsAdapter
ในไฟล์ GestureRecognizerResultsAdapter.kt
จะจัดการผลลัพธ์