Guida al rilevamento dei punti di riferimento della mano per Android

L'attività Punto di riferimento della mano di MediaPipe consente di rilevare i punti di riferimento delle mani in un'immagine. Queste istruzioni mostrano come utilizzare la funzione Tappa della mano con le app per Android. La l'esempio di codice descritto in queste istruzioni è disponibile 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 riferimento a mano per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare continuamente i punti di riferimento delle mani e utilizzare anche immagini e video galleria di dispositivi per rilevare in modo statico i punti di riferimento delle mani.

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 d'esempio di Hand 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 l'istanza Git in modo da utilizzare il pagamento sparso, in modo da avere solo i file per l'app di esempio di Riferimento Mano:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/hand_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, vedi Guida alla configurazione per Android.

Componenti chiave

I seguenti file contengono il codice fondamentale per questo punto di riferimento della mano di rilevamento dell'applicazione di esempio:

  • HandLandmarkerHelper.kt - Inizializza il rilevatore di punti di riferimento della mano e gestisce il modello e il delegato selezione.
  • MainActivity.kt: Implementa l'applicazione, inclusa la chiamata a HandLandmarkerHelper.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e per creare un modello di codice specifico per l'uso di Hand riferimentoer. 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 Guida alla configurazione per Android.

Dipendenze

L'attività Riferimento mano utilizza l'com.google.mediapipe:tasks-vision libreria. Aggiungi questa dipendenza al file build.gradle della tua app per Android:

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

Modello

L'attività Indicatore della mano di MediaPipe richiede un bundle di modelli addestrato che siano compatibili con questa attività. Per maggiori informazioni sui modelli addestrati disponibili per la funzione di riferimento della mano, 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 esempio di codice, Il modello è definito nel campo HandLandmarkerHelper.kt file:

baseOptionBuilder.setModelAssetPath(MP_HAND_LANDMARKER_TASK)

Crea l'attività

L'attività Punto di riferimento della mano 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, consulta Opzioni di configurazione.

La funzione Tapis roulant supporta tre tipi di dati di input: immagini fisse, file video e in live streaming. Devi specificare la modalità di corsa corrispondente di input durante la creazione dell'attività. Scegli la scheda corrispondente tipo di dati di input per vedere come creare l'attività ed eseguire l'inferenza.

Immagine

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

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

Video

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

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

Live streaming

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

val optionsBuilder =
    HandLandmarker.HandLandmarkerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setNumHands(maxNumHands)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

handLandmarker =
    HandLandmarker.createFromOptions(context, options)
    

L'implementazione del codice di esempio di Hand Taper consente all'utente di passare da 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 setupHandLandmarker() HandLandmarkerHelper.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
numHands Il numero massimo di mani rilevate dal rilevatore dei punti di riferimento della mano. Any integer > 0 1
minHandDetectionConfidence Il punteggio di confidenza minimo per il rilevamento della mano considerata efficace nel modello di rilevamento della palma. 0.0 - 1.0 0.5
minHandPresenceConfidence Il punteggio di confidenza minimo per il punteggio relativo alla presenza della mano nella mano modello di rilevamento dei punti di riferimento. In modalità Video e Live streaming: se il punteggio di confidenza della presenza della mano dal modello di punto di riferimento della mano è inferiore a questa soglia, la funzione di riferimento della mano attiva il modello di rilevamento della mano. Altrimenti, un algoritmo leggero di rilevamento della mano determina la posizione le mani per i successivi rilevamenti dei punti di riferimento. 0.0 - 1.0 0.5
minTrackingConfidence Il punteggio di confidenza minimo per cui deve essere preso in considerazione il monitoraggio della mano riuscito. Questa è la soglia di IoU del riquadro di delimitazione tra le mani nella il frame corrente e l'ultimo. In modalità Video e Stream di Punto di riferimento mano, se il rilevamento non va a buon fine, si attiva la mano il rilevamento automatico. In caso contrario, il rilevamento della mano viene saltato. 0.0 - 1.0 0.5
resultListener Imposta il listener dei risultati in modo che riceva i risultati del rilevamento in modo asincrono quando l'indicatore della mano è in modalità live streaming. Applicabile solo quando la modalità di corsa è impostata su LIVE_STREAM N/D N/D
errorListener Imposta un listener di errori facoltativo. N/D N/D

