Opzioni di classificazione delle pose

Con l'API ML Kit Pose Detection, puoi ricavare interpretazioni significative di una posa controllando le posizioni relative delle varie parti del corpo. Questa pagina illustra alcuni esempi.

Classificazione delle posizioni e conteggio delle ripetizioni con l'algoritmo k-NN

Una delle applicazioni più comuni del rilevamento delle pose è il monitoraggio dell'attività fisica. Creazione di un classificatore delle posizioni che riconosca determinate posizioni e il conteggio delle posizioni per il fitness le ripetizioni possono essere un'impresa impegnativa per gli sviluppatori.

In questa sezione viene spiegato come abbiamo creato una posa personalizzata. di classificazione utilizzando il Colab MediaPipe e Dimostrare un classificatore funzionante nell'app di esempio ML Kit.

Se non hai dimestichezza con Google Colaboratory, consulta il guida introduttiva.

Per riconoscere le pose usiamo l'algoritmo k- nearest neighbors (k-NN) perché è semplice e con cui iniziare è facile. L'algoritmo determina la classe dell'oggetto in base ai campioni più vicini nel set di addestramento.

Per creare e addestrare il riconoscimento:

1. Raccogliere campioni di immagini

Abbiamo raccolto campioni di immagini degli esercizi target da varie fonti. Me ha scelto alcune centinaia di immagini per ogni allenamento, ad esempio "su" e "Giù" posizioni per le flessioni. È importante raccogliere campioni che coprono diverse videocamere angoli, condizioni ambientali, forme del corpo e variazioni di allenamento.

Figura 1. Posizioni per i push-up verso l'alto e verso il basso

2. Esegui il rilevamento della posa sulle immagini di esempio

Viene generato un insieme di landmark della posa da utilizzare per l'addestramento. Non stiamo essere interessati al rilevamento della posa in sé, dato che addestreremo i nostri il proprio modello nel passaggio successivo.

L'algoritmo k-NN che abbiamo scelto per la classificazione delle pose personalizzate richiede una representatione del vettore di funzionalità per ogni campione e una metrica per calcolare la distanza tra due vettori per trovare il target più vicino al campione di pose. Ciò significa che dobbiamo convertire i punti di riferimento delle pose che abbiamo appena ottenuto.

Per convertire i landmark della posa in un vettore di caratteristiche, utilizziamo le distanze tra coppie di elenchi predefiniti di articolazioni della posa, ad esempio la distanza tra polso e spalla, caviglia e anca e polsi sinistro e destro. Poiché la scala delle immagini può variare, le pose sono state normalizzate in modo da avere la stessa dimensione del busto e la stessa verticale prima di convertire i punti di riferimento.

3. Addestra il modello e conta le ripetizioni

Abbiamo utilizzato MediaPipe Colab per accedere al codice del classificatore e per addestrare il modello.

Per conteggiare le ripetizioni, abbiamo utilizzato un altro algoritmo di Colab per monitorare la soglia di probabilità di una posizione della posa target. Ad esempio:

  • Quando la probabilità di "down" pose supera una determinata soglia per la prima volta, l'algoritmo contrassegna che la barra "giù" è stato inserito il corso di pose.
  • Quando la probabilità scende al di sotto della soglia, l'algoritmo indica che la classe di posa "giù" è stata abbandonata e aumenta il contatore.
Figura 2. Esempio di conteggio delle ripetizioni

4. Esegui l'integrazione con l'app rapida ML Kit

Il codice Colab riportato sopra produce un file CSV che puoi compilare con tutti i campioni di posa. In questa sezione imparerai a integrare il file CSV con l'app di avvio rapido di ML Kit per Android per visualizzare la classificazione delle pose personalizzate in tempo reale.

Prova la classificazione delle posizioni con esempi inclusi nell'app di avvio rapido

  • Recupera il progetto dell'app di guida rapida di ML Kit per Android da GitHub e assicurati che venga compilato e eseguito correttamente.
  • Vai a LivePreviewActivity e attiva Rilevamento posa Run classification dalla sezione Impostazioni . Ora dovresti essere in grado di classificare le flessioni e gli squat.

Aggiungere il tuo file CSV

  • Aggiungi il file CSV alla cartella degli asset dell'app.
  • In PoseClassifierProcessor, aggiorna le variabili POSE_SAMPLES_FILE e POSE_CLASSES in modo che corrispondano File CSV e esempi di posizioni.
  • Crea ed esegui l'app.

Tieni presente che la classificazione potrebbe non funzionare bene se non sono disponibili campioni sufficienti. In genere, sono necessari circa 100 campioni per classe di posa.

Per scoprire di più e provare questa funzionalità, consulta MediaPipe Colab e la guida alla classificazione di MediaPipe.

Riconoscere gesti semplici calcolando la distanza dei punti di riferimento

Quando due o più punti di riferimento sono vicini tra loro, possono essere utilizzati per: riconoscere i gesti. Ad esempio, quando il punto di riferimento per una o più dita su un mano è vicina al punto di riferimento per il naso, si può dedurre che l'utente è probabilmente si toccano il viso.

Figura 3. Interpretazione di una posa

Riconoscere una posizione di yoga con euristica angolare

Puoi identificare una posizione yoga calcolando gli angoli di varie articolazioni. Per esempio, la Figura 2 qui sotto mostra la posa dello yoga del Guerriero II. Gli angoli approssimativi che identificano questa posa sono scritti in:

Figura 4. Suddividere una posa in angolazione

Questa posa può essere descritta come la seguente combinazione di corpo approssimato angoli delle parti:

  • Angolo di 90 gradi su entrambe le spalle
  • 180 gradi su entrambi i gomiti
  • Angolo di 90 gradi sulla gamba anteriore e in vita
  • Angolo di 180 gradi al ginocchio posteriore
  • Angolo di 135 gradi in vita

Puoi utilizzare i landmark della posa per calcolare questi angoli. Ad esempio, l'angolo nella parte anteriore destra della gamba e della vita è l'angolo tra la linea da destra spalla al fianco destro e la linea tra il fianco destro e il ginocchio destro.

Dopo aver calcolato tutti gli angoli necessari per identificare la posa, puoi verificare se esiste una corrispondenza, nel qual caso avrai riconosciuto la posa.

Lo snippet di codice di seguito mostra come utilizzare le coordinate X e Y per calcolare l'angolo tra due parti del corpo. Questo approccio alla classificazione ha alcune limitazioni. Se controlli solo X e Y, gli angoli calcolati variano in base all'angolo tra il soggetto e la fotocamera. Otterrai il i risultati migliori con un'immagine frontale, dritta e piana. Puoi anche provare a estendere questo algoritmo utilizzando la coordinata Z e vedere se ha un rendimento migliore per il tuo caso d'uso.

Calcolo degli angoli dei punti di riferimento su Android

Il seguente metodo calcola l'angolo tra tre punti di riferimento. Garantisce che l'angolo restituito sia compreso tra 0 e 180 gradi.

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

Ecco come calcolare l'angolo all'anca destra:

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

Calcolo degli angoli dei punti di riferimento su iOS

Il seguente metodo calcola l'angolo tra tre qualsiasi punti di riferimento. Garantisce che l'angolo restituito sia compreso tra 0 e 180 gradi.

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

Ecco come calcolare l'angolo all'anca destra:

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