Leitfaden zur Gesichtserkennung für iOS

Mit der Aufgabe „Gesichtserkennung“ können Sie Gesichter in einem Bild oder Video erkennen. Mit dieser Aufgabe können Sie Gesichter und Gesichtsmerkmale in einem Frame finden. Für diese Aufgabe wird ein ML-Modell (Machine Learning) verwendet, das mit einzelnen Bildern oder einem kontinuierlichen Bildstream funktioniert. Die Aufgabe gibt die Gesichtspositionen sowie die folgenden wichtigen Gesichtsmerkmale 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. In dieser Webdemo können Sie sich diese Aufgabe in Aktion ansehen. Weitere Informationen zu den Funktionen, Modellen und Konfigurationsoptionen dieser Aufgabe finden Sie in der Übersicht.

Codebeispiel

Der Beispielcode für MediaPipe Tasks ist eine einfache Implementierung einer Gesichtserkennungs-App für iOS. Im Beispiel wird die Kamera eines physischen 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.

Sie können die App als Ausgangspunkt für Ihre eigene iOS-App verwenden oder sich an ihr orientieren, wenn Sie eine vorhandene App ändern. Der Beispielcode für die Gesichtserkennung wird auf GitHub gehostet.

Code herunterladen

In der folgenden Anleitung wird beschrieben, wie Sie mit dem Befehlszeilentool git 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. Optional können Sie Ihre Git-Instanz für die Verwendung einer spärlichen Überprüfung konfigurieren, sodass nur die Dateien für die Beispiel-App „Gesichtserkennung“ vorhanden sind:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_detector/ios/
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie die MediaPipe-Aufgabenbibliothek installieren, das Projekt mit Xcode öffnen und die App ausführen. Eine Anleitung finden Sie im Einrichtungsleitfaden für iOS.

Schlüsselkomponenten

Die folgenden Dateien enthalten den wichtigsten Code für die Beispielanwendung „Face Detector“:

  • FaceDetectorService.swift: Initialisiert den Detektor, verarbeitet die Modellauswahl und führt eine Inferenz auf den Eingabedaten aus.
  • CameraViewController: Implementiert die Benutzeroberfläche für den Eingabemodus des Live-Kamerafeeds und visualisiert die Erkennungsergebnisse.
  • MediaLibraryViewController.swift: Implementiert die Benutzeroberfläche für den Eingabemodus für Standbilder und Videodateien und visualisiert die Erkennungsergebnisse.

Einrichtung

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

Abhängigkeiten

Der Gesichtserkennungsdienst verwendet die MediaPipeTasksVision-Bibliothek, die mit CocoaPods installiert werden muss. Die Bibliothek ist sowohl mit Swift- als auch mit Objective-C-Apps kompatibel und erfordert keine zusätzliche sprachspezifische Einrichtung.

Eine Anleitung zur Installation von CocoaPods unter macOS finden Sie in der CocoaPods-Installationsanleitung. Eine Anleitung zum Erstellen einer Podfile mit den erforderlichen Pods für Ihre App finden Sie unter CocoaPods verwenden.

Fügen Sie den Pod „MediaPipeTasksVision“ in der Datei Podfile mit dem folgenden Code hinzu:

target 'MyFaceDetectorApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Wenn Ihre App Unit-Testziele enthält, finden Sie im Einrichtungsleitfaden für iOS weitere Informationen zur Einrichtung Ihrer Podfile.

Modell

Für die MediaPipe-Gesichtserkennungsaufgabe ist ein trainiertes Modell erforderlich, das mit dieser Aufgabe kompatibel ist. Weitere Informationen zu den verfügbaren trainierten Modellen für den Gesichtserkennungs-KI-Dienst finden Sie in der Aufgabenübersicht im Abschnitt „Modelle“.

Wählen Sie ein Modell aus, laden Sie es herunter und fügen Sie es mit Xcode Ihrem Projektverzeichnis hinzu. Eine Anleitung zum Hinzufügen von Dateien zu Ihrem Xcode-Projekt finden Sie unter Dateien und Ordner im Xcode-Projekt verwalten.

Verwenden Sie das Attribut BaseOptions.modelAssetPath, um den Pfad zum Modell in Ihrem App-Bundle anzugeben. Ein Codebeispiel finden Sie im nächsten Abschnitt.

