Poz sınıflandırma seçenekleri

ML Kit Pose Detection API ile anlamlı yorumlar elde edebilirsiniz Vücudun çeşitli kısımlarının göreli konumlarını kontrol ederek pozun farklı kısımlarını kontrol edebilirsiniz. Bu sayfa birkaç örnek gösteriyor.

k-NN algoritmasıyla duruş sınıflandırması ve tekrar sayımı

Poz algılamanın en yaygın uygulamalarından biri fitness takibidir. Belirli fitness duruşlarını ve sayılarını tanıyan bir poz sınıflandırıcı oluşturma tekrarlar, geliştiriciler için zorlu bir iş olabilir.

Bu bölümde özel bir pozu nasıl oluşturduğumuz açıklanmaktadır. MediaPipe Colab kullanarak sınıflandırıcılar ve ML Kit örnek uygulamamızda çalışan bir sınıflandırıcıyı inceleyelim.

Google Colaboratory hakkında bilginiz yoksa lütfen şu sayfaya göz atın: giriş rehberini inceleyin.

Pozları tanımak için k-en yakın komşular algoritmasını (k-NN) kullanırız. ve kolayca başlayabilirsiniz. Algoritma, şu bilgilere göre nesnenin sınıfını belirler: en yakın örnekleri içerir.

Tanıyıcıyı oluşturmak ve eğitmek için şu adımları uygulayın:

1. Görüntü örnekleri toplama

