เมื่อใช้ ML Kit Pose Detection API คุณจะได้รับการตีความที่มีความหมาย ด้วยการตรวจสอบตำแหน่งสัมพัทธ์ของส่วนต่างๆ ของร่างกาย หน้านี้แสดงตัวอย่างบางส่วน
การจัดประเภทท่าทางและการนับซ้ำด้วยอัลกอริทึม k-NN
การใช้งานที่พบบ่อยที่สุดอย่างหนึ่งของการตรวจจับท่าทางคือการติดตามการออกกำลังกาย การสร้างตัวแยกประเภทท่าทางที่จดจำท่าทางและจำนวนการออกกำลังกายที่เจาะจง การทำซ้ำๆ อาจเป็นสิ่งที่ท้าทายสำหรับนักพัฒนาซอฟต์แวร์
ในส่วนนี้ เราจะอธิบายวิธีสร้างตัวแยกประเภทท่าทางที่กำหนดเองโดยใช้ MediaPipe Colab และสาธิตตัวแยกประเภทที่ใช้งานได้ในแอปตัวอย่าง ML Kit
หากคุณไม่คุ้นเคยกับ Google Colaboratory โปรดดูคู่มือแนะนำ
เราใช้อัลกอริทึม k-Nabor Nabors (k-NN) ในการจดจำท่าทางเพราะว่านั้นง่ายมาก และเริ่มต้นได้ง่าย อัลกอริทึมจะกำหนดคลาสของออบเจ็กต์ตามตัวอย่างที่ใกล้เคียงที่สุดในชุดการฝึก
ทำตามขั้นตอนต่อไปนี้เพื่อสร้างและฝึกโปรแกรมจดจำ
1. รวบรวมตัวอย่างรูปภาพ
เรารวบรวมตัวอย่างรูปภาพการออกกำลังกายเป้าหมายจากแหล่งที่มาต่างๆ พ เลือกรูปภาพสองสามร้อยภาพสำหรับการออกกำลังกายแต่ละครั้ง เช่น "ขึ้น" และ "ลง" ตำแหน่ง สำหรับการวิดพื้น คุณควรรวบรวมตัวอย่างที่ครอบคลุมมุมกล้อง สภาพสภาพแวดล้อม รูปร่าง และการออกกำลังกายที่หลากหลาย

2. เรียกใช้การตรวจจับท่าทางในรูปภาพตัวอย่าง
การดำเนินการนี้จะสร้างชุดจุดสังเกตของท่าทางที่ใช้สำหรับการฝึก เราไม่ได้สนใจการตรวจจับท่าทางเพียงอย่างเดียว เนื่องจากเราจะฝึกโมเดลของเราเองในขั้นตอนถัดไป
อัลกอริทึม k-NN ที่เราเลือกสำหรับการจัดประเภทท่าทางที่กำหนดเองจะต้องใช้ แสดงเวกเตอร์ของตัวอย่างแต่ละรายการและเมตริกที่จะคำนวณ ระยะทางระหว่างเวกเตอร์ 2 เวกเตอร์เพื่อหาเป้าหมายที่อยู่ใกล้กับตัวอย่างท่าทางมากที่สุด ซึ่งหมายความว่าเราต้องแปลงจุดสังเกตต่างๆ ที่เราเพิ่งได้มา
ในการแปลงจุดสังเกตของการโพสเป็นเวกเตอร์ของจุดสนใจ เราใช้ระยะทางแบบคู่ ระหว่างรายการของข้อต่อโพสที่กำหนดไว้ล่วงหน้า เช่น ระยะห่างระหว่างข้อมือกับ ไหล่ ข้อเท้าและสะโพก และข้อมือซ้ายและขวา เนื่องจากขนาดของรูปภาพอาจแตกต่างกันไป เราจึงปรับท่าทางให้มีขนาดลำตัวและการวางแนวลำตัวในแนวตั้งเหมือนกันก่อนที่จะแปลงจุดสังเกต
3. ฝึกโมเดลและนับการทำซ้ำ
เราใช้ MediaPipe Colab เพื่อเข้าถึงโค้ดสำหรับตัวแยกประเภทและ ฝึกโมเดล
ในการนับการเกิดซ้ำ เราใช้อัลกอริทึมของ Colab อีกตัวหนึ่งเพื่อตรวจสอบความน่าจะเป็น ของตำแหน่งเป้าหมาย เช่น
- เมื่อความน่าจะเป็นของการ "ลดลง" ทำให้คลาสผ่านเกณฑ์ที่กำหนดให้สำหรับ ในครั้งแรก อัลกอริทึมจะทำเครื่องหมาย "ลูกศรลง" มีการป้อนคลาสการโพส
- เมื่อความน่าจะเป็นลดลงต่ำกว่าเกณฑ์ อัลกอริทึมจะระบุว่าออกจากคลาสท่าทาง "ลง" แล้วและเพิ่มตัวนับ

4. ผสานรวมกับแอปเริ่มต้นใช้งาน ML Kit อย่างรวดเร็ว
Colab ด้านบนจะสร้างไฟล์ CSV ที่คุณป้อนข้อมูลท่าทางทั้งหมดได้ ตัวอย่าง ในหัวข้อนี้ คุณจะได้เรียนรู้วิธีผสานรวมไฟล์ CSV กับ แอปเริ่มต้นใช้งาน ML Kit สำหรับ Android อย่างรวดเร็วเพื่อดูการจัดประเภทท่าทางที่กำหนดเองแบบเรียลไทม์
ลองใช้การแยกประเภทท่าทางด้วยตัวอย่างที่รวมอยู่ในแอปเริ่มต้นใช้งานอย่างรวดเร็ว
- รับโปรเจ็กต์แอปการเริ่มต้นอย่างรวดเร็วสำหรับ Android ของ ML Kit จาก 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 องศา
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
}
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;
}
วิธีคำนวณมุมที่สะโพกขวามีดังนี้
val rightHipAngle = getAngle(
pose.getPoseLandmark(PoseLandmark.Type.RIGHT_SHOULDER),
pose.getPoseLandmark(PoseLandmark.Type.RIGHT_HIP),
pose.getPoseLandmark(PoseLandmark.Type.RIGHT_KNEE))
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 องศา
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
}
(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;
}
วิธีคำนวณมุมที่สะโพกขวามีดังนี้
let rightHipAngle = angle(
firstLandmark: pose.landmark(ofType: .rightShoulder),
midLandmark: pose.landmark(ofType: .rightHip),
lastLandmark: pose.landmark(ofType: .rightKnee))
CGFloat rightHipAngle =
[self angleFromFirstLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightShoulder]
midLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightHip]
lastLandmark:[pose landmarkOfType:MLKPoseLandmarkTypeRightKnee]];