ML Kit Pose Detection API ช่วยให้คุณรับการตีความท่าทางที่มีความหมายได้ด้วยการตรวจสอบตำแหน่งสัมพัทธ์ของส่วนต่างๆ ของร่างกาย หน้านี้จะแสดงให้เห็นตัวอย่างบางส่วน
การแยกประเภทท่าทางและการนับการทำซ้ำด้วยอัลกอริทึม k-NN
หนึ่งในแอปพลิเคชันที่พบบ่อยที่สุดในการตรวจจับท่าทางคือการติดตามการออกกำลังกาย การสร้างตัวแยกประเภทที่รู้จำท่าออกกำลังและนับจำนวนการทำซ้ำอาจเป็นสิ่งที่ท้าทายสำหรับนักพัฒนาซอฟต์แวร์
ในส่วนนี้ เราจะอธิบายถึงวิธีที่เราสร้างตัวแยกประเภทท่าทางที่กำหนดเองโดยใช้ MediaPipe Colab และสาธิตการใช้ตัวแยกประเภทที่ใช้งานได้ในแอปตัวอย่าง ML Kit
หากไม่คุ้นเคยกับ Google Colaboratory โปรดดูคู่มือแนะนำ
ในการรู้จำท่าทาง เราใช้อัลกอริทึมเพื่อนบ้านที่อยู่ใกล้ที่สุด (k-NN) เพราะเรียบง่ายและเริ่มต้นได้ง่าย อัลกอริทึมจะกำหนดคลาสของออบเจ็กต์ตามตัวอย่างที่ใกล้เคียงที่สุดในชุดการฝึก
ทำตามขั้นตอนต่อไปนี้เพื่อสร้างและฝึกโปรแกรมรู้จำ
1. รวบรวมตัวอย่างรูปภาพ
เรารวบรวมตัวอย่างรูปภาพของแบบฝึกหัดเป้าหมายจากแหล่งที่มาต่างๆ เราจะเลือกรูปภาพ 200-300 รูปสำหรับการออกกำลังกายแต่ละครั้ง เช่น ท่า "ขึ้น" และ "ลง" สำหรับการวิดพื้น คุณต้องรวบรวมตัวอย่างที่ครอบคลุมมุมกล้อง สภาพสภาพแวดล้อม รูปร่าง และการออกกำลังกายรูปแบบต่างๆ
2. เรียกใช้การตรวจหาท่าทางในรูปภาพตัวอย่าง
ระบบจะสร้างชุดจุดสังเกตของท่าสำหรับฝึก เราไม่สนใจเกี่ยวกับการตรวจจับท่าทาง เนื่องจากเราจะฝึกโมเดลของเราเองในขั้นตอนถัดไป
อัลกอริทึม k-NN ที่เราเลือกสำหรับการแยกประเภทท่าทางที่กำหนดเองต้องใช้การแสดงเวกเตอร์ฟีเจอร์ของตัวอย่างแต่ละรายการและเมตริกในการคำนวณระยะห่างระหว่างเวกเตอร์ 2 เวกเตอร์เพื่อหาเป้าหมายที่ใกล้เคียงที่สุดกับตัวอย่างท่าทาง ซึ่งหมายความว่าเราต้องแปลงจุดสังเกตของท่าทางที่เพิ่งได้รับมา
ในการแปลงจุดสังเกตของท่าทางเป็นเวกเตอร์ของฟีเจอร์ เราใช้ระยะห่างแบบจับคู่ระหว่างรายการข้อต่อที่กำหนดไว้ล่วงหน้า เช่น ระยะห่างระหว่างข้อมือกับไหล่ ข้อเท้าและสะโพก และข้อมือซ้ายและขวา เนื่องจากขนาดรูปภาพอาจแตกต่างกันไป เราจึงปรับท่าทางให้มีขนาดลำตัวและแนวลำตัวแนวตั้งเท่ากันก่อนที่จะแปลงจุดสังเกต
3. ฝึกโมเดลและนับการทำซ้ำ
เราใช้ MediaPipe Colab เพื่อเข้าถึงโค้ดสำหรับตัวแยกประเภทและฝึกโมเดล
ในการนับจำนวนครั้งที่ทำซ้ำ เราใช้อัลกอริทึม Colab อื่นในการตรวจสอบเกณฑ์ความน่าจะเป็นของตำแหน่งท่าทาง เช่น
- เมื่อความน่าจะเป็นของคลาสท่าทาง "ลง" ผ่านเกณฑ์ที่ระบุเป็นครั้งแรก อัลกอริทึมจะทำเครื่องหมายว่ามีการป้อนคลาสท่าทาง "ลง"
- เมื่อความน่าจะเป็นลดลงต่ำกว่าเกณฑ์ อัลกอริทึมจะทำเครื่องหมายการออกจากคลาสท่าทาง "ลง" แล้วเพิ่มตัวนับ
4. ผสานรวมกับแอปเริ่มต้นใช้งานอย่างรวดเร็วของ ML Kit
Colab ด้านบนจะสร้างไฟล์ CSV ที่คุณนำไปเติมข้อมูลด้วยตัวอย่างท่าทางทั้งหมดของคุณได้ ในส่วนนี้ คุณจะได้เรียนรู้วิธีผสานรวมไฟล์ CSV กับแอปเริ่มใช้งาน Android ของ ML Kit อย่างรวดเร็วเพื่อดูการจัดประเภทท่าทางที่กำหนดเองแบบเรียลไทม์
ลองจัดประเภทท่าทางด้วยตัวอย่างที่รวมอยู่ในแอป Quickstart
- รับโปรเจ็กต์แอปสำหรับการเริ่มต้นใช้งาน Android อย่างรวดเร็ว จาก GitHub และตรวจสอบว่าสร้างและใช้งานได้ดี
- ไปที่
LivePreviewActivity
แล้วเปิดใช้การตรวจจับท่าทางRun classification
จากหน้า "การตั้งค่า" ตอนนี้คุณควรจะจัดประเภทการวิดพื้นและสควอทได้แล้ว
เพิ่ม CSV ของคุณเอง
- เพิ่มไฟล์ CSV ลงในโฟลเดอร์ชิ้นงานของแอป
- ใน PoseClassifierProcessor ให้อัปเดตตัวแปร
POSE_SAMPLES_FILE
และPOSE_CLASSES
ให้ตรงกับไฟล์ CSV และวางตัวอย่าง - สร้างและเรียกใช้แอป
โปรดทราบว่าการจัดประเภทอาจทำงานได้ไม่ดีหากมีตัวอย่างไม่เพียงพอ โดยทั่วไป คุณต้องการประมาณ 100 ตัวอย่างต่อคลาสท่าทาง
ดูข้อมูลเพิ่มเติมและลองใช้งานด้วยตัวเองได้ใน MediaPipe Colab และคู่มือการแยกประเภท MediaPipe
การจดจำท่าทางสัมผัสง่ายๆ โดยการคำนวณระยะห่างของจุดสังเกต
เมื่อจุดสังเกต 2 รายการขึ้นไปอยู่ใกล้กัน สามารถใช้เพื่อจดจำท่าทางสัมผัสได้ เช่น เมื่อจุดสังเกตสำหรับนิ้วมือ 1 นิ้วหรือมากกว่าอยู่ใกล้กับจุดสังเกตสำหรับจมูก คุณจะอนุมานได้ว่าผู้ใช้มีแนวโน้มที่จะสัมผัสใบหน้าของตนมากที่สุด
การจดจำท่าโยคะที่มีการเรียนรู้มุม
คุณสามารถระบุท่าโยคะได้โดยการคำนวณมุมของข้อต่อต่างๆ ตัวอย่างเช่น รูปที่ 2 ด้านล่างแสดงท่าโยคะ Warrior II มุมโดยประมาณที่ระบุท่าทางนี้เขียนว่า
ท่าทางนี้อาจอธิบายได้จากการรวมมุมส่วนต่างๆ ของร่างกายโดยประมาณดังต่อไปนี้
- ทำมุม 90 องศาที่ไหล่ทั้ง 2 ข้าง
- 180 องศาที่ข้อศอกทั้ง 2 ข้าง
- ทำมุม 90 องศาที่ขาหน้าและเอว
- ทำมุม 180 องศาที่เข่าด้านหลัง
- ทำมุม 135 องศาที่เอว
คุณใช้จุดสังเกตของท่าทางเพื่อคำนวณมุมเหล่านี้ได้ ตัวอย่างเช่น มุมที่ขาหน้าและเอวด้านขวาคือมุมระหว่างเส้นจากไหล่ด้านขวาไปยังสะโพกด้านขวา และเส้นจากสะโพกด้านขวาไปยังเข่าด้านขวา
เมื่อคุณคำนวณมุมทั้งหมดที่ต้องใช้ในการระบุท่าทางแล้ว คุณก็ดูว่ามีภาพที่ตรงกันไหม ซึ่งในกรณีนี้คุณรู้ท่าโพสแล้ว
ข้อมูลโค้ดด้านล่างสาธิตวิธีใช้พิกัด X และ Y เพื่อคำนวณมุมระหว่างส่วนต่างๆ ของร่างกาย วิธีการแยกประเภทนี้ มีข้อจำกัดบางประการ ถ้าเลือกเฉพาะ X และ Y มุมที่คำนวณได้ จะแตกต่างกันไปตามมุมระหว่างวัตถุและกล้อง คุณจะได้ผลลัพธ์ที่ดีที่สุดเมื่อ เห็นภาพชัดเจนตรงไปตรงมา คุณยังสามารถลองขยายอัลกอริทึมนี้โดยใช้พิกัด Z และดูว่ามีประสิทธิภาพดีกว่าสำหรับกรณีการใช้งานของคุณไหม
คำนวณมุมของจุดสังเกตบน Android
เมธอดต่อไปนี้จะคำนวณมุมระหว่างจุดสังเกต 3 อย่าง เพื่อให้แน่ใจว่ามุมที่แสดงผลอยู่ระหว่าง 0 ถึง 180 องศา
Kotlin
fun getAngle(firstPoint: PoseLandmark, midPoint: PoseLandmark, lastPoint: PoseLandmark): Double { var result = Math.toDegrees(atan2(lastPoint.getPosition().y - midPoint.getPosition().y, lastPoint.getPosition().x - midPoint.getPosition().x) - atan2(firstPoint.getPosition().y - midPoint.getPosition().y, firstPoint.getPosition().x - midPoint.getPosition().x)) result = Math.abs(result) // Angle should never be negative if (result > 180) { result = 360.0 - result // Always get the acute representation of the angle } return result }
Java
static double getAngle(PoseLandmark firstPoint, PoseLandmark midPoint, PoseLandmark lastPoint) { double result = Math.toDegrees( atan2(lastPoint.getPosition().y - midPoint.getPosition().y, lastPoint.getPosition().x - midPoint.getPosition().x) - atan2(firstPoint.getPosition().y - midPoint.getPosition().y, firstPoint.getPosition().x - midPoint.getPosition().x)); result = Math.abs(result); // Angle should never be negative if (result > 180) { result = (360.0 - result); // Always get the acute representation of the angle } return result; }
วิธีคำนวณมุมด้านขวาสะโพกมีดังนี้
Kotlin
val rightHipAngle = getAngle( pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE))
Java
double rightHipAngle = getAngle( pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP), pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE));
คำนวณมุมของจุดสังเกตบน iOS
เมธอดต่อไปนี้จะคำนวณมุมระหว่างจุดสังเกต 3 อย่าง เพื่อให้แน่ใจว่ามุมที่แสดงผลอยู่ระหว่าง 0 ถึง 180 องศา
Swift
func angle( firstLandmark: PoseLandmark, midLandmark: PoseLandmark, lastLandmark: PoseLandmark ) -> CGFloat { let radians: CGFloat = atan2(lastLandmark.position.y - midLandmark.position.y, lastLandmark.position.x - midLandmark.position.x) - atan2(firstLandmark.position.y - midLandmark.position.y, firstLandmark.position.x - midLandmark.position.x) var degrees = radians * 180.0 / .pi degrees = abs(degrees) // Angle should never be negative if degrees > 180.0 { degrees = 360.0 - degrees // Always get the acute representation of the angle } return degrees }
Objective-C
(CGFloat)angleFromFirstLandmark:(MLKPoseLandmark *)firstLandmark midLandmark:(MLKPoseLandmark *)midLandmark lastLandmark:(MLKPoseLandmark *)lastLandmark { CGFloat radians = atan2(lastLandmark.position.y - midLandmark.position.y, lastLandmark.position.x - midLandmark.position.x) - atan2(firstLandmark.position.y - midLandmark.position.y, firstLandmark.position.x - midLandmark.position.x); CGFloat degrees = radians * 180.0 / M_PI; degrees = fabs(degrees); // Angle should never be negative if (degrees > 180.0) { degrees = 360.0 - degrees; // Always get the acute representation of the angle } return degrees; }
วิธีคำนวณมุมด้านขวาสะโพกมีดังนี้
Swift
let rightHipAngle = angle( firstLandmark: pose.landmark(ofType: .rightShoulder), midLandmark: pose.landmark(ofType: .rightHip), lastLandmark: pose.landmark(ofType: .rightKnee))
Objective-C
CGFloat rightHipAngle = [self angleFromFirstLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightShoulder] midLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightHip] lastLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightKnee]];