Guida al rilevamento dei volti per Android

L'attività Rilevatore di volti MediaPipe consente di rilevare i volti in un'immagine o in un video. Puoi usare questa attività per individuare i volti e le caratteristiche del viso all'interno di un'inquadratura. Questa attività utilizza un modello di machine learning (ML) che funziona con immagini singole o un flusso continuo di immagini. L'attività restituisce la posizione del volto, oltre ai seguenti punti chiave del viso: occhio sinistro, occhio destro, punta del naso, bocca, tragione dell'occhio sinistro e tragione dell'occhio destro.

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 Face Detector per Android. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare i volti in uno stream video continuo. L'app può anche rilevare i volti 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 del rilevatore di volti è 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 l'istanza Git in modo da utilizzare il pagamento sparse, in modo da avere solo i file per l'app di esempio di Face Detector:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_detector/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 rilevamento dei volti:

  • FaceDetectorHelper.kt: inizializza il rilevatore dei volti, gestisce il modello e delega la selezione.
  • 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 con riquadri di delimitazione per i volti rilevati.

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 Face Detector. 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à Rilevatore di volti 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à Rilevamento viso MediaPipe richiede un bundle di modelli addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il rilevatore di volti, 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 FaceDetectorHelper.kt:

val modelName = "face_detection_short_range.tflite"
baseOptionsBuilder.setModelAssetPath(modelName)

Creare l'attività

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

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

Immagine

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.IMAGE)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

Video

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setRunningMode(RunningMode.VIDEO)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

Live streaming

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

val optionsBuilder =
    FaceDetector.FaceDetectorOptions.builder()
        .setBaseOptions(baseOptionsBuilder.build())
        .setMinDetectionConfidence(threshold)
        .setResultListener(this::returnLivestreamResult)
        .setErrorListener(this::returnLivestreamError)
        .setRunningMode(RunningMode.LIVE_STREAM)

val options = optionsBuilder.build()

FaceDetector =
    FaceDetector.createFromOptions(context, options)
    

L'implementazione di codice di esempio del rilevatore di volti 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 setupFaceDetector() del file FaceDetectorHelper.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
minDetectionConfidence Il punteggio di confidenza minimo affinché il rilevamento dei volti venga considerato efficace. Float [0,1] 0.5
minSuppressionThreshold La soglia minima non massima di soppressione per il rilevamento dei volti affinché venga considerato sovrapposto. Float [0,1] 0.3
resultListener Imposta il listener dei risultati per ricevere i risultati del rilevamento in modo asincrono quando il rilevatore di volti è in modalità live streaming. Può essere utilizzato solo quando la modalità di esecuzione è impostata su LIVE_STREAM. N/A Not set
errorListener Imposta un listener di errori facoltativo. N/A Not set

Preparazione dei dati

La funzionalità di rilevamento dei volti 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 rilevatore di volti, la preparazione dei dati viene gestita nel file FaceDetectorHelper.kt.

Esegui l'attività

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

I seguenti esempi di codice mostrano semplici esempi di come eseguire Rilevatore del volto in queste diverse modalità dati:

Immagine

val result = faceDetector.detect(mpImage)
    

Video

val timestampMs = i * inferenceIntervalMs

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

Live streaming

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

faceDetector.detectAsync(mpImage, frameTime)
    

Tieni presente quanto riportato di seguito:

  • Quando l'esecuzione è in modalità video o live streaming, devi fornire il timestamp del frame di input all'attività di rilevamento dei volti.
  • Quando viene eseguita in modalità immagine o video, l'attività di rilevamento dei volti blocca il thread corrente finché non completa 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à di riconoscimento facciale 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. Se la funzione di rilevamento viene richiamata quando l'attività di rilevamento dei volti è impegnata a elaborare un altro frame, l'attività ignorerà il nuovo frame di input.

Nel codice di esempio del rilevatore di volti, le funzioni detect, detectForVideo e detectAsync sono definite nel file FaceDetectorHelper.kt.

Gestire e visualizzare i risultati

Il rilevatore di volti restituisce un oggetto FaceDetectorResult per ogni esecuzione di rilevamento. L'oggetto risultato contiene riquadri di delimitazione per i volti rilevati e un punteggio di affidabilità per ciascun volto rilevato.

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

FaceDetectionResult:
  Detections:
    Detection #0:
      BoundingBox:
        origin_x: 126
        origin_y: 100
        width: 463
        height: 463
      Categories:
        Category #0:
          index: 0
          score: 0.9729152917861938
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.18298381567001343
          y: 0.2961040139198303
        NormalizedKeypoint #1:
          x: 0.3302789330482483
          y: 0.29289937019348145
        ... (6 keypoints for each face)
    Detection #1:
      BoundingBox:
        origin_x: 616
        origin_y: 193
        width: 430
        height: 430
      Categories:
        Category #0:
          index: 0
          score: 0.9251380562782288
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.6151331663131714
          y: 0.3713381886482239
        NormalizedKeypoint #1:
          x: 0.7460576295852661
          y: 0.38825345039367676
        ... (6 keypoints for each face)

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

Per l'immagine senza riquadri di delimitazione, vedi l'immagine originale.

Il codice di esempio di Rilevatore dei volti mostra come visualizzare i risultati restituiti dall'attività. Per ulteriori dettagli, consulta la classe OverlayView.