Opsi klasifikasi pose

Dengan ML Kit Pose Detection API, Anda dapat mendapatkan penafsiran 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 paling umum dari deteksi pose adalah pelacakan kebugaran. Membuat pengklasifikasi pose yang mengenali pose dan jumlah kebugaran tertentu pengulangan bisa menjadi pencapaian yang menantang bagi developer.

Di bagian ini kami menjelaskan cara kami membuat pose khusus pengklasifikasi menggunakan MediaPipe Colab, dan mendemonstrasikan pengklasifikasi yang berfungsi di aplikasi contoh ML Kit.

Jika Anda belum terbiasa dengan Google Colaboratory, buka panduan pengantar.

Untuk mengenali pose, kita menggunakan algoritma {i>k-nearest keberlanjutan <i}(k-NN) karena dan mudah untuk memulainya. 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 sampel gambar latihan target dari berbagai sumber. Rab memilih beberapa ratus gambar untuk setiap latihan, seperti "naik" dan "down" posisi untuk push-up. Penting untuk mengumpulkan sampel yang mencakup kamera yang berbeda sudut, kondisi lingkungan, bentuk tubuh, dan variasi latihan.

Gambar 1. Posisi pose pushup ke atas dan ke bawah

2. Jalankan deteksi pose pada gambar sampel

Hal ini menghasilkan serangkaian penanda pose yang akan digunakan untuk pelatihan. Kami tidak tertarik pada deteksi pose itu sendiri, karena kita akan melatih model Anda sendiri di langkah berikutnya.

Algoritma k-NN yang telah dipilih untuk klasifikasi pose kustom membutuhkan representasi vektor fitur untuk setiap sampel dan metrik yang akan dihitung jarak antara dua vektor untuk menemukan target yang paling dekat dengan sampel pose. Ini berarti kita harus mengonversi penanda pose yang baru saja kita peroleh.

Untuk mengonversi {i>landmark <i}pose menjadi vektor fitur, kita menggunakan jarak berpasangan di antara daftar sendi pose yang telah ditentukan, seperti jarak antara pergelangan tangan dan bahu, pergelangan kaki dan pinggul, serta pergelangan tangan kiri dan kanan. Karena skala gambar bisa bervariasi, kami menormalkan pose agar memiliki ukuran batang tubuh dan batang tubuh vertikal yang sama sebelum mengonversi {i>landmark.<i}

3. Latih model dan hitung pengulangan

Kami menggunakan MediaPipe Colab untuk mengakses kode untuk pengklasifikasi dan melatih model.

Untuk menghitung pengulangan, kami menggunakan algoritma Colab lain untuk memantau probabilitas ambang batas posisi pose target. Contoh:

  • Ketika probabilitas "turun" kelas pose melewati ambang batas tertentu untuk pertama kali, algoritma menandai bahwa perintah "{i>down<i}" kelas pose dimasukkan.
  • Ketika probabilitas turun di bawah ambang batas, algoritma menandai bahwa "turun" telah dihapus dan jumlah penghitung meningkat.
Gambar 2. Contoh penghitungan pengulangan

4. Mengintegrasikan dengan aplikasi panduan memulai ML Kit

Colab di atas menghasilkan file CSV yang dapat diisi dengan semua pose Anda sampel. Di bagian ini, Anda akan mempelajari cara mengintegrasikan {i>file<i} CSV Anda dengan Aplikasi panduan memulai Android ML Kit untuk melihat klasifikasi pose kustom secara real time.

Coba klasifikasi pose dengan contoh yang disertakan dalam aplikasi panduan memulai

  • Dapatkan project aplikasi panduan memulai Android ML Kit dari Github dan memastikannya membangun dan berjalan dengan baik.
  • Buka LivePreviewActivity dan aktifkan Deteksi Pose Run classification dari menu Setelan' kami. Sekarang Anda seharusnya dapat mengklasifikasikan gerakan pushup dan squat.

Tambahkan CSV Anda sendiri

  • Tambahkan file CSV ke folder aset aplikasi.
  • Di PoseClassifierProcessor, perbarui variabel POSE_SAMPLES_FILE dan POSE_CLASSES agar sesuai dengan file CSV dan contoh posenya.
  • Bangun dan jalankan aplikasi.

Perhatikan bahwa klasifikasi mungkin tidak berfungsi dengan baik jika jumlah sampel tidak cukup. Umumnya, Anda memerlukan sekitar 100 sampel per class pose.

Untuk mempelajari lebih lanjut dan mencobanya sendiri, buka Colab MediaPipe dan panduan klasifikasi MediaPipe.

Mengenali gestur sederhana dengan menghitung jarak tempat terkenal

Ketika dua atau lebih {i>landmark<i} berdekatan satu sama lain, mereka dapat digunakan untuk mengenali {i>gestures.<i} Misalnya, saat penanda untuk satu atau beberapa jari pada tangan dekat dengan tonggak batas untuk hidung, Anda dapat menyimpulkan bahwa pengguna paling yang menyentuh wajah mereka.

Gambar 3. Menafsirkan pose

Mengenali pose yoga dengan heuristik sudut

Anda dapat mengidentifikasi pose yoga dengan menghitung sudut berbagai sendi. Sebagai gambar 2 di bawah ini menunjukkan pose yoga Warrior II. Perkiraan sudut yang mengidentifikasi pose ini ditulis dalam:

Gambar 4. Membagi pose menjadi beberapa sudut

Pose ini dapat dijelaskan sebagai kombinasi perkiraan tubuh berikut sudut bagian:

  • Sudut 90 derajat di kedua bahu
  • 180 derajat di kedua siku
  • Sudut 90 derajat di kaki depan dan pinggang
  • Sudut 180 derajat di lutut belakang
  • Sudut 135 derajat di pinggang

Anda dapat menggunakan penanda pose untuk menghitung sudut-sudut ini. Misalnya, sudut di kaki depan dan pinggang kanan adalah sudut antara garis dari kanan bahu ke pinggul kanan, dan garis dari pinggul kanan ke lutut kanan.

Setelah menghitung semua sudut yang diperlukan untuk mengidentifikasi pose, Anda dapat memeriksa untuk melihat apakah ada kecocokan, di mana Anda telah mengenali posenya.

Cuplikan kode di bawah ini menunjukkan cara menggunakan koordinat X dan Y untuk menghitung sudut antara dua bagian tubuh. Pendekatan terhadap klasifikasi memiliki beberapa keterbatasan. Dengan hanya memeriksa X dan Y, sudut yang dihitung akan bervariasi sesuai dengan sudut antara subjek dan kamera. Anda akan mendapatkan hasil terbaik dengan gambar yang lurus, lurus ke depan. Anda juga dapat coba memperluas algoritma ini dengan memanfaatkan Koordinat Z dan lihat apakah performanya lebih baik untuk kasus penggunaan Anda.

Menghitung sudut tempat terkenal di Android

Metode berikut menghitung sudut antara tiga {i>landmark.<i} Cara ini memastikan sudut yang dikembalikan berada di 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 pada 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 terkenal di iOS

Metode berikut menghitung sudut antara tiga {i>landmark.<i} Cara ini memastikan sudut yang dikembalikan berada di 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 pada 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]];