Opzioni di classificazione delle pose

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

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

Una delle applicazioni più comuni del rilevamento della posa è il monitoraggio dell'attività fisica. Creazione di un classificatore delle posizioni che riconosca determinate posizioni e il conteggio delle posizioni 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 nella nostra 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 al ai campioni più vicini nel set di addestramento.

Per creare e addestrare il riconoscimento:

1. Raccogli esempi 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 di posa per flessioni su e giù

2. Esegui il rilevamento della posa sulle immagini di esempio

Questo produce una serie di punti di riferimento di posa da utilizzare per l'allenamento. Non stiamo interessato 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 personalizzata delle posizioni richiede una rappresentazione vettoriale di caratteristiche per ogni campione e una metrica da calcolare la distanza tra due vettori per trovare il bersaglio più vicino al campione di posa. Questo significa che dobbiamo convertire i punti di riferimento delle pose che abbiamo appena ottenuto.

Per convertire i punti di riferimento delle pose in un vettore di caratteristiche, utilizziamo le distanze di coppie tra elenchi predefiniti di articolazioni di pose, come la distanza tra polso e spalla, caviglia e fianchi, nonché polsi sinistro e destro. Poiché la scala delle immagini può variare, le pose sono state normalizzate per avere il tronco e lo stesso tronco verticale prima di convertire i punti di riferimento.

3. Addestra il modello e conta le ripetizioni

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

Per conteggiare le ripetizioni abbiamo usato un altro algoritmo di Colab per monitorare la probabilità soglia di una posizione 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 contrassegna che la "verso il basso" è stata chiusa la classe pose e il contatore aumenta.
Figura 2. Esempio di conteggio delle ripetizioni

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

Il Colab riportato sopra produce un file CSV che puoi compilare con tutte le tue pose i campioni. In questa sezione, scoprirai come integrare il file CSV con il App rapida per Android ML Kit per vedere la classificazione personalizzata delle posizioni in tempo reale.

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

  • Accedi al progetto dell'app rapida per Android ML Kit da GitHub e assicurarti che build e funzioni 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.

Aggiungi 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.
  • Creare ed eseguire l'app.

Tieni presente che la classificazione potrebbe non funzionare correttamente se non ci sono abbastanza campioni. In genere, sono necessari circa 100 campioni per classe di posa.

Per scoprire di più e provarlo in autonomia, dai un'occhiata al Colab MediaPipe 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. Interpretare una posa

Riconoscere una posizione di yoga con l'euristica angolare

Puoi identificare una posizione di 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. Suddivisione della posa in diverse angolazioni

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

  • Angolo di 90° su entrambe le spalle
  • 180 gradi a entrambi i gomiti
  • Angolo di 90° su gamba e vita anteriori
  • Angolo di 180° nella parte posteriore del ginocchio
  • Angolo di 135° alla vita

Puoi utilizzare i punti di riferimento delle posizioni 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.

Una volta calcolate tutte le angolazioni necessarie per identificare la posa, puoi controllare per vedere se c'è una corrispondenza e in questo caso hai riconosciuto la posa.

Lo snippet di codice riportato 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. Selezionando solo X e Y, gli angoli calcolati variano in base all'angolazione tra il soggetto e la fotocamera. Otterrai il i risultati migliori con un'immagine frontale, dritta e piana. Potresti inoltre prova a estendere questo algoritmo utilizzando la classe Coordinata Z e vedere se funziona meglio 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 dell'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 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 dell'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]];