Guida al rilevamento dei volti per Android

L'attività MediaPipe Face Detector consente di rilevare i volti in un'immagine o in un video. Puoi utilizzare questa attività per individuare volti e tratti del viso all'interno di un fotogramma. Questa attività utilizza un modello di machine learning (ML) che funziona con immagini singole o un flusso continuo di immagini. L'attività genera le posizioni del viso, insieme ai seguenti punti chiave del viso: occhio sinistro, occhio destro, punta del naso, bocca, tragio dell'occhio sinistro e tragio dell'occhio destro.

L'esempio di codice descritto in queste istruzioni è disponibile su GitHub. Per saperne di più 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 rilevamento dei volti 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 della 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 di Rilevamento volti è ospitato su GitHub.

Scarica il codice

Le istruzioni riportate di seguito 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. Se vuoi, configura l'istanza Git in modo da utilizzare il controllo sparse, in modo da avere solo i file per l'app di esempio 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 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 di volti e gestisce il modello e la selezione del delegato.
  • CameraFragment.kt: gestisce la videocamera 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 le caselle delimitanti per i volti rilevati.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e i progetti di codice specificamente per utilizzare Rilevamento volti. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'utilizzo delle attività MediaPipe, inclusi i requisiti della versione della piattaforma, consulta la guida alla configurazione per Android.

Dipendenze

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

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

Modello

L'attività Rilevamento volti di MediaPipe richiede un bundle di modelli addestrati compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per Rilevamento volti, consulta la sezione Modelli della panoramica dell'attività.

Seleziona e scarica il modello e memorizzalo nella 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)

Crea l'attività

L'attività MediaPipe Face Detector utilizza la funzione createFromOptions() per configurare l'attività. La funzione createFromOptions() accetta valori per le opzioni di configurazione. Per ulteriori informazioni sulle opzioni di configurazione, consulta Opzioni di configurazione.

Il Rilevamento di volti supporta i seguenti tipi di dati di input: immagini fisse, file video e streaming video dal vivo. Quando crei l'attività, devi specificare la modalità di esecuzione corrispondente al tipo di dati di input. Scegli la scheda corrispondente al tipo di dati di input per scoprire 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 del codice di esempio del Rilevamento di volti consente all'utente di passare da una modalità di elaborazione all'altra. L'approccio rende il codice di creazione delle attività più complicato 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à offre le seguenti opzioni di configurazione per le app per Android:

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

IMMAGINE: la modalità per l'inserimento 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 ascoltatore per ricevere i risultati in modo asincrono.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
minDetectionConfidence Il punteggio di attendibilità minimo per il rilevamento del volto considerato riuscito. Float [0,1] 0.5
minSuppressionThreshold La soglia minima di soppressione non massima per il rilevamento dei volti da considerare sovrapposti. Float [0,1] 0.3
resultListener Imposta l'ascoltatore dei risultati in modo da ricevere i risultati del rilevamento in modo asincrono quando il Rilevamento dei 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 errore facoltativo. N/A Not set

Preparazione dei dati

Rilevamento volti funziona con immagini, file video e live streaming video. L'attività gestisce la preelaborazione dei dati di input, tra cui ridimensionamento, rotazione e 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 streaming di video live.

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 di Face Detector, la preparazione dei dati viene gestita nel file FaceDetectorHelper.kt.

Esegui l'attività

A seconda del tipo di dati con cui stai lavorando, utilizza il metodo faceDetector.detect...() specifico per quel tipo di dati. Utilizza detect() per le singole immagini, detectForVideo() per i fotogrammi nei file video e detectAsync() per gli stream video. Quando esegui i rilevamenti su un spostamento video, assicurati di eseguirli in un thread separato per evitare di bloccare il thread dell'interfaccia utente.

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

  • Quando esegui l'operazione in modalità video o live streaming, devi fornire il timestamp del frame di input all'attività Rilevamento volti.
  • Quando viene eseguita in modalità immagine o video, l'attività Rilevamento volti blocca il thread corrente fino al termine dell'elaborazione dell'immagine o del frame di input. Per evitare di bloccare l'interfaccia utente, esegui l'elaborazione in un THREAD in background.
  • Quando viene eseguito in modalità live streaming, il compito del Rilevamento volti ritorna immediatamente e non blocca il thread corrente. Evocherà l'ascoltatore dei risultati con il risultato del rilevamento ogni volta che termina l'elaborazione di un frame di input. Se la funzione di rilevamento viene chiamata quando il compito del Rilevamento dei volti è impegnato a elaborare un altro frame, il compito ignorerà il nuovo frame di input.

Nel codice di esempio di Rilevamento 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 del rilevamento. L'oggetto risultato contiene i riquadri di delimitazione per i volti rilevati e un voto di affidabilità per ogni 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à:

Due bambini con i contorni dei volti

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

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