Dengan ML Kit Pose Detection API, Anda dapat memperoleh interpretasi yang bermakna dari sebuah pose dengan memeriksa posisi relatif dari berbagai bagian tubuh. Halaman ini menunjukkan beberapa contoh.
Klasifikasi pose dan penghitungan pengulangan dengan algoritma k-NN
Salah satu penerapan deteksi pose yang paling umum adalah pelacakan kebugaran. Membuat pengklasifikasi pose yang mengenali pose kebugaran tertentu dan menghitung pengulangan dapat menjadi pekerjaan yang menantang bagi developer.
Di bagian ini, kami menjelaskan cara kami membuat pengklasifikasi pose kustom menggunakan MediaPipe Colab, dan mendemonstrasikan pengklasifikasi yang berfungsi di aplikasi contoh ML Kit kami.
Jika Anda belum terbiasa dengan Google Colaboratory, lihat panduan pengantar.
Untuk mengenali pose, kami menggunakan algoritma k-nearestNeighbors (k-NN) karena sederhana dan mudah dimulai. Algoritma menentukan class objek berdasarkan sampel terdekat dalam set pelatihan.
Ikuti langkah-langkah berikut untuk membuat dan melatih pengenal:
1. Mengumpulkan contoh gambar
Kami mengumpulkan contoh gambar latihan target dari berbagai sumber. Kami memilih beberapa ratus gambar untuk setiap latihan, seperti posisi "atas" dan "bawah" untuk push-up. Penting untuk mengumpulkan sampel yang mencakup berbagai sudut kamera, kondisi lingkungan, bentuk tubuh, dan variasi olahraga.
2. Menjalankan deteksi pose pada gambar contoh
Ini menghasilkan serangkaian penanda pose yang akan digunakan untuk pelatihan. Kami tidak tertarik dengan deteksi pose itu sendiri, karena kami akan melatih model kami sendiri di langkah berikutnya.
Algoritma k-NN yang dipilih untuk klasifikasi pose kustom memerlukan representasi vektor fitur untuk setiap sampel, dan metrik untuk menghitung jarak antara dua vektor guna menemukan target yang paling dekat dengan sampel pose. Ini berarti kita harus mengonversi penanda pose yang baru saja diperoleh.
Untuk mengonversi tempat terkenal pose menjadi vektor fitur, kami menggunakan jarak berpasangan antara daftar sambungan pose yang telah ditentukan, seperti jarak antara pergelangan tangan dan bahu, pergelangan kaki dan pinggul, serta pergelangan tangan kiri dan kanan. Karena skala gambar dapat bervariasi, kami menormalisasi pose agar memiliki ukuran batang tubuh dan orientasi batang tubuh vertikal yang sama sebelum mengonversi tempat terkenal.
3. Melatih model dan menghitung pengulangan
Kami menggunakan MediaPipe Colab untuk mengakses kode pengklasifikasi dan melatih model.
Untuk menghitung pengulangan, kami menggunakan algoritma Colab lain untuk memantau batas probabilitas posisi pose target. Contoh:
- Ketika probabilitas class pose "bawah" melewati batas tertentu untuk pertama kalinya, algoritme akan menandai bahwa class pose "bawah" dimasukkan.
- Saat probabilitas turun di bawah nilai minimum, algoritme akan menandai bahwa class pose "bawah" telah keluar dan meningkatkan penghitung.
4. Berintegrasi dengan aplikasi panduan memulai ML Kit
Colab di atas menghasilkan file CSV yang dapat Anda isi dengan semua contoh pose. Di bagian ini, Anda akan mempelajari cara mengintegrasikan file CSV dengan aplikasi panduan memulai Android ML Kit untuk melihat klasifikasi pose kustom secara real time.
Coba klasifikasi pose dengan contoh yang dipaketkan di aplikasi panduan memulai
- Dapatkan project aplikasi panduan memulai Android ML Kit dari GitHub dan pastikan aplikasi tersebut dibangun dan berjalan dengan baik.
- Buka
LivePreviewActivity
dan aktifkan Deteksi PoseRun classification
dari halaman Setelan. Sekarang Anda seharusnya sudah bisa mengklasifikasikan {i>pushup<i} dan {i>squat<i}.
Tambahkan CSV Anda sendiri
- Tambahkan file CSV ke folder aset aplikasi.
- Di PoseClassifierProcessor, perbarui variabel
POSE_SAMPLES_FILE
danPOSE_CLASSES
agar sesuai dengan file CSV dan contoh pose. - Bangun dan jalankan aplikasi.
Perhatikan bahwa klasifikasi mungkin tidak berfungsi dengan baik jika sampel tidak cukup. Umumnya, Anda memerlukan sekitar 100 sampel per class pose.
Untuk mempelajari lebih lanjut dan mencobanya sendiri, lihat MediaPipe Colab dan panduan klasifikasi MediaPipe.
Mengenali gestur sederhana dengan menghitung jarak penanda
Jika dua atau beberapa tempat terkenal saling berdekatan, keduanya dapat digunakan untuk mengenali gestur. Misalnya, jika penanda untuk satu atau beberapa jari di tangan dekat dengan penanda untuk hidung, Anda dapat menyimpulkan bahwa pengguna kemungkinan besar menyentuh wajahnya.
Mengenali pose yoga dengan heuristik sudut
Anda dapat mengidentifikasi pose yoga dengan menghitung sudut berbagai sendi. Misalnya, Gambar 2 di bawah menunjukkan pose yoga Warrior II. Perkiraan sudut yang mengidentifikasi pose ini ditulis dalam:
Pose ini dapat dijelaskan sebagai kombinasi perkiraan sudut bagian tubuh berikut:
- sudut 90 derajat di kedua bahu
- 180 derajat di kedua siku
- Sudut 90 derajat di kaki depan dan pinggang
- Sudut 180 derajat di bagian belakang lutut
- Sudut 135 derajat di bagian pinggang
Anda dapat menggunakan penanda pose untuk menghitung sudut-sudut ini. Misalnya, sudut di kaki depan kanan dan pinggang adalah sudut antara garis dari bahu kanan ke pinggul kanan, dan garis dari pinggul kanan ke lutut kanan.
Setelah menghitung semua sudut yang diperlukan untuk mengidentifikasi pose, Anda dapat memeriksa apakah ada kecocokan, dan dalam hal ini Anda telah mengenali pose tersebut.
Cuplikan kode di bawah menunjukkan cara menggunakan koordinat X dan Y untuk menghitung sudut antara dua bagian tubuh. Pendekatan klasifikasi ini memiliki beberapa batasan. Dengan hanya memeriksa X dan Y, sudut yang dihitung bervariasi sesuai dengan sudut antara subjek dan kamera. Anda akan mendapatkan hasil terbaik dengan gambar langsung yang lurus ke depan. Anda juga dapat mencoba memperluas algoritme ini dengan menggunakan koordinat Z dan melihat apakah performanya lebih baik untuk kasus penggunaan Anda.
Menghitung sudut tempat terkenal di Android
Metode berikut menghitung sudut antara tiga landmark. Hal ini memastikan sudut yang ditampilkan antara 0 dan 180 derajat.
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; }
Berikut cara menghitung sudut di pinggul kanan:
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));
Menghitung sudut tempat terkenal di iOS
Metode berikut menghitung sudut antara tiga landmark. Hal ini memastikan sudut yang ditampilkan antara 0 dan 180 derajat.
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; }
Berikut cara menghitung sudut di pinggul kanan:
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]];