Optionen für die Klassifizierung von Positionen

Mit der ML Kit Pose Detection API können Sie aussagekräftige Interpretationen Pose, indem die relativen Positionen verschiedener Körperteile überprüft werden. Diese Seite zeigt einige Beispiele.

Posenkennzeichnung und Wiederholungszählung mit dem k-NN-Algorithmus

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

In diesem Abschnitt beschreiben wir, wie wir eine individuelle Pose erstellen. Klassifikator mit dem MediaPipe Colab und einen funktionierenden Klassifikator in unserer ML Kit-Beispiel-App.

Wenn Sie mit Google Colaboratory nicht vertraut sind, finden Sie im Einführungsleitfaden.

Um Posen zu erkennen, verwenden wir den Algorithmus für die k-nächstgelegenen Nachbarn (k-NN), da er einfach und ein einfacher Einstieg. Der Algorithmus bestimmt die Klasse des Objekts basierend auf dem im Trainings-Dataset am nächsten liegen.

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. Mi. habe ein paar Hundert Bilder für jede Übung ausgewählt, z. B. „nach oben“ und „nach unten“ Positionen für Liegestütze. Es ist wichtig, Beispiele zu erfassen, die verschiedene Kamerawinkel, Umgebungsbedingungen, Körperformen und Übungsvarianten abdecken.

Abbildung 1 Liegestützpositionen nach oben und unten

2. Körperhaltungserkennung auf den Beispielbildern ausführen

So erhalten Sie eine Reihe von Orientierungspunkten für die Pose, die für das Training verwendet werden können. Wir sind nicht an der Posenerkennung selbst interessiert sind, da wir unsere eigenen Modell erstellen.

Der von uns für die Klassifizierung benutzerdefinierter Posen ausgewählte k-NN-Algorithmus erfordert eine Merkmalsvektordarstellung für jede Probe und einen Messwert, um die Entfernung zwischen zwei Vektoren zu berechnen und das dem Pose-Beispiel am nächsten gelegene Ziel zu finden. Das bedeutet, dass wir die gerade ermittelten Positionsmarkierungen konvertieren müssen.

Um die Positionsmarkierungen in einen Merkmalsvektor umzuwandeln, verwenden wir die paarweisen Abstände zwischen vordefinierten Listen von Gelenken, z. B. den Abstand zwischen Handgelenk und Schulter, Knöchel und Hüfte sowie zwischen linkem und rechtem Handgelenk. Da die Größe der Bilder variieren kann, haben wir die Posen normalisiert, damit sie dieselbe Torsogröße und vertikale Ausrichtung haben, bevor wir die Markierungen konvertiert haben.

3. Modell trainieren und Wiederholungen zählen

Wir haben mit MediaPipe Colab auf den Code für den Klassifikator zugegriffen und das Modell trainieren.

Um Wiederholungen zu zählen, haben wir einen weiteren Colab-Algorithmus verwendet, um den Wahrscheinlichkeitsgrenzwert einer Zielpose zu überwachen. Beispiel:

  • Wenn die Wahrscheinlichkeit eines „Rückwärtsgangs“ Pose-Klasse erfüllt einen bestimmten Schwellenwert erkennt der Algorithmus, dass die „schlechten“ Pose-Klasse eingegeben wurde.
  • Wenn die Wahrscheinlichkeit unter den Grenzwert sinkt, kennzeichnet der Algorithmus, dass die „nach unten“-Pose-Klasse verlassen wurde, und erhöht den Zähler.
Abbildung 2. Beispiel für die Wiederholungszählung

4. Integration in die ML Kit-Schnellstart-App

Das Colab oben generiert eine CSV-Datei, die Sie mit allen Ihren Positionsbeispielen füllen können. In diesem Abschnitt erfahren Sie, wie Sie Ihre CSV-Datei in die ML Kit-Android-Kurzanleitungs-App einbinden, um die benutzerdefinierte Körperhaltungsklassifizierung in Echtzeit zu sehen.

Körperhaltungsklassifizierung mit in der Kurzanleitungs-App enthaltenen Beispielen ausprobieren

  • Laden Sie das ML Kit Android-Schnellstart-App-Projekt von GitHub herunter und prüfen Sie, ob es richtig erstellt und ausgeführt wird.
  • Gehe zu LivePreviewActivity und aktiviere auf der Seite „Einstellungen“ die Körperhaltungserkennung Run classification. Jetzt sollten Sie in der Lage sein, Liegestütze und Kniebeugen zu klassifizieren.

Eigene CSV-Datei hinzufügen

  • Fügen Sie die CSV-Datei dem Asset-Ordner der App hinzu.
  • Führen Sie in PoseClassifierProcessor folgende Schritte aus: Aktualisieren Sie die Variablen POSE_SAMPLES_FILE und POSE_CLASSES entsprechend Ihren CSV-Datei und stellen Beispiele bereit.
  • Erstellen Sie die Anwendung und führen Sie sie aus.

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

Wenn Sie mehr erfahren und dies selbst ausprobieren möchten, sehen Sie sich MediaPipe Colab an und im Leitfaden zur MediaPipe-Klassifizierung.

Erkennen einfacher Gesten durch Berechnen der Entfernung zu einem Wahrzeichen

Wenn zwei oder mehr Orientierungspunkte nahe beieinander liegen, können sie verwendet werden, Gesten erkennen. Wenn beispielsweise die Markierung für einen oder mehrere Finger auf einem sich nah an der Markierung für die Nase befindet, können Sie daraus ableiten, wahrscheinlich, dass sie ihr Gesicht berühren.

Abbildung 3: Eine Pose interpretieren

Yogastellung mit Winkelheuristiken erkennen

Du kannst eine Yogastellung identifizieren, indem du die Winkel verschiedener Gelenke berechnet. Für Beispiel: Abbildung 2 zeigt die Yoga-Pose von Warrior II. Die ungefähren Winkel die diese Pose identifizieren, geschrieben in:

Abbildung 4: Eine Stellung in die richtigen Winkel bringen

Diese Haltung lässt sich als die folgende Kombination aus Körperform beschreiben: Teilwinkel:

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

Sie können diese Winkel mit den Orientierungspunkten für die Pose berechnen. Der Winkel zwischen dem rechten Vorderbein und der Taille ist beispielsweise 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 zur Identifizierung der Position erforderlichen Winkel berechnet haben, um zu sehen, ob es eine Übereinstimmung gibt.

Das folgende Code-Snippet zeigt, wie die X- und Y-Koordinaten verwendet werden, um um den Winkel zwischen zwei Körperteilen zu berechnen. Dieser Klassifizierungsansatz hat einige Einschränkungen. Indem Sie nur X und Y prüfen, variieren die berechneten Winkel je nach Winkel zwischen Objekt und Kamera. Sie erhalten die beste Ergebnisse mit einem waagerechten, geraden, Frontalbild zu erzielen. Sie können auch Erweitern Sie diesen Algorithmus mithilfe des Z-Koordinate und prüfen, ob sie für Ihren Anwendungsfall besser geeignet ist.

Orientierungspunkte unter Android berechnen

Die folgende Methode berechnet den Winkel zwischen drei beliebigen Sehenswürdigkeiten. Sie stellt sicher, dass der zurückgegebene Winkel zwischen 0 und 180 Grad.

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

Orientierungspunkte unter iOS berechnen

Mit der folgenden Methode wird der Winkel zwischen beliebigen drei Markierungen berechnet. Sie stellt sicher, dass der zurückgegebene Winkel zwischen 0 und 180 Grad.

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