Hedef egzersizlerin görüntü örneklerini çeşitli kaynaklardan topladık. Biz Her egzersiz için birkaç yüz resim seçti (örneğin, "yukarıda" ve "down" konumlar iyi bir fırsattır. Farklı kameraları kapsayan örnekler toplanması açıları, ortam koşulları, vücut şekilleri ve egzersiz varyasyonları.

.
Şekil 1. Yukarı ve aşağı şınav duruş pozisyonları

2. Örnek görüntülerde poz algılamayı çalıştır

Bu şekilde, eğitim için kullanılacak bir dizi duruş simgesi oluşturulur. Biz, çünkü poz algılamayla ilgili ayrıntılı eğitimlere sahip olacağız. modelinize göz atın.

Özel poz sınıflandırması için seçtiğimiz k-NN algoritmasında her örneklem için özellik vektörü gösterimi ve hesaplanacak bir metrik poz örneğine en yakın hedefi bulmak için iki vektör arasındaki mesafeyi ölçer. Bu, az önce edindiğimiz poz önemli noktalarını dönüştürmemiz gerektiği anlamına gelir.

Pozdaki önemli noktaları bir özellik vektörüne dönüştürmek için, iki yönlü mesafeleri kullanırız önceden tanımlanmış poz eklemleri listeleri arasında (örneğin, bilek ile bilek arasındaki mesafe) omuz, ayak bileği, kalça, sol ve sağ bilekler. Resimlerin ölçeği değişebildiğinden, duruşları aynı gövde boyutuna ve dikey gövdeye sahip olacak şekilde normalleştirdik. yönü.

3. Modeli eğitme ve tekrarları sayma

Sınıflandırıcının koduna erişmek için MediaPipe Colab'i ve modeli eğitirsiniz.

Tekrarları saymak amacıyla, tekrarlama olasılığını izlemek için başka bir Colab algoritması kullandık eşiğine ulaşabilirsiniz. Örneğin:

  • "Düşüş" olasılığı, poz sınıfı, belirli bir eşiği geçer işlemden sonra, algoritma "aşağı"nın poz sınıfı girildi.
  • Olasılık eşiğin altına düştüğünde, algoritma "aşağı" poz sınıfından çıkıldı ve sayacı artırıyor.
.
Şekil 2. Tekrar sayma örneği

4. ML Kit hızlı başlangıç uygulamasıyla entegrasyon

Yukarıdaki Colab, tüm pozlarınızı doldurabileceğiniz bir CSV dosyası oluşturur. kullanabilirsiniz. Bu bölümde, CSV dosyanızı CSV dosyasıyla nasıl entegre edeceğinizi Özel poz sınıflandırmasını gerçek zamanlı olarak görmenizi sağlayan ML Kit Android hızlı başlangıç uygulaması.

Hızlı başlangıç uygulamasında paket halinde sunulan örneklerle poz sınıflandırmasını deneyin

  • ML Kit Android hızlı başlangıç kılavuzu uygulama projesini edinin. iyi derlendiğinden ve çalıştığından emin olun.
  • LivePreviewActivity bölümüne gidip Poz Algılama'yı etkinleştirin Run classification Ayarlar'dan sayfasını ziyaret edin. Artık şınav ve çömelme egzersizlerini sınıflandırabilmelisiniz.

Kendi CSV'nizi ekleyin

  • CSV dosyanızı uygulamanın öğe klasörüne ekleyin.
  • PoseClassifierProcessor'da, POSE_SAMPLES_FILE ve POSE_CLASSES değişkenlerini CSV dosyası ve poz örnekleri.
  • Uygulamayı derleyip çalıştırın.

Yeterli örnek olmadığında sınıflandırma iyi sonuç vermeyebilir. Genellikle poz dersi başına yaklaşık 100 örneğe ihtiyacınız vardır.

Daha fazla bilgi edinmek ve bunu kendiniz denemek için MediaPipe Colab'e göz atın ve MediaPipe sınıflandırma kılavuzu'na göz atın.

Önemli nokta mesafesini hesaplayarak basit hareketleri tanıma

İki veya daha fazla önemli nokta birbirine yakın olduğunda, bu noktalar hareketleri tanıyalım. Örneğin, bir konumdaki bir veya daha fazla parmağınızla bir el simgesi burundaki belirgin noktaya yakınsa, kullanıcının en çok muhtemelen yüzlerine değiyorlar.

.
Şekil 3. Bir pozu yorumlama

Açı buluşsal yöntemlerle yoga duruşunu tanıma

Farklı eklemlerin açılarını hesaplayarak bir yoga duruşunu tanıyabilirsiniz. Örneğin, aşağıdaki Şekil 2'de Savaşçı II yoga pozu gösterilmektedir. Yaklaşık açılar şu karakterlerle yazılmıştır:

.
Şekil 4. Pozları farklı açılardan ayırma

Bu poz, aşağıdaki yaklaşık vücut kombinasyonu olarak açıklanabilir parça açıları:

  • Her iki omuzda 90 derece açı
  • Her iki dirsekte 180 derece
  • Ön bacak ve belden 90 derece açı
  • Dizin arkadan 180 derece açı
  • Belden 135 derece açı

Bu açıları hesaplamak için pozdaki önemli noktaları kullanabilirsiniz. Örneğin, açı belde, sağ ön bacakta ve belde, sağ taraftaki çizgi arasındaki açıdır. kalçadan sağ kalçaya kadar uzanan çizgiyi kapsar.

Pozu belirlemek için gereken tüm açıları hesapladıktan sonra, bir eşleşme olup olmadığına bakın. Bu durumda, pozu tanımış olursunuz.

Aşağıdaki kod snippet'i, iki vücudun iki bölümü arasındaki açıyı hesaplayabilme. Sınıflandırmaya bu yaklaşım bazı sınırlamalar vardır. Yalnızca X ve Y'yi işaretlediğinizde hesaplanan açılar değişir kamera ile özne arasındaki açıya göre ayarlanır. Her e-postada doğrudan bir resimle en iyi sonuçları elde edebilirsiniz. Ayrıca transkriptinizi Z koordinatı daha iyi performans gösterip göstermediğine bakın.

Android'de önemli nokta açıları hesaplama

Aşağıdaki yöntemde, herhangi bir üç alan arasındaki açı hesaplanır önemli noktalardır. Döndürülen açısın 0 ve 180 derece.

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;
}

Sağ kalçadaki açı şu şekilde hesaplanabilir:

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'ta önemli nokta açıları hesaplama

Aşağıdaki yöntemde, herhangi bir üç alan arasındaki açı hesaplanır önemli noktalardır. Döndürülen açısın 0 ve 180 derece.

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;
}

Sağ kalçadaki açı şu şekilde hesaplanabilir:

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]];