Guida al riconoscimento dei gesti per Android

L'attività Riconoscimento dei gesti di MediaPipe ti consente di riconoscere i gesti delle mani in tempo reale e fornisce i risultati dei gesti della mano riconosciuti e i punti di riferimento delle mani rilevate. Queste istruzioni ti mostrano come usare il riconoscimento gesti con le app per Android. L'esempio di codice descritto in queste istruzioni è disponibile su GitHub.

Puoi vedere questa attività in azione visualizzando la demo web. 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 di riconoscimento gesti per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare continuamente i gesti delle mani e può utilizzare anche immagini e video della galleria del dispositivo per rilevare in modo statico i gesti.

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 del Riconoscimento gesti è 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 il pagamento sparse, in modo da avere solo i file per l'app di esempio di riconoscimento gesti:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/gesture_recognizer/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 riconoscimento dei gesti della mano:

Configurazione

In questa sezione vengono descritti i passaggi fondamentali per configurare l'ambiente di sviluppo e codificare i progetti in modo specifico per l'utilizzo del riconoscimento gesti. 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à di riconoscimento gesti 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à Riconoscimento gesti MediaPipe richiede un bundle di modelli addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il riconoscimento dei gesti, consulta la sezione Modelli della panoramica delle 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 GestureRecognizerHelper.kt:

baseOptionBuilder.setModelAssetPath(MP_RECOGNIZER_TASK)

Creare l'attività

L'attività Riconoscimento gesti MediaPipe utilizza la funzione createFromOptions() per configurarla. La funzione createFromOptions() accetta valori per le opzioni di configurazione. Per ulteriori informazioni sulle opzioni di configurazione, consulta Opzioni di configurazione.

Il riconoscimento gesti supporta tre 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 corrispondente al tipo di dati di input per vedere come creare l'attività ed eseguire l'inferenza.

Immagine

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Video

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

Live streaming

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

val optionsBuilder =
    GestureRecognizer.GestureRecognizerOptions.builder()
        .setBaseOptions(baseOptions)
        .setMinHandDetectionConfidence(minHandDetectionConfidence)
        .setMinTrackingConfidence(minHandTrackingConfidence)
        .setMinHandPresenceConfidence(minHandPresenceConfidence)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()
gestureRecognizer =
    GestureRecognizer.createFromOptions(context, options)
    