Aufgabe erstellen

Sie können die Aufgabe „Gesichtserkennung“ erstellen, indem Sie einen ihrer Initialisierer aufrufen. Der FaceDetector(options:)-Initialisierer akzeptiert Werte für die Konfigurationsoptionen.

Wenn Sie keinen mit benutzerdefinierten Konfigurationsoptionen initialisierten Gesichtserkennungs-Detektor benötigen, können Sie mit der FaceDetector(modelPath:)-Initialisierung einen Gesichtserkennungs-Detektor mit den Standardoptionen erstellen. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfigurationsübersicht.

Die Aufgabe „Gesichtserkennung“ unterstützt drei Eingabedatentypen: Standbilder, Videodateien und Livestreams. Standardmäßig initialisiert FaceDetector(modelPath:) eine Aufgabe für Standbilder. Wenn Sie möchten, dass Ihre Aufgabe für die Verarbeitung von Videodateien oder Live-Videostreams initialisiert wird, geben Sie mit FaceDetector(options:) den Ausführungsmodus für Video oder Livestream an. Der Livestream-Modus erfordert außerdem die zusätzliche Konfigurationsoption faceDetectorLiveStreamDelegate, mit der die Gesichtserkennung Ergebnisse der Gesichtserkennung asynchron an den Bevollmächtigten senden kann.

Wählen Sie den Tab für Ihren Ausführungsmodus aus, um zu sehen, wie Sie die Aufgabe erstellen und eine Inferenz ausführen.

Swift

Bild

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image

let faceDetector = try FaceDetector(options: options)
    

Video

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video

let faceDetector = try FaceDetector(options: options)
    

Livestream

import MediaPipeTasksVision

// Class that conforms to the `FaceDetectorLiveStreamDelegate` protocol and
// implements the method that the face detector calls once it finishes
// detecting faces in each input frame.
class FaceDetectorResultProcessor: NSObject, FaceDetectorLiveStreamDelegate {

  func faceDetector(
    _ faceDetector: FaceDetector,
    didFinishDetection result: FaceDetectorResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the face detection result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream

// Assign an object of the class to the `faceDetectorLiveStreamDelegate`
// property.
let processor = FaceDetectorResultProcessor()
options.faceDetectorLiveStreamDelegate = processor

let faceDetector = try FaceDetector(options: options)
    

Objective-C

Bild

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

Livestream

@import MediaPipeTasksVision;

// Class that conforms to the `MPPFaceDetectorLiveStreamDelegate` protocol
// and implements the method that the face detector calls once it finishes
// detecting faces in each input frame.

@interface APPFaceDetectorResultProcessor : NSObject 

@end

@implementation APPFaceDetectorResultProcessor

-   (void)faceDetector:(MPPFaceDetector *)faceDetector
    didFinishDetectionWithResult:(MPPFaceDetectorResult *)faceDetectorResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the face detector result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;

// Assign an object of the class to the `faceDetectorLiveStreamDelegate`
// property.
APPFaceDetectorResultProcessor *processor = [APPFaceDetectorResultProcessor new];
options.faceDetectorLiveStreamDelegate = processor;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

Hinweis:Wenn Sie den Videomodus oder Livestreammodus verwenden, verwendet die Gesichtserkennung das Tracking, um zu vermeiden, dass das Erkennungsmodell bei jedem Frame ausgelöst wird. Dadurch wird die Latenz verringert.

Konfigurationsoptionen

Für diese Aufgabe stehen die folgenden Konfigurationsoptionen für iOS-Apps zur Verfügung:

Option Beschreibung Wertebereich Standardwert
runningMode Legt den Ausführungsmodus für die Aufgabe 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 von Eingabedaten, z. B. von einer Kamera. In diesem Modus muss resultListener aufgerufen werden, um einen Listener für den asynchronen Empfang von Ergebnissen einzurichten.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
minDetectionConfidence Der minimale Konfidenzwert, mit dem die Gesichtserkennung als erfolgreich gilt. Float [0,1] 0.5
minSuppressionThreshold Der Mindestgrenzwert für die Nicht-Maximalunterdrückung, bei dem die Gesichtserkennung als überlappend betrachtet wird. Float [0,1] 0.3

Livestreamkonfiguration

Wenn der Ausführungsmodus auf „Livestream“ festgelegt ist, benötigt der Gesichtserkennungsdienst die zusätzliche Konfigurationsoption faceDetectorLiveStreamDelegate. Dadurch kann der Dienst die Erkennungsergebnisse asynchron liefern. Der Delegate implementiert die Methode faceDetector(_:didFinishDetection:timestampInMilliseconds:error:), die der Gesichtserkennungsalgorithmus aufruft, nachdem die Ergebnisse der Gesichtserkennung für jeden Frame verarbeitet wurden.

Optionsname Beschreibung Wertebereich Standardwert
faceDetectorLiveStreamDelegate Ermöglicht es der Gesichtserkennung, Ergebnisse der Gesichtserkennung im Livestream-Modus asynchron zu erhalten. Die Klasse, deren Instanz auf dieses Attribut gesetzt wird, muss die Methode faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) implementieren. Nicht zutreffend Nicht festgelegt

Daten vorbereiten

Sie müssen das Eingabebild oder den Frame in ein MPImage-Objekt konvertieren, bevor Sie es an den Gesichtserkennungsalgorithmus übergeben. MPImage unterstützt verschiedene Arten von iOS-Bildformaten und kann sie in jedem Betriebsmodus für die Inferenz verwenden. Weitere Informationen zu MPImage finden Sie in der MPImage API.

Wählen Sie ein iOS-Bildformat entsprechend Ihrem Anwendungsfall und dem erforderlichen Ausführungsmodus Ihrer Anwendung aus.MPImage unterstützt die iOS-Bildformate UIImage, CVPixelBuffer und CMSampleBuffer.

UIImage

Das UIImage-Format eignet sich gut für die folgenden Laufmodi:

