Guida al rilevamento dei punti di riferimento per Android

L'attività Punto di riferimento per la posa di MediaPipe consente di rilevare i punti di riferimento di corpi umani in un'immagine o in un video. Puoi utilizzare questa attività per identificare le posizioni chiave del corpo, analizzare la postura e classificare i movimenti. Questa attività usa modelli di machine learning (ML) che funzionano con singole immagini o video. L'attività restituisce i punti di riferimento nelle coordinate dell'immagine e nelle coordinate tridimensionali.

L'esempio di codice descritto in queste istruzioni è disponibile su GitHub. Per ulteriori informazioni sulle funzionalità, sui modelli e sulle opzioni di configurazione di questa attività, consulta la Panoramica.

Esempio di codice

Il codice di esempio di MediaPipe Tasks è una semplice implementazione di un'app Pose Referenceer per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare le pose in uno stream video continuo. L'app può anche rilevare le pose nelle immagini e nei video dalla galleria del dispositivo.

Puoi utilizzare l'app come punto di partenza per la tua app per Android o farvi riferimento quando modifichi un'app esistente. Il codice di esempio per la posizione di riferimento è ospitato su GitHub.

Scarica il codice

Le seguenti istruzioni mostrano come creare una copia locale del codice di esempio utilizzando lo strumento a riga di comando git.

Per scaricare il codice di esempio:

  1. Clona il repository git utilizzando il seguente comando:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Facoltativamente, configura la tua istanza Git in modo da utilizzare un pagamento sparse, in modo da avere solo i file per l'app di esempio Pose Referenceer:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/pose_landmarker/android
    

Dopo aver creato una versione locale del codice di esempio, puoi importare il progetto in Android Studio ed eseguire l'app. Per le istruzioni, consulta la Guida alla configurazione per Android.

Componenti chiave

I seguenti file contengono il codice fondamentale per questa applicazione di esempio di riferimento per la posa:

  • PoseLandmarkerHelper.kt: inizializza l'indicatore di riferimento per la posa e gestisce il modello e la selezione dei delegati.
  • CameraFragment.kt: gestisce la fotocamera del dispositivo ed elabora i dati di input di immagini e video.
  • GalleryFragment.kt: interagisce con OverlayView per visualizzare l'immagine o il video di output.
  • OverlayView.kt: implementa il display per le pose rilevate.

Configurazione

In questa sezione vengono descritti i passaggi chiave per configurare l'ambiente di sviluppo e codificare i progetti in modo specifico per l'utilizzo di Punto di riferimento per le posizioni. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'utilizzo delle attività di MediaPipe, inclusi i requisiti di versione della piattaforma, consulta la Guida alla configurazione per Android.

Dipendenze

L'attività Punto di riferimento per la posa utilizza la libreria com.google.mediapipe:tasks-vision. Aggiungi questa dipendenza al file build.gradle della tua app Android:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

Modello

L'attività Punto di riferimento per la posizione di MediaPipe richiede un bundle di modelli addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il punto di riferimento Pose, consulta la sezione Modelli della panoramica dell'attività.

Seleziona e scarica il modello e archivialo all'interno della directory del progetto:

<dev-project-root>/src/main/assets

Specifica il percorso del modello all'interno del parametro ModelAssetPath. Nel codice di esempio, il modello è definito nel file PoseLandmarkerHelper.kt:

val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)

Creare l'attività

L'attività Punto di riferimento per la posizione di MediaPipe utilizza la funzione createFromOptions() per configurarla. La funzione createFromOptions() accetta i valori per le opzioni di configurazione. Per maggiori informazioni sulle opzioni di configurazione, consulta Opzioni di configurazione.

Il punto di riferimento per la posa supporta i seguenti tipi di dati di input: immagini fisse, file video e stream video in diretta. Devi specificare la modalità di esecuzione corrispondente al tipo di dati di input quando crei l'attività. Scegli la scheda relativa al tipo di dati di input per vedere come creare l'attività.

Immagine

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

Video

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

Live streaming

val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName)
val baseOptions = baseOptionBuilder.build()

val optionsBuilder = 
    poseLandmarker.poseLandmarkerOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinPoseDetectionConfidence(minPoseDetectionConfidence)
        .setMinTrackingConfidence(minPoseTrackingConfidence)
        .setMinPosePresenceConfidence(minposePresenceConfidence)
        .setNumPoses(maxNumPoses)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
poseLandmarker = poseLandmarker.createFromOptions(context, options)
    

L'implementazione di codice di esempio di Punto di riferimento per la posizione consente all'utente di passare da una modalità di elaborazione all'altra. Questo approccio rende più complicato il codice per la creazione delle attività e potrebbe non essere appropriato per il tuo caso d'uso. Puoi vedere questo codice nella funzione setupPoseLandmarker() del file PoseLandmarkerHelper.kt.

Opzioni di configurazione

Questa attività prevede le seguenti opzioni di configurazione per le app per Android:

Nome opzione Descrizione Intervallo di valori Valore predefinito
runningMode Imposta la modalità di esecuzione per l'attività. Esistono tre modalità:

IMAGE: la modalità per gli input di singole immagini.

VIDEO: la modalità per i fotogrammi decodificati di un video.

LIVE_STREAM: la modalità per un live streaming di dati di input, ad esempio da una videocamera. In questa modalità, resultListener deve essere chiamato per configurare un listener per ricevere i risultati in modo asincrono.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numposes Il numero massimo di pose che possono essere rilevate dall'elemento di riferimento per le pose. Integer > 0 1
minPoseDetectionConfidence Il punteggio di affidabilità minimo affinché il rilevamento della posa venga considerato riuscito. Float [0.0,1.0] 0.5
minPosePresenceConfidence Il punteggio di affidabilità minimo del punteggio di presenza della posa nel rilevamento dei punti di riferimento della posa. Float [0.0,1.0] 0.5
minTrackingConfidence Il punteggio di affidabilità minimo affinché il monitoraggio della posa venga considerato riuscito. Float [0.0,1.0] 0.5
outputSegmentationMasks Indica se il punto di riferimento per la posa restituisce una maschera di segmentazione per la posa rilevata. Boolean False
resultListener Imposta il listener dei risultati per ricevere i risultati del punto di riferimento in modo asincrono quando il punto di riferimento per la posa è in modalità live streaming. Può essere utilizzato solo quando la modalità di esecuzione è impostata su LIVE_STREAM ResultListener N/A
errorListener Imposta un listener di errori facoltativo. ErrorListener N/A

Preparazione dei dati

Pose Punto di riferimento funziona con immagini, file video e stream video in diretta. L'attività gestisce la pre-elaborazione dell'input dei dati, tra cui il ridimensionamento, la rotazione e la normalizzazione dei valori.

Il seguente codice mostra come trasferire i dati per l'elaborazione. Questi esempi includono dettagli su come gestire i dati di immagini, file video e stream di video dal vivo.

Immagine

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()
    

Video

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

val argb8888Frame =
    if (frame.config == Bitmap.Config.ARGB_8888) frame
    else frame.copy(Bitmap.Config.ARGB_8888, false)

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(argb8888Frame).build()
    

Live streaming

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    

Nel codice di esempio del punto di riferimento per la posa, la preparazione dei dati viene gestita nel file PoseLandmarkerHelper.kt.

Esegui l'attività

A seconda del tipo di dati con cui lavori, utilizza il metodo poseLandmarker.detect...() specifico per quel tipo di dati. Utilizza detect() per le singole immagini, detectForVideo() per i frame nei file video e detectAsync() per gli stream video. Quando esegui rilevamenti su uno stream video, assicurati di eseguirli in un thread separato per evitare di bloccare l'interposizione del thread da parte dell'utente.

I seguenti esempi di codice mostrano semplici esempi di come eseguire Pose Targeter in queste diverse modalità dei dati:

Immagine

val result = poseLandmarker.detect(mpImage)
    

Video

val timestampMs = i * inferenceIntervalMs

poseLandmarker.detectForVideo(mpImage, timestampMs)
    .let { detectionResult ->
        resultList.add(detectionResult)
    }
    

Live streaming

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

poseLandmarker.detectAsync(mpImage, frameTime)
    

Tieni presente quanto riportato di seguito:

  • Quando esegui l'esecuzione in modalità video o live streaming, devi fornire il timestamp del frame di input all'attività Pose Referenceer.
  • Quando viene eseguita in modalità immagine o video, l'attività Metrica di riferimento per la posizione blocca il thread corrente finché non completa l'elaborazione dell'immagine o del frame di input. Per evitare di bloccare l'interazione dell'utente, esegui l'elaborazione in un thread in background.
  • Quando è in esecuzione in modalità live streaming, l'attività Posa di riferimento restituisce immediatamente e non blocca il thread corrente. Richiama l'elenco dei risultati con il risultato del rilevamento ogni volta che termina l'elaborazione di un frame di input.

Nel codice di esempio del punto di riferimento per la posizione, le funzioni detect, detectForVideo e detectAsync sono definite nel file PoseLandmarkerHelper.kt.

Gestire e visualizzare i risultati

Il punto di riferimento per la posizione restituisce un oggetto poseLandmarkerResult per ogni esecuzione di rilevamento. L'oggetto risultato contiene le coordinate di ogni punto di riferimento per la posa.

Di seguito è riportato un esempio dei dati di output di questa attività:

PoseLandmarkerResult:
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : 0.129959
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
      visibility   : 0.999909
      presence     : 0.999958
    ... (33 landmarks per pose)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
      visibility   : 0.9999997615814209
      presence     : 0.9999984502792358
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
      visibility   : 0.999976
      presence     : 0.999998
    ... (33 world landmarks per pose)
  SegmentationMasks:
    ... (pictured below)

L'output contiene sia coordinate normalizzate (Landmarks) sia coordinate mondiali (WorldLandmarks) per ogni punto di riferimento.

L'output contiene le seguenti coordinate normalizzate (Landmarks):

  • x e y: coordinate dei punti di riferimento normalizzate tra 0,0 e 1,0 per la larghezza e l'altezza dell'immagine (x) (y).

  • z: la profondità importante, con la profondità al punto centrale dei fianchi come origine. Più basso è il valore, più il punto di riferimento è vicino alla fotocamera. L'entità di z utilizza all'incirca la stessa scala di x.

  • visibility: la probabilità che il punto di riferimento sia visibile all'interno dell'immagine.

L'output contiene le seguenti coordinate mondiali (WorldLandmarks):

  • x, y e z: coordinate tridimensionali nel mondo reale in metri, con il punto medio dei fianchi come origine.

  • visibility: la probabilità che il punto di riferimento sia visibile all'interno dell'immagine.

L'immagine seguente mostra una visualizzazione dell'output dell'attività:

La maschera di segmentazione facoltativa rappresenta la probabilità che ogni pixel appartenga a una persona rilevata. La seguente immagine è una maschera di segmentazione dell'output dell'attività:

Il codice di esempio del punto di riferimento per la posa mostra come visualizzare i risultati restituiti dall'attività. Per ulteriori dettagli, consulta la classe OverlayView.