L'implementazione di codice di esempio del riconoscimento dei gesti 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 setupGestureRecognizer() del file GestureRecognizerHelper.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
numHands Il numero massimo di mani può essere rilevato dall'GestureRecognizer. Any integer > 0 1
minHandDetectionConfidence Il punteggio di affidabilità minimo affinché il rilevamento della mano venga considerato efficace nel modello di rilevamento del palmo. 0.0 - 1.0 0.5
minHandPresenceConfidence Il punteggio di affidabilità minimo del punteggio della presenza di persone nel modello di rilevamento dei punti di riferimento della mano. In modalità Video e in live streaming del Riconoscimento gesti, se il punteggio di sicurezza della presenza della mano del modello del punto di riferimento della mano è inferiore a questa soglia, viene attivato il modello di rilevamento del palmo. Altrimenti, viene utilizzato un algoritmo di tracciamento della mano leggero per determinare la posizione delle lancette e del successivo rilevamento dei punti di riferimento. 0.0 - 1.0 0.5
minTrackingConfidence Il punteggio di affidabilità minimo affinché la registrazione della mano venga considerata riuscita. Si tratta della soglia IoU del riquadro di delimitazione tra le mani nel frame corrente e nell'ultimo frame. In modalità Video e in modalità stream del Riconoscimento di gesti, se il rilevamento non va a buon fine, quest'ultimo attiva il rilevamento delle mani. In caso contrario, il rilevamento della mano viene ignorato. 0.0 - 1.0 0.5
cannedGesturesClassifierOptions Opzioni per configurare il comportamento predefinito del classificatore di gesti. I gesti predefiniti sono ["None", "Closed_Fist", "Open_Palm", "Pointing_Up", "Thumb_Down", "Thumb_Up", "Victory", "ILoveYou"]
  • Impostazioni internazionali dei nomi visualizzati: le impostazioni internazionali da utilizzare per i nomi visualizzati specificati tramite gli eventuali metadati del modello TFLite.
  • Numero massimo di risultati: il numero massimo di risultati di classificazione con il punteggio più alto da restituire. Se < 0, verranno restituiti tutti i risultati disponibili.
  • Soglia di punteggio: il punteggio al di sotto dei quali i risultati vengono rifiutati. Se impostato su 0, verranno restituiti tutti i risultati disponibili.
  • Lista consentita delle categorie: la lista consentita dei nomi delle categorie. Se il campo non è vuoto, i risultati di classificazione la cui categoria non è presente in questo set verranno filtrati. Esclusiva a vicenda con la lista bloccata.
  • Lista bloccata categoria: la lista bloccata dei nomi di categoria. Se il campo non è vuoto, i risultati di classificazione la cui categoria rientra in questo set verranno filtrati. Esclusiva a vicenda con lista consentita.
    • Impostazioni internazionali dei nomi visualizzati: any string
    • N. massimo di risultati: any integer
    • Soglia punteggio: 0.0-1.0
    • Lista consentita della categoria: vector of strings
    • Lista bloccata categoria: vector of strings
    • Impostazioni internazionali dei nomi visualizzati: "en"
    • N. massimo di risultati: -1
    • Soglia punteggio: 0
    • Lista consentita della categoria: vuota
    • Lista bloccata categoria: vuota
    customGesturesClassifierOptions Opzioni per configurare il comportamento del classificatore di gesti personalizzati.
  • Impostazioni internazionali dei nomi visualizzati: le impostazioni internazionali da utilizzare per i nomi visualizzati specificati tramite gli eventuali metadati del modello TFLite.
  • Numero massimo di risultati: il numero massimo di risultati di classificazione con il punteggio più alto da restituire. Se < 0, verranno restituiti tutti i risultati disponibili.
  • Soglia di punteggio: il punteggio al di sotto dei quali i risultati vengono rifiutati. Se impostato su 0, verranno restituiti tutti i risultati disponibili.
  • Lista consentita delle categorie: la lista consentita dei nomi delle categorie. Se il campo non è vuoto, i risultati di classificazione la cui categoria non è presente in questo set verranno filtrati. Esclusiva a vicenda con la lista bloccata.
  • Lista bloccata categoria: la lista bloccata dei nomi di categoria. Se il campo non è vuoto, i risultati di classificazione la cui categoria rientra in questo set verranno filtrati. Esclusiva a vicenda con lista consentita.
    • Impostazioni internazionali dei nomi visualizzati: any string
    • N. massimo di risultati: any integer
    • Soglia punteggio: 0.0-1.0
    • Lista consentita della categoria: vector of strings
    • Lista bloccata categoria: vector of strings
    • Impostazioni internazionali dei nomi visualizzati: "en"
    • N. massimo di risultati: -1
    • Soglia punteggio: 0
    • Lista consentita della categoria: vuota
    • Lista bloccata categoria: vuota
    resultListener Imposta il listener dei risultati per ricevere i risultati della classificazione in modo asincrono quando il riconoscimento dei gesti è in modalità live streaming. Può essere utilizzato solo quando la modalità di esecuzione è impostata su LIVE_STREAM ResultListener N/A N/A
    errorListener Imposta un listener di errori facoltativo. ErrorListener N/A N/A

    Preparazione dei dati

    Il riconoscimento gesti funziona con immagini, file video e video in live streaming. 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 riconoscimento gesti, la preparazione dei dati viene gestita nel file GestureRecognizerHelper.kt.

    Esegui l'attività

    Il riconoscimento gesti utilizza le funzioni recognize, recognizeForVideo e recognizeAsync per attivare le inferenze. Per il riconoscimento dei gesti, ciò comporta il pre-elaborazione dei dati di input, il rilevamento delle mani nell'immagine, il rilevamento dei punti di riferimento delle mani e il riconoscimento del gesto della mano dai punti di riferimento.

    Il seguente codice mostra come eseguire l'elaborazione con il modello di attività. Questi esempi includono dettagli su come gestire i dati di immagini, file video e stream video in diretta.

    Immagine

    val result = gestureRecognizer?.recognize(mpImage)
        

    Video

    val timestampMs = i * inferenceIntervalMs
    
    gestureRecognizer?.recognizeForVideo(mpImage, timestampMs)
        ?.let { recognizerResult ->
            resultList.add(recognizerResult)
        }
        

    Live streaming

    val mpImage = BitmapImageBuilder(rotatedBitmap).build()
    val frameTime = SystemClock.uptimeMillis()
    
    gestureRecognizer?.recognizeAsync(mpImage, frameTime)
        

    Tieni presente quanto riportato di seguito:

    • Quando l'app è in modalità video o live streaming, devi anche fornire il timestamp del frame di input all'attività Riconoscimento gesti.
    • Quando viene eseguita in modalità immagine o video, l'attività Riconoscimento dei gesti bloccherà il thread corrente finché non avrà completato l'elaborazione dell'immagine o del frame di input. Per evitare di bloccare l'interfaccia utente, esegui l'elaborazione in un thread in background.
    • Quando è in esecuzione in modalità live streaming, l'attività Riconoscimento gesti non blocca il thread corrente, ma torna immediatamente. Richiama il proprio listener dei risultati con il risultato del riconoscimento ogni volta che ha terminato l'elaborazione di un frame di input. Se la funzione di riconoscimento viene richiamata quando l'attività di riconoscimento gesti è impegnata a elaborare un altro frame, l'attività ignorerà il nuovo frame di input.

    Nel codice di esempio del riconoscimento gesti, le funzioni recognize, recognizeForVideo e recognizeAsync sono definite nel file GestureRecognizerHelper.kt.

    Gestire e visualizzare i risultati

    Il riconoscimento gesti genera un oggetto risultato per il rilevamento dei gesti per ogni esecuzione di riconoscimento. L'oggetto risultato contiene punti di riferimento della mano nelle coordinate dell'immagine, punti di riferimento della mano nelle coordinate del mondo, mano(mano sinistra/destra) e gesti della mano nelle categorie delle mani rilevate.

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

    Il risultato GestureRecognizerResult contiene quattro componenti e ogni componente è un array in cui ogni elemento contiene il risultato rilevato di una singola mano rilevata.

    • Mano dominante

      La mano indica se la mano viene rilevata sia destra che sinistra.

    • Gesti

      Le categorie di gesti riconosciuti delle mani rilevate.

    • Punti di riferimento

      Ci sono 21 punti di riferimento della mano, ciascuno composto dalle coordinate x, y e z. Le coordinate x e y sono normalizzate su [0,0, 1,0] rispettivamente in base alla larghezza e all'altezza dell'immagine. La coordinata z rappresenta la profondità del punto di riferimento, dove la profondità al polso è l'origine. Più basso è il valore, più il punto di riferimento è vicino alla fotocamera. La grandezza di z utilizza approssimativamente la stessa scala di x.

    • Punti di riferimento mondiali

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

    GestureRecognizerResult:
      Handedness:
        Categories #0:
          index        : 0
          score        : 0.98396
          categoryName : Left
      Gestures:
        Categories #0:
          score        : 0.76893
          categoryName : Thumb_Up
      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)
    

    Le immagini seguenti mostrano una visualizzazione dell'output dell'attività:

    Nel codice di esempio del riconoscimento gesti, la classe GestureRecognizerResultsAdapter nel file GestureRecognizerResultsAdapter.kt gestisce i risultati.