Guida al rilevamento dei punti di riferimento per Android

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

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

Esempio di codice

Il codice di esempio relativo alle attività di MediaPipe è una semplice implementazione di un Indicatore di posizioni per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare le posizioni in un video stream continuo. L'app può anche rilevare le pose di immagini e video dalla galleria del dispositivo.

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

Scarica il codice

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

Per scaricare il codice di esempio:

  1. Clona il repository git utilizzando il comando seguente:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Facoltativamente, configura la tua istanza Git per l'utilizzo di un pagamento sparso, in modo da avere solo i file per l'app di esempio Pose Highlighter:
    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 istruzioni, consulta la Guida alla configurazione per Android.

Componenti chiave

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

  • PoseLandmarkerHelper.kt: inizializza lo strumento di riferimento della posa e gestisce il modello e il delegato selezione.
  • CameraFragment.kt: gestisce la fotocamera del dispositivo ed elabora i dati di input dell'immagine e del video.
  • GalleryFragment.kt: interagisce con OverlayView per visualizzare l'immagine o il video di output.
  • OverlayView.kt: implementa la visualizzazione per le pose rilevate.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e che utilizzano specificatamente i progetti di codice per usare Pose Highlighter. Per informazioni generali su configurare l'ambiente di sviluppo per l'utilizzo delle attività di MediaPipe, tra cui: i requisiti di versione della piattaforma, consulta la Guida alla configurazione per Android.

Dipendenze

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

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

Modello

L'attività Pose Highlighter di MediaPipe richiede un bundle di modelli addestrato che siano compatibili con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per Pose Highlighter, consulta la sezione Modelli della panoramica delle attività.

Seleziona e scarica il modello e archivialo nella directory del progetto:

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

Specifica il percorso del modello all'interno del parametro ModelAssetPath. Nella di esempio, il modello viene definito PoseLandmarkerHelper.kt file:

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

Crea l'attività

L'attività Livello di riferimento di MediaPipe utilizza la funzione createFromOptions() per configurare dell'attività. La funzione createFromOptions() accetta i valori per la configurazione le opzioni di CPU e memoria disponibili. Per ulteriori informazioni sulle opzioni di configurazione, vedi Configurazione opzioni.

The Pose Taper supporta i seguenti tipi di dati di input: immagini fisse, video e stream video in diretta. Devi specificare la modalità di corsa corrispondenti al tipo di dati di input durante la creazione dell'attività. Scegli la scheda per il 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 del codice d'esempio di Pose Taper consente all'utente di passare da una modalità all'altra di elaborazione. L'approccio rende il codice di creazione delle attività più complicato potrebbero non essere appropriati per il tuo caso d'uso. Puoi trovare questo codice nel nella funzione setupPoseLandmarker() PoseLandmarkerHelper.kt .

Opzioni di configurazione

Questa attività include 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 tipi di modalità:

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

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

LIVE_STREAM: la modalità per un live streaming di input dati, ad esempio quelli di una videocamera. In questa modalità, resultListener deve essere per impostare un listener in modo che riceva risultati in modo asincrono.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numposes Il numero massimo di pose che possono essere rilevate dal Punto di riferimento per la posa. Integer > 0 1
minPoseDetectionConfidence Il punteggio di confidenza minimo per il rilevamento della posizione viene considerata riuscita. Float [0.0,1.0] 0.5
minPosePresenceConfidence Il punteggio di confidenza minimo della presenza della posa il punteggio nel rilevamento dei punti di riferimento della posizione. Float [0.0,1.0] 0.5
minTrackingConfidence Il punteggio di confidenza minimo per il monitoraggio della posizione per essere considerate efficaci. Float [0.0,1.0] 0.5
outputSegmentationMasks Consente di stabilire se mostrare o meno una maschera di segmentazione per l'oggetto rilevato posa. Boolean False
resultListener Imposta il listener dei risultati per ricevere i risultati dei punti di riferimento in modo asincrono quando l'app Luogo di riferimento è in modalità live streaming. Può essere utilizzato solo quando la modalità di corsa è impostata su LIVE_STREAM ResultListener N/A
errorListener Imposta un listener di errori facoltativo. ErrorListener N/A

Preparazione dei dati

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

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 video.

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 d'esempio di Pose Highlighter, la preparazione dei dati viene gestita nella PoseLandmarkerHelper.kt .

Esegui l'attività

A seconda del tipo di dati con cui stai lavorando, utilizza poseLandmarker.detect...() specifico per il tipo di dati. Utilizza le funzionalità di detect() per le singole immagini, detectForVideo() per i frame nei file video, e detectAsync() per gli stream video. Quando esegui rilevamenti su una nello stream video, assicurati di eseguire i rilevamenti su un thread separato per evitare bloccare l'utente e interporre il thread.

I seguenti esempi di codice mostrano semplici esempi di come eseguire Pose Highlighter in queste diverse modalità 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 segue:

  • Quando utilizzi la modalità video o live streaming, devi fornire i campi il timestamp del frame di input all'attività Punti di riferimento in posizioni.
  • Durante l'esecuzione in modalità immagine o video, l'attività Punti di riferimento si blocca sul thread corrente fino al termine dell'elaborazione dell'immagine o del frame di input. A evitare di bloccare l'interazione dell'utente, esegui l'elaborazione in background .
  • Quando viene eseguita in modalità live streaming, l'attività Punti di riferimento restituisce l'attività immediatamente e non blocca il thread corrente. Richiamerà il risultato con il risultato del rilevamento ogni volta che termina l'elaborazione di un frame di input.

Nel codice di esempio di Pose Taper, detect, detectForVideo e Le funzioni detectAsync sono definite PoseLandmarkerHelper.kt .

Gestire e visualizzare i risultati

La funzione di riferimento per le posizioni restituisce un oggetto poseLandmarkerResult per ogni rilevamento vengono eseguiti tutti i test delle unità. L'oggetto risultato contiene le coordinate di ogni punto di riferimento di 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 le coordinate normalizzate (Landmarks) sia il mondo coordinate (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 in base al larghezza (x) e altezza (y) dell'immagine.

  • z: la profondità del punto di riferimento, con la profondità nel punto centrale dei fianchi come origine dati. Più basso è il valore, più il punto di riferimento è vicino alla fotocamera. La magnitude z utilizza più o meno 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 del mondo (WorldLandmarks):

  • x, y e z: coordinate 3dimensionali del mondo reale in metri, con parte centrale 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 ciascun pixel appartenga a una persona rilevata. Nell'immagine di seguito è riportata una maschera di segmentazione output dell'attività:

Il codice d'esempio di Pose Taper illustra come visualizzare i risultati restituiti dall'attività, controlla OverlayView per ulteriori dettagli.