Leitfaden zur Gesichtserkennung für Android

Mit der Aufgabe „MediaPipe-Gesichtserkennung“ können Sie Gesichter in einem Bild oder Video erkennen. Sie können diese Aufgabe verwenden, um Gesichter und Gesichtsmerkmale innerhalb eines Rahmens zu finden. Bei dieser Aufgabe wird ein Modell für maschinelles Lernen (ML) verwendet, das mit einzelnen Bildern oder einem kontinuierlichen Bilderstrom arbeitet. Die Aufgabe gibt Gesichterpositionen zusammen mit den folgenden wichtigen Gesichtspunkten aus: linkes Auge, rechtes Auge, Nasenspitze, Mund, Tragion des linken Auges und Tragion des rechten Auges.

Das in dieser Anleitung beschriebene Codebeispiel ist auf GitHub verfügbar. Weitere Informationen zu den Funktionen, Modellen und Konfigurationsoptionen dieser Aufgabe finden Sie in der Übersicht.

Codebeispiel

Der Beispielcode von MediaPipe Tasks ist eine einfache Implementierung einer Face Detector-App für Android. In diesem Beispiel wird die Kamera eines Android-Geräts verwendet, um Gesichter in einem kontinuierlichen Videostream zu erkennen. Die App kann auch Gesichter in Bildern und Videos aus der Gerätegalerie erkennen.

Du kannst die App als Ausgangspunkt für deine eigene Android-App verwenden oder beim Modifizieren einer vorhandenen App darauf zurückgreifen. Der Beispielcode für die Gesichtserkennung wird auf GitHub gehostet.

Code herunterladen

In der folgenden Anleitung erfahren Sie, wie Sie mit dem git-Befehlszeilentool eine lokale Kopie des Beispielcodes erstellen.

So laden Sie den Beispielcode herunter:

  1. Klonen Sie das Git-Repository mit dem folgenden Befehl:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Konfigurieren Sie optional die Git-Instanz für die Verwendung von Sparse Checkout, sodass Sie nur die Dateien für die Face Detector-Beispielanwendung haben:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_detector/android
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie das Projekt in Android Studio importieren und die App ausführen. Eine Anleitung dazu finden Sie im Einrichtungsleitfaden für Android.

Schlüsselkomponenten

Die folgenden Dateien enthalten den wichtigen Code für diese Beispielanwendung für die Gesichtserkennung:

  • FaceDetectorHelper.kt: Initialisiert den Gesichtserkennung und übernimmt das Modell und die delegierte Auswahl.
  • CameraFragment.kt: Bearbeitet die Kamera des Geräts und verarbeitet die Bild- und Videoeingabedaten.
  • GalleryFragment.kt: Interagiert mit OverlayView, um das Ausgabebild oder -video anzuzeigen.
  • OverlayView.kt: Implementiert die Anzeige mit Begrenzungsrahmen für erkannte Gesichter.

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten der Entwicklungsumgebung und Codeprojekte speziell für die Verwendung von Face Detector beschrieben. Allgemeine Informationen zum Einrichten der Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich der Anforderungen an die Plattformversion, finden Sie im Einrichtungsleitfaden für Android.

Abhängigkeiten

Für die Aufgabe „Gesichtserkennung“ wird die Bibliothek com.google.mediapipe:tasks-vision verwendet. Füge diese Abhängigkeit in die Datei build.gradle deiner Android-App ein:

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

Modell

Für die Aufgabe „MediaPipe-Gesichtserkennung“ ist ein Bundle mit trainiertem Modell erforderlich, das mit dieser Aufgabe kompatibel ist. Weitere Informationen zu verfügbaren trainierten Modellen für Face Detector finden Sie in der Aufgabenübersicht im Abschnitt „Modelle“.

Wählen Sie das Modell aus, laden Sie es herunter und speichern Sie es in Ihrem Projektverzeichnis:

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

Geben Sie den Pfad des Modells innerhalb des Parameters ModelAssetPath an. Im Beispielcode wird das Modell in der Datei FaceDetectorHelper.kt definiert:

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

Aufgabe erstellen

Die Aufgabe „MediaPipe Face Detector“ verwendet die Funktion createFromOptions(), um die Aufgabe einzurichten. Die Funktion createFromOptions() akzeptiert Werte für die Konfigurationsoptionen. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfigurationsoptionen.

Face Detector unterstützt die folgenden Eingabedatentypen: Standbilder, Videodateien und Live-Videostreams. Beim Erstellen der Aufgabe müssen Sie den Ausführungsmodus angeben, der Ihrem Eingabedatentyp entspricht. Wählen Sie den Tab für Ihren Eingabedatentyp aus, um zu sehen, wie die Aufgabe erstellt und die Inferenz ausgeführt werden soll.

Bild

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)
    

Livestream

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)
    

Mit der Implementierung des Beispielcodes für Face Detector kann der Nutzer zwischen den Verarbeitungsmodi wechseln. Dadurch wird der Code zur Aufgabenerstellung komplizierter und ist für Ihren Anwendungsfall möglicherweise nicht geeignet. Sie finden diesen Code in der Funktion setupFaceDetector() in der Datei FaceDetectorHelper.kt.

Konfigurationsoptionen

Diese Aufgabe umfasst die folgenden Konfigurationsoptionen für Android-Apps:

Option Beschreibung Wertebereich Standardwert
runningMode Legt den Ausführungsmodus für die Task fest. Es gibt drei Modi:

IMAGE: Der Modus für Einzelbildeingaben.

VIDEO: Der Modus für decodierte Frames eines Videos.

LIVE_STREAM: Der Modus für einen Livestream der Eingabedaten, z. B. von einer Kamera. In diesem Modus muss resultListener aufgerufen werden, um einen Listener einzurichten, der die Ergebnisse asynchron empfängt.
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
minDetectionConfidence Der Mindestkonfidenzwert, mit dem die Gesichtserkennung als erfolgreich gilt. Float [0,1] 0.5
minSuppressionThreshold Der minimale nicht maximale Grenzwert für die Gesichtserkennung, der als überlappend eingestuft wird. Float [0,1] 0.3
resultListener Legt den Ergebnis-Listener so fest, dass er die Erkennungsergebnisse asynchron empfängt, wenn sich der Gesichtserkennung im Livestreammodus befindet. Kann nur verwendet werden, wenn der Ausführungsmodus auf LIVE_STREAM festgelegt ist. N/A Not set
errorListener Legt einen optionalen Fehler-Listener fest. N/A Not set

Daten vorbereiten

Die Gesichtserkennung funktioniert mit Bildern, Videodateien und Live-Videostreams. Die Aufgabe übernimmt die Vorverarbeitung der Dateneingabe, einschließlich Größenanpassung, Rotation und Wertnormalisierung.

Der folgende Code zeigt, wie Daten zur Verarbeitung übergeben werden. Diese Beispiele enthalten Details zum Umgang mit Daten aus Bildern, Videodateien und Live-Videostreams.

Bild

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()
    

Livestream

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()
    

Im Beispielcode für die Gesichtserkennung wird die Datenvorbereitung in der Datei FaceDetectorHelper.kt ausgeführt.

Task ausführen

Verwenden Sie je nach Datentyp, mit dem Sie arbeiten, die Methode faceDetector.detect...() für diesen Datentyp. Verwenden Sie detect() für einzelne Bilder, detectForVideo() für Frames in Videodateien und detectAsync() für Videostreams. Wenn Sie Erkennungsvorgänge in einem Videostream durchführen, sollten Sie die Erkennung in einem separaten Thread ausführen, damit der Thread der Benutzeroberfläche nicht blockiert wird.

Die folgenden Codebeispiele enthalten einfache Beispiele dafür, wie Face Detector in diesen verschiedenen Datenmodi ausgeführt wird:

Bild

val result = faceDetector.detect(mpImage)
    

Video

val timestampMs = i * inferenceIntervalMs

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

Livestream

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

faceDetector.detectAsync(mpImage, frameTime)
    

Wichtige Hinweise:

  • Im Video- oder Livestreammodus musst du der Gesichtserkennungsaufgabe den Zeitstempel des Eingabeframes mitteilen.
  • Im Bild- oder Videomodus blockiert die Gesichtserkennungsaufgabe den aktuellen Thread, bis die Verarbeitung des Eingabebilds oder ‐frames abgeschlossen ist. Führen Sie die Verarbeitung in einem Hintergrundthread aus, damit die Benutzeroberfläche nicht blockiert wird.
  • Im Livestreammodus wird die Gesichtserkennungsaufgabe sofort zurückgegeben und der aktuelle Thread nicht blockiert. Der Ergebnis-Listener wird mit dem Erkennungsergebnis aufgerufen, sobald ein Eingabe-Frame verarbeitet wurde. Wenn die Erkennungsfunktion aufgerufen wird, während die Gesichtserkennung mit der Verarbeitung eines weiteren Frames beschäftigt ist, ignoriert die Aufgabe den neuen Eingabeframe.

Im Beispielcode für die Gesichtserkennung werden die Funktionen detect, detectForVideo und detectAsync in der Datei FaceDetectorHelper.kt definiert.

Ergebnisse verarbeiten und anzeigen

Der Gesichtserkennung gibt für jeden Erkennungslauf ein FaceDetectorResult-Objekt zurück. Das Ergebnisobjekt enthält Begrenzungsrahmen für die erkannten Gesichter und einen Konfidenzwert für jedes erkannte Gesicht.

Im Folgenden sehen Sie ein Beispiel für die Ausgabedaten dieser Aufgabe:

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)

Die folgende Abbildung zeigt eine Visualisierung der Aufgabenausgabe:

Informationen für das Bild ohne Begrenzungsrahmen finden Sie im Originalbild.

Der Beispielcode für Face Detector zeigt, wie die von der Aufgabe zurückgegebenen Ergebnisse angezeigt werden. Weitere Informationen finden Sie in der Klasse OverlayView.