Leitfaden zur Gesichtserkennung für iOS

Mit der Aufgabe „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 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. In dieser Web-Demo 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 von MediaPipe Tasks ist eine einfache Implementierung einer Face Detector-App für iOS. In diesem 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 darauf zurückgreifen, wenn Sie eine vorhandene App ändern. 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/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 wichtigen Code für die Beispielanwendung „Gesichtserkennung“:

  • FaceDetectorService.swift: Initialisiert den Detektor, verarbeitet die Modellauswahl und führt eine Inferenz für die Eingabedaten aus.
  • CameraViewController: Implementiert die UI 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 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 iOS.

Abhängigkeiten

Face Detector verwendet die MediaPipeTasksVision-Bibliothek, die mit CocoaPods installiert werden muss. Die Bibliothek ist sowohl mit Swift- als auch mit Objective-C-Anwendungen 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 eines Podfile mit den erforderlichen Pods für Ihre Anwendung finden Sie unter CocoaPods verwenden.

Fügen Sie den MediaPipeTasksVision-Pod mit dem folgenden Code in Podfile ein:

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

Falls Ihre App Ziele für Einheitentests enthält, finden Sie im Einrichtungsleitfaden für iOS weitere Informationen zum Einrichten von Podfile.

Modell

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

Wählen Sie ein Modell aus, laden Sie es herunter und fügen Sie es Ihrem Projektverzeichnis mithilfe von Xcode hinzu. Eine Anleitung zum Hinzufügen von Dateien zu Ihrem Xcode-Projekt finden Sie unter Dateien und Ordner in einem 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 Initialisierungen aufrufen. Der FaceDetector(options:)-Initialisierer akzeptiert Werte für die Konfigurationsoptionen.

Wenn du keinen Gesichtsdetektor benötigst, der mit benutzerdefinierten Konfigurationsoptionen initialisiert wurde, kannst du mit dem FaceDetector(modelPath:)-Initialisierer einen Gesichtserkennung mit den Standardoptionen erstellen. Weitere Informationen zu Konfigurationsoptionen finden Sie in der Konfigurationsübersicht.

Die Gesichtserkennung unterstützt drei Eingabedatentypen: Standbilder, Videodateien und Live-Videostreams. Standardmäßig initialisiert FaceDetector(modelPath:) eine Aufgabe für Standbilder. Wenn Sie möchten, dass die Aufgabe zur Verarbeitung von Videodateien oder Live-Videostreams initialisiert wird, geben Sie den Video- oder Livestream-Ausführungsmodus mit FaceDetector(options:) an. Für den Livestream-Modus ist außerdem die zusätzliche Konfigurationsoption faceDetectorLiveStreamDelegate erforderlich, mit der Gesichtserkennungsergebnisse asynchron an den Bevollmächtigten gesendet werden können.

Wählen Sie den Tab für Ihren Ausführungsmodus aus, um zu erfahren, wie Sie die Aufgabe erstellen und die 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 Video- oder Livestream-Modus verwenden, nutzt Face Detector Tracking, um zu vermeiden, dass das Erkennungsmodell bei jedem Frame ausgelöst wird. Dadurch wird die Latenz reduziert.

Konfigurationsoptionen

Diese Aufgabe bietet die folgenden Konfigurationsoptionen für iOS-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.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.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

Livestream-Konfiguration

Wenn der Ausführungsmodus auf Livestream festgelegt ist, benötigt der Gesichtserkennung die zusätzliche Konfigurationsoption faceDetectorLiveStreamDelegate, damit der Gesichtserkennungsergebnis asynchron Ergebnisse liefern kann. Der Bevollmächtigte implementiert die Methode faceDetector(_:didFinishDetection:timestampInMilliseconds:error:), die der Gesichtsdetektor nach der Verarbeitung der Gesichtserkennungsergebnisse für jeden Frame aufruft.

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

Daten vorbereiten

Sie müssen das Eingabebild oder den Eingabeframe in ein MPImage-Objekt konvertieren, bevor Sie es an den Face Detector übergeben. MPImage unterstützt verschiedene Arten von iOS-Bildformaten und kann in jedem Ausführungsmodus für die Inferenz verwendet werden. Weitere Informationen zu MPImage finden Sie in der MPImage API.

Wählen Sie ein iOS-Bildformat basierend auf Ihrem Anwendungsfall und dem Ausführungsmodus Ihrer Anwendung aus.MPImage akzeptiert die iOS-Bildformate UIImage, CVPixelBuffer und CMSampleBuffer.

UIImage

Das Format UIImage eignet sich gut für die folgenden Ausführungsmodi:

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

  • Videos: Extrahieren Sie Videoframes mit AVAssetImageGenerator in das CGImage und konvertieren Sie sie dann in UIImage-Bilder.

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 ein MPImage mit der Standardausrichtung UIImage.Orientation.Up initialisiert. Sie können ein MPImage mit jedem der unterstützten UIImage.Orientation-Werte initialisieren. Die Gesichtserkennung unterstützt keine gespiegelten Ausrichtungen wie .upMirrored, .downMirrored, .leftMirrored, .rightMirrored.

Weitere Informationen zu UIImage finden Sie in der Apple-Entwicklerdokumentation UIImage.

CVPixelBuffer

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

Das Format CVPixelBuffer eignet sich gut für die folgenden Ausführungsmodi:

  • Bilder: Apps, die nach einer gewissen Verarbeitung mit dem CoreImage-Framework von iOS CVPixelBuffer-Bilder generieren, können im Bildausführungsmodus an den Gesichtsdetektor gesendet werden.

  • Videos: Videoframes können zur Verarbeitung in das Format CVPixelBuffer konvertiert und dann im Videomodus an den Face Detector gesendet werden.

  • Livestream: Apps, bei denen Frames mit einer iOS-Kamera erstellt werden, können zur Verarbeitung in das CVPixelBuffer-Format konvertiert werden, bevor sie im Livestream-Modus an den Gesichtserkennungsmelder 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.

CMSampleBuffer

Im Format CMSampleBuffer werden Medienbeispiele eines einheitlichen Medientyps gespeichert. Es eignet sich gut für den Livestream-Ausführungsmodus. Live-Frames von iOS-Kameras werden von iOS AVCaptureVideoDataOutput asynchron im CMSampleBuffer-Format übertragen.

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 von Apple.

Task ausführen

Verwenden Sie zum Ausführen des Gesichtsdetektors die für den zugewiesenen Ausführungsmodus spezifische detect()-Methode:

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

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

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

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];
    

Das Codebeispiel für die Gesichtserkennung zeigt die Implementierungen der einzelnen Modi im Detail: detect(image:), detect(videoFrame:timestampInMilliseconds:) und detectAsync(image:timestampInMilliseconds:). Mit dem Beispielcode können Nutzer zwischen den Verarbeitungsmodi wechseln, die für Ihren Anwendungsfall möglicherweise nicht erforderlich sind.

Wichtige Hinweise:

  • Im Video- oder Livestream-Modus müssen Sie auch den Zeitstempel des Eingabe-Frames an die Face Detector-Aufgabe übergeben.

  • Im Bild- oder Videomodus blockiert die Gesichtserkennungsaufgabe den aktuellen Thread, bis die Verarbeitung des Eingabebilds oder ‐frames abgeschlossen ist. Damit der aktuelle Thread nicht blockiert wird, führen Sie die Verarbeitung mithilfe von iOS Dispatch- oder NSOperation-Frameworks in einem Hintergrundthread aus.

  • Im Livestream-Modus wird die Gesichtserkennungsaufgabe sofort zurückgegeben und der aktuelle Thread nicht blockiert. Nach der Verarbeitung jedes Eingabeframes wird die Methode faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) mit dem Ergebnis der Gesichtserkennung aufgerufen. Der Gesichtserkennung ruft diese Methode in einer dedizierten seriellen Weiterleitungswarteschlange asynchron auf. Leiten Sie die Ergebnisse nach der Verarbeitung an die Hauptwarteschlange zur Anzeige der Ergebnisse auf der Benutzeroberfläche weiter. Wenn die Funktion detectAsync aufgerufen wird, während die Gesichtserkennungsaufgabe mit der Verarbeitung eines anderen Frames beschäftigt ist, ignoriert der Gesichtserkennung den neuen Eingabeframe.

Ergebnisse verarbeiten und anzeigen

Beim Ausführen der Inferenz gibt die Gesichtserkennungsaufgabe 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)

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 Ergebnisse angezeigt werden. Weitere Informationen finden Sie im Codebeispiel.