Preparazione dei dati

Mano del punto di riferimento funziona con immagini, file video e video in live streaming. 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. Tesi 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()
    

Nella nel codice di esempio di Vertex AI, la preparazione dei dati viene gestita HandLandmarkerHelper.kt .

Esegui l'attività

A seconda del tipo di dati con cui stai lavorando, utilizza HandLandmarker.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 il thread dell'interfaccia utente.

Gli esempi di codice riportati di seguito mostrano semplici esempi di come eseguire HandRuner in queste diverse modalità dati:

Immagine

val result = handLandmarker?.detect(mpImage)
    

Video

val timestampMs = i * inferenceIntervalMs

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

Live streaming

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

handLandmarker?.detectAsync(mpImage, frameTime)
    

Tieni presente quanto segue:

  • Quando è attiva la modalità video o live streaming, devi anche fornisce il timestamp del frame di input all'attività Punti di riferimento mano.
  • Quando viene eseguita in modalità immagine o video, l'attività Indicatore della mano bloccare il thread corrente finché non termina di elaborare l'immagine di input o frame. Per evitare di bloccare l'interfaccia utente, esegui l'elaborazione in una in background.
  • Quando viene eseguita in modalità live streaming, l'attività Riferimento mano non blocca il thread corrente, ma restituisce immediatamente. Richiamerà il suo risultato con il risultato del rilevamento ogni volta che termina l'elaborazione di un frame di input. Se la funzione di rilevamento viene chiamata quando viene eseguita l'attività è impegnato a elaborare un altro frame, l'attività ignorerà il nuovo frame di input.

Nella Codice di esempio di Hand Joiner, detect, detectForVideo e Le funzioni detectAsync sono definite HandLandmarkerHelper.kt .

Gestire e visualizzare i risultati

La funzione di riferimento della mano genera un oggetto risultato del dispositivo di riferimento della mano per ogni rilevamento vengono eseguiti tutti i test delle unità. L'oggetto risultato contiene punti di riferimento a mano nelle coordinate dell'immagine, mano punti di riferimento nelle coordinate del mondo e mano(mano sinistra/destra) dell' mani.

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

L'output HandLandmarkerResult contiene tre componenti. Ogni componente è un array, in cui ogni elemento contiene i seguenti risultati per una singola mano rilevata:

  • Mano dominante

    La mano indica se le mani rilevate sono mani sinistra o destra.

  • Punti di riferimento

    Ci sono 21 punti di riferimento a mano, ognuno composto da coordinate x, y e z. La Le coordinate di x e y sono normalizzate a [0,0, 1,0] in base alla larghezza dell'immagine e rispettivamente per l'altezza e l'altezza. La coordinata z rappresenta la profondità del punto di riferimento, con la profondità al polso rappresenta l'origine. Più basso è il valore, più vicino sarà è la fotocamera. La grandezza di z utilizza più o meno la stessa scala di x.

  • Punti di riferimento mondiali

    I punti di riferimento con 21 mani sono anche presentati in coordinate mondiali. Ogni punto di riferimento è composto da x, y e z, che rappresentano le coordinate 3D del mondo reale metri con l'origine al centro geometrico della mano.

HandLandmarkerResult:
  Handedness:
    Categories #0:
      index        : 0
      score        : 0.98396
      categoryName : Left
  Landmarks:
    Landmark #0:
      x            : 0.638852
      y            : 0.671197
      z            : -3.41E-7
    Landmark #1:
      x            : 0.634599
      y            : 0.536441
      z            : -0.06984
    ... (21 landmarks for a hand)
  WorldLandmarks:
    Landmark #0:
      x            : 0.067485
      y            : 0.031084
      z            : 0.055223
    Landmark #1:
      x            : 0.063209
      y            : -0.00382
      z            : 0.020920
    ... (21 world landmarks for a hand)

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

Il codice d'esempio di Mano del punto di riferimento illustra come visualizzare i risultati restituiti dall'attività, controlla OverlayView per ulteriori dettagli.