Opzioni di classificazione delle posizioni

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

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

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

Una delle applicazioni più comuni per il rilevamento della posizione è il monitoraggio dell'attività fisica. Creare un classificatore di posa che riconosce specifiche posizioni di allenamento e conteggiare le ripetizioni può essere un'impresa impegnativa per gli sviluppatori.

In questa sezione viene descritto il modo in cui abbiamo creato un classificatore di pose personalizzato utilizzando MediaPipe Colab e dimostri una categoria di lavoro funzionante nella nostra app di esempio ML Kit.

Se non conosci Google Colaboratory, consulta la guida introduttiva.

Per riconoscere le posizioni, utilizziamo l'algoritmo k-vicinante più vicino (k-NN), perché è semplice e facile da usare. L'algoritmo determina la classe dell'oggetto in base ai campioni più vicini del set di addestramento.

Per creare e addestrare il riconoscimento:

1. Raccogli esempi di immagini

Abbiamo raccolto campioni di immagini degli allenamenti target da varie fonti. Per ogni esercizio abbiamo scelto alcune centinaia di immagini, ad esempio "up" e &downt; posizioni per flessioni. È importante raccogliere campioni che comprendano diverse angolazioni della videocamera, condizioni ambientali, forme del corpo e variazioni dell'allenamento.

Figura 1. Posizione delle flessioni in alto e in basso

2. Esegui il rilevamento della posa sulle immagini di esempio

Viene generato un set di punti di riferimento per la posa da utilizzare per l'addestramento. Non siamo interessati al rilevamento della posizione, dato che addestreremo il nostro modello nel passaggio successivo.

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

Per convertire i punti di riferimento di una posa in un vettore caratteristica, utilizziamo le distanze a coppie tra elenchi predefiniti di articolazioni della posa, come la distanza tra il polso e la spalla, la caviglia e l'anca e i polsi sinistro e destro. Poiché la scala delle immagini può variare, abbiamo normalizzato le posizioni per avere le stesse dimensioni e lo stesso orientamento del busto prima di convertire i punti di riferimento.

3. Addestrare il modello e conteggiare le ripetizioni

Abbiamo utilizzato MediaPipe Colab per accedere al codice per la categoria di classificazione e addestrare il modello.

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

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

4. Integrazione con l'app Guida rapida di ML Kit

Colab genera un file CSV che puoi completare con tutti i tuoi esempi di posa. In questa sezione imparerai a integrare il tuo file CSV con l'app rapida Guida rapida di ML Kit per Android per visualizzare la classificazione delle posizioni personalizzate in tempo reale.

Prova la classificazione delle posizioni con i campioni in bundle nell'app Guida rapida

  • Scarica il progetto dell'app Guida rapida di ML Kit Android da GitHub e assicurati che venga creato e funzioni correttamente.
  • Vai a LivePreviewActivity e attiva Rilevamento posizioneRun classification dalla pagina Impostazioni. Ora dovresti essere in grado di classificare flessioni e squat.

Aggiungi il tuo file CSV

  • Aggiungi il file CSV alla cartella di asset dell'app.
  • In PoseClassifierProcessor, aggiorna le variabili POSE_SAMPLES_FILE e POSE_CLASSES in modo che corrispondano al file CSV e agli esempi di posa.
  • Creare ed eseguire l'app.

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

Per saperne di più e provarlo in prima persona, consulta le pagine relative a MediaPipe Colab e alla guida alla classificazione di MediaPipe.

Riconoscere semplici gesti calcolando la distanza di un punto 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 una mano è vicino al punto di riferimento per il naso, è probabile che l'utente stia toccando il suo volto.

Figura 3. Interpretare una posa

Riconoscere una posizione yoga con l'euristica angolare

Per individuare la posizione di uno yoga, calcola gli angoli di varie articolazioni. Ad esempio, la Figura 2 di seguito mostra la posizione di yoga del Guerriero II. Gli angoli approssimativi che identificano questa posa sono scritti in:

Figura 4. Sfocare una posa da diverse angolazioni

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

  • Angolo di 90 gradi su entrambe le spalle
  • 180 gradi su entrambi i gomiti
  • Angolo di 90 gradi nella parte anteriore e in vita
  • Angolo di 180 gradi alla schiena
  • Angolo di 135 gradi in vita

Puoi utilizzare le punti di riferimento per la posa per calcolare queste angolazioni. Ad esempio, l'angolo nella parte anteriore destra e in vita è l'angolo tra la linea dalla spalla destra all'anca destra e la linea dall'anca destra al ginocchio destro.

Una volta calcolati tutti gli angoli necessari per identificare la posa, puoi controllare se c'è una corrispondenza, nel qual caso hai riconosciuto la posa.

Lo snippet di codice riportato di seguito illustra 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'angolo tra il soggetto e la fotocamera. Otterrai i migliori risultati con un'immagine frontale, dritta e senza ostacoli. Puoi anche provare a estendere questo algoritmo utilizzando la coordinata Z per vedere se ha un rendimento migliore per il tuo caso d'uso.

Calcolo degli angoli di riferimento su Android

Il metodo seguente 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'angolazione sull'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 di riferimento su iOS

Il metodo seguente 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'angolazione sull'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]];