Optionen für die Klassifizierung von Positionen

Mit der ML Kit Pose Detection API können Sie die relativen Positionen verschiedener Körperteile prüfen und so aussagekräftige Interpretationen einer Pose ableiten. Auf dieser Seite werden einige Beispiele vorgestellt.

Posenklassifizierung und Zählung von Wiederholungen mit dem k-NN-Algorithmus

Eine der häufigsten Anwendungen der Posenerkennung ist das Fitness-Tracking. Das Erstellen eines Posenklassifikators, der bestimmte Fitnesspositionen erkennt und Wiederholungen zählt, kann für Entwickler eine Herausforderung sein.

In diesem Abschnitt wird beschrieben, wie wir mit MediaPipe Colab einen benutzerdefinierten Posenklassifikator erstellt und einen funktionierenden Klassifikator in unserer ML Kit-Beispiel-App demonstriert haben.

Wenn Sie mit Google Colaboratory nicht vertraut sind, lesen Sie die Einführung.

Um Posen zu erkennen, verwenden wir den Algorithmus der k-nächsten Nachbarn (k-NN), da er einfach und leicht zu beginnen ist. Der Algorithmus bestimmt die Klasse des Objekts basierend auf den nächstgelegenen Beispielen im Trainingssatz.

Führen Sie die folgenden Schritte aus, um die Erkennung zu erstellen und zu trainieren:

1. Bildbeispiele erfassen

Wir haben Bildbeispiele der Zielübungen aus verschiedenen Quellen gesammelt. Für jede Übung wählen wir ein paar hundert Bilder aus, z. B. die „nach oben“- und „nach unten“-Positionen für Liegestütze. Es ist wichtig, Proben zu sammeln, die verschiedene Kamerawinkel, Umgebungsbedingungen, Körperformen und Trainingsvarianten abdecken.

Abbildung 1: Liegestütze nach oben und unten

2. Posenerkennung für Beispielbilder ausführen

Dadurch werden eine Reihe von Posen-Markierungspunkten erstellt, die für das Training verwendet werden können. Wir sind nicht an der Posenerkennung selbst interessiert, da wir im nächsten Schritt unser eigenes Modell trainieren.

Der k-NN-Algorithmus, den wir für die benutzerdefinierte Posenklassifizierung ausgewählt haben, erfordert eine Featurevektordarstellung für jede Stichprobe und einen Messwert zur Berechnung der Entfernung zwischen zwei Vektoren, um das Ziel zu finden, das der Posenprobe am nächsten ist. Das bedeutet, dass wir die gerade erhaltenen Posen-Markierungen konvertieren müssen.

Um Posen-Markierungen in einen Featurevektor umzuwandeln, verwenden wir paarweise Abstände zwischen vordefinierten Listen von Posenverbindungen, z. B. den Abstand zwischen Handgelenk und Schulter, Knöchel und Hüfte sowie linkes und rechtes Handgelenk. Da der Maßstab von Bildern variieren kann, haben wir die Posen vor dem Konvertieren der Orientierungspunkte so normalisiert, dass sie dieselbe Rumpfgröße und vertikale Rumorausrichtung haben.

3. Modell trainieren und Wiederholungen zählen

Wir haben MediaPipe Colab verwendet, um auf den Code für den Klassifikator zuzugreifen und das Modell zu trainieren.

Zum Zählen von Wiederholungen haben wir einen weiteren Colab-Algorithmus verwendet, um den Wahrscheinlichkeitsgrenzwert einer Zielposition zu überwachen. Beispiel:

  • Wenn die Wahrscheinlichkeit der Posenklasse „nach unten“ zum ersten Mal einen bestimmten Grenzwert überschreitet, markiert der Algorithmus, dass die Posenklasse „nach unten“ eingegeben wurde.
  • Wenn die Wahrscheinlichkeit unter den Grenzwert fällt, markiert der Algorithmus, dass die Posenklasse „Abwärts“ beendet wurde, und erhöht den Zähler.
Abbildung 2: Beispiel für die Zählung von Wiederholungen

4. ML Kit-Kurzanleitungs-App einbinden

Das obige Colab erstellt eine CSV-Datei, in die Sie alle Ihre Posen-Beispiele einfügen können. In diesem Abschnitt erfahren Sie, wie Sie Ihre CSV-Datei in die ML Kit Android-Kurzanleitungs-App einbinden, um benutzerdefinierte Posenklassifizierung in Echtzeit zu sehen.

Mit Beispielen, die in der Kurzanleitung gebündelt sind, die Positionsklassifizierung testen

  • Laden Sie das ML Kit Android-Kurzanleitungs-App-Projekt von GitHub herunter und prüfen Sie, ob es einwandfrei erstellt und ausgeführt werden kann.
  • Rufe LivePreviewActivity auf und aktiviere auf der Seite „Einstellungen“ die Positionserkennung Run classification. Jetzt solltest du Liegestütze und Kniebeugen klassifizieren können.

Eigene CSV-Datei hinzufügen

  • Fügen Sie die CSV-Datei dem Asset-Ordner der App hinzu.
  • Aktualisieren Sie in PoseClassifierProcessor die Variablen POSE_SAMPLES_FILE und POSE_CLASSES, damit sie Ihrer CSV-Datei entsprechen und Beispiele darstellen.
  • Erstellen Sie die Anwendung und führen Sie sie aus.

Beachten Sie, dass die Klassifizierung möglicherweise nicht gut funktioniert, wenn nicht genügend Beispiele vorhanden sind. Im Allgemeinen benötigen Sie etwa 100 Beispiele pro Posenklasse.

Weitere Informationen und dazu, wie Sie dies selbst ausprobieren können, finden Sie im MediaPipe Colab- und im MediaPipe-Klassifizierungsleitfaden.

Einfache Gesten durch Berechnung der Entfernung von Orientierungspunkten erkennen

Wenn zwei oder mehr Orientierungspunkte nah beieinander sind, können sie verwendet werden, um Gesten zu erkennen. Wenn sich beispielsweise die Markierung für einen oder mehrere Finger einer Hand nahe an der Markierung für die Nase befindet, können Sie daraus ableiten, dass der Nutzer am ehesten das Gesicht berührt.

Abbildung 3: Pose interpretieren

Eine Yogastellung mit Winkelheuristik erkennen

Du kannst eine Yogastellung bestimmen, indem du die Winkel verschiedener Gelenke berechnest. Abbildung 2 unten zeigt zum Beispiel die Yogastellung von Warrior II. Die ungefähren Winkel, die diese Pose identifizieren, sind so angegeben:

Abbildung 4: Eine Stellung in verschiedene Winkel aufbrechen

Diese Pose kann als folgende Kombination aus ungefähren Winkeln der Körperteile beschrieben werden:

  • 90-Grad-Winkel an beiden Schultern
  • 180 Grad bei beiden Ellbogen
  • 90-Grad-Winkel an vorderem Bein und an der Taille
  • 180-Grad-Winkel am hinteren Knie
  • 135-Grad-Winkel an der Taille

Sie können die Positionsmarkierungen verwenden, um diese Winkel zu berechnen. Beispielsweise ist der Winkel am rechten vorderen Bein und an der Taille der Winkel zwischen der Linie von der rechten Schulter zur rechten Hüfte und der Linie von der rechten Hüfte zum rechten Knie.

Nachdem Sie alle Winkel berechnet haben, die zum Identifizieren der Position erforderlich sind, können Sie überprüfen, ob es eine Übereinstimmung gibt. In diesem Fall haben Sie die Position erkannt.

Das folgende Code-Snippet zeigt, wie mithilfe der x- und y-Koordinaten der Winkel zwischen zwei Körperteilen berechnet wird. Dieser Klassifizierungsansatz hat einige Einschränkungen. Indem Sie nur X und Y überprüfen, variieren die berechneten Winkel entsprechend dem Winkel zwischen Objekt und Kamera. Die besten Ergebnisse erzielen Sie mit einem neutralen, direkt ausgerichteten Bild. Sie können auch versuchen, diesen Algorithmus mithilfe der Z-Koordinate zu erweitern, um festzustellen, ob er für Ihren Anwendungsfall besser funktioniert.

Winkel der Sehenswürdigkeiten unter Android berechnen

Mit der folgenden Methode wird der Winkel zwischen drei beliebigen Sehenswürdigkeiten berechnet. Sie sorgt dafür, dass der zurückgegebene Winkel zwischen 0 und 180 Grad liegt.

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

So berechnen Sie den Winkel an der rechten Hüfte:

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

Winkel der Sehenswürdigkeiten unter iOS berechnen

Mit der folgenden Methode wird der Winkel zwischen drei beliebigen Sehenswürdigkeiten berechnet. Sie sorgt dafür, dass der zurückgegebene Winkel zwischen 0 und 180 Grad liegt.

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

So berechnen Sie den Winkel an der rechten Hüfte:

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