  • Bilder: Bilder aus einem App-Bundle, einer Nutzergalerie oder einem Dateisystem, das als UIImage-Bilder formatiert ist, können in ein MPImage-Objekt umgewandelt werden.

  • Videos: Mit dem AVAssetImageGenerator können Sie Videoframes im CGImage-Format extrahieren und dann in UIImage-Bilder konvertieren.

Swift

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(uiImage: image)
    

Objective-C

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

Im Beispiel wird eine MPImage mit der Standardausrichtung UIImage.Orientation.Up initialisiert. Sie können ein MPImage mit einem beliebigen der unterstützten Werte von UIImage.Orientation initialisieren. Die Gesichtserkennung unterstützt keine gespiegelten Ausrichtungen wie .upMirrored, .downMirrored, .leftMirrored oder .rightMirrored.

Weitere Informationen zu UIImage finden Sie in der Apple Developer-Dokumentation zu UIImage.

CVPixelBuffer

Das Format CVPixelBuffer eignet sich gut für Anwendungen, die Frames generieren und das iOS-Framework für CoreImage für die Verarbeitung verwenden.

Das CVPixelBuffer-Format eignet sich gut für die folgenden Laufmodi:

  • Bilder: Apps, die nach einer Verarbeitung mit dem CoreImage-Framework von iOS CVPixelBuffer-Bilder generieren, können im Modus „Bild ausführen“ an die Gesichtserkennung gesendet werden.

  • Videos: Videoframes können zur Verarbeitung in das CVPixelBuffer-Format konvertiert und dann im Videomodus an die Gesichtserkennung gesendet werden.

  • Livestream: Frames, die in Apps mit einer iOS-Kamera generiert werden, können zur Verarbeitung in das CVPixelBuffer-Format konvertiert werden, bevor sie im Livestream-Modus an die Gesichtserkennung gesendet werden.

Swift

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(pixelBuffer: pixelBuffer)
    

Objective-C

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

Weitere Informationen zu CVPixelBuffer findest du in der CVPixelBuffer-Entwicklerdokumentation von Apple.

CMSampleBuffer

Das Format CMSampleBuffer speichert Medienbeispiele eines einheitlichen Medientyps und eignet sich gut für den Livestream-Ausführungsmodus. Live-Frames von iOS-Kameras werden asynchron im CMSampleBuffer-Format von iOS AVCaptureVideoDataOutput bereitgestellt.

Swift

// Obtain a CMSampleBuffer.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(sampleBuffer: sampleBuffer)
    

Objective-C

// Obtain a `CMSampleBuffer`.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
    

Weitere Informationen zu CMSampleBuffer finden Sie in der Entwicklerdokumentation zu CMSampleBuffer Apple.

Aufgabe ausführen

Verwenden Sie zum Ausführen der Gesichtserkennung die Methode detect() für den zugewiesenen Laufmodus:

  • Standbild: detect(image:)
  • Video: detect(videoFrame:timestampInMilliseconds:)
  • Livestream: detectAsync(image:timestampInMilliseconds:)

Die Gesichtserkennung gibt die erkannten Gesichter im Eingabebild oder -frame zurück.

Die folgenden Codebeispiele zeigen einfache Beispiele für die Ausführung der Gesichtserkennung in diesen verschiedenen Ausführungsmodi:

Swift

Bild

let result = try faceDetector.detect(image: image)
    

Video

let result = try faceDetector.detect(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Livestream

try faceDetector.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Bild

MPPFaceDetectorResult *result = [faceDetector detectInImage:image
                                                      error:nil];
    

Video

MPPFaceDetectorResult *result = [faceDetector detectInVideoFrame:image
                                         timestampInMilliseconds:timestamp
                                                           error:nil];
    

Livestream

BOOL success = [faceDetector detectAsyncInImage:image
                        timestampInMilliseconds:timestamp
                                          error:nil];
    

Im Codebeispiel für den Gesichtserkennungs-Detektor werden die Implementierungen der einzelnen Modi detect(image:), detect(videoFrame:timestampInMilliseconds:) und detectAsync(image:timestampInMilliseconds:) genauer erläutert. Mit dem Beispielcode kann der Nutzer zwischen Verarbeitungsmodi wechseln, die für Ihren Anwendungsfall möglicherweise nicht erforderlich sind.

Wichtige Hinweise:

  • Wenn Sie die Funktion im Video- oder Livestream-Modus ausführen, müssen Sie der Aufgabe „Gesichtserkennung“ auch den Zeitstempel des Eingabeframes angeben.

  • Wenn die Funktion im Bild- oder Videomodus ausgeführt wird, blockiert die Aufgabe „Gesichtserkennung“ den aktuellen Thread, bis die Verarbeitung des Eingabebilds oder ‑frames abgeschlossen ist. Um das Blockieren des aktuellen Threads zu vermeiden, führen Sie die Verarbeitung in einem Hintergrund-Thread mithilfe der iOS-Frameworks Dispatch oder NSOperation aus.

  • Wenn die Erkennung im Livestream-Modus ausgeführt wird, gibt die Aufgabe „Gesichtserkennung“ sofort ein Ergebnis zurück und blockiert den aktuellen Thread nicht. Nach der Verarbeitung jedes Eingabeframes wird die Methode faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) mit dem Ergebnis der Gesichtserkennung aufgerufen. Der Gesichtserkennungsdienst ruft diese Methode asynchron in einer speziellen seriellen Dispatch-Warteschlange auf. Übermitteln Sie die Ergebnisse nach Verarbeitung der Ergebnisse an die Hauptwarteschlange, um sie auf der Benutzeroberfläche anzuzeigen. Wenn die detectAsync-Funktion aufgerufen wird, während die Aufgabe „Gesichtserkennung“ gerade einen anderen Frame verarbeitet, ignoriert die Gesichtserkennung den neuen Eingabeframe.

Ergebnisse verarbeiten und anzeigen

Nach der Ausführung der Inferenz gibt die Aufgabe „Gesichtserkennung“ ein FaceDetectorResult-Objekt zurück, das die Begrenzungsrahmen für die erkannten Gesichter und einen Konfidenzwert für jedes erkannte Gesicht enthält.

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)

Das folgende Bild zeigt eine Visualisierung der Aufgabenausgabe:

Das Bild ohne Begrenzungsrahmen finden Sie im Originalbild.

Der Beispielcode für die Gesichtserkennung zeigt, wie die Ergebnisse angezeigt werden. Weitere Informationen finden Sie im Codebeispiel.