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ı ile poz sınıflandırma ve tekrar sayımı

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

Bu bölümde, MediaPipe Colab'ı kullanarak özel bir duruş sınıflandırıcıyı nasıl oluşturduğumuzu açıklıyor ve ML Kit örnek uygulamamızda çalışan bir sınıflandırıcıyı gösteriyoruz.

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

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. Resim örnekleri toplama

Hedef egzersizlerin görüntü örneklerini çeşitli kaynaklardan topladık. Her egzersiz için birkaç yüz resim seçtik (ör. şınav için "yukarı" ve "aşağı" pozisyonları). Farklı kamera açıları, ortam koşulları, vücut şekilleri ve egzersiz varyasyonlarını kapsayan örnekler toplamak önemlidir.

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

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

Bu işlem, eğitim için kullanılacak bir dizi duruş yer işareti oluşturur. 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 nedenle, yeni aldığımız poz yer işaretlerini dönüştürmemiz gerekir.

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 ve bilek arasındaki mesafe) omuz, ayak bileği, kalça, sol ve sağ bilekler. Resimlerin ölçeği değişiklik gösterebileceğinden, yer işaretlerini dönüştürmeden önce pozları aynı gövde boyutuna ve dikey gövde yönelimine sahip olacak şekilde normalleştirdik.

3. Modeli eğitme ve tekrarları sayma

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

Tekrarları saymak için hedef poz pozisyonunun olasılık eşiğini izlemek üzere başka bir Colab algoritması kullandık. Örneğin:

  • "Aşağı" duruş sınıfının olasılığı ilk kez belirli bir eşiği geçtiğinde algoritma, "aşağı" duruş sınıfının girildiğini işaretler.
  • Olasılık eşiğin altına düştüğünde algoritma, "aşağı" poz sınıfından çıkıldığını işaretler ve sayacı artırır.
.
Şekil 2. Tekrar sayma örneği

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

Yukarıdaki Colab, tüm pozlarınızla doldurabileceğiniz bir CSV dosyası oluşturur. kullanabilirsiniz. Bu bölümde, özel poz sınıflandırmasını anlık olarak görmek için CSV dosyanızı ML Kit Android hızlı başlangıç uygulamasıyla nasıl entegre edeceğinizi öğreneceksiniz.

Hızlı başlangıç uygulamasında bulunan örneklerle duruş sınıflandırmasını deneyin

Kendi CSV dosyanızı ekleme

  • 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ırmanın iyi sonuç vermeyebileceğini unutmayın. 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 ve MediaPipe sınıflandırma kılavuzuna 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 dokunurlar.

Şekil 3. Bir pozu yorumlama

Açı keşifleriyle yoga duruşlarını tanıma

Çeşitli eklemlerin açılarını hesaplayarak yoga pozlarını tanımlayabilirsiniz. Ö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. Pozlamayı farklı açılardan ayırma

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

  • Her iki omuz da 90 derecelik açıda
  • Her iki dirsek de 180 derece
  • Ön bacak ve bel 90 derecelik açıda
  • Arka dizde 180 derece açı
  • Belde 135 derecelik açı

Bu açıları hesaplamak için poz yer işaretlerini 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'inde, iki vücut parçası arasındaki açıyı hesaplamak için X ve Y koordinatlarının nasıl kullanılacağı gösterilmektedir. 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 yer açılarını hesaplama

Aşağıdaki yöntem, herhangi üç yer işareti arasındaki açıyı hesaplar. Döndürülen açının 0 ile 180 derece arasında olmasını sağlar.

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çının 0 ile 180 derece arasında olmasını sağlar.

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çıyı hesaplamak için:

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