Gesichter mit ML Kit für iOS erkennen

Mit ML Kit können Sie Gesichter in Bildern und Videos erkennen.

Ausprobieren

  • Probieren Sie die Beispiel-App aus, um ein Beispiel für die Verwendung dieser API zu sehen.
  • Probieren Sie den Code mit dem Codelab selbst aus.

Hinweis

  1. Nehmen Sie die folgenden ML Kit-Pods in Ihre Podfile-Datei auf:
    pod 'GoogleMLKit/FaceDetection', '3.2.0'
    
  2. Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie Ihr Xcode-Projekt mit der zugehörigen .xcworkspace. ML Kit wird in Xcode ab Version 12.4 unterstützt.

Richtlinien für Eingabebilder

Für die Gesichtserkennung sollten Sie ein Bild mit einer Größe von mindestens 480 × 360 Pixeln verwenden. Damit ML Kit Gesichter genau erkennen kann, müssen die Eingabebilder Gesichter mit ausreichenden Pixeldaten enthalten. Im Allgemeinen sollte jedes Gesicht, das in einem Bild erkannt werden soll, mindestens 100 × 100 Pixel groß sein. Wenn Sie die Konturen von Gesichtern erkennen möchten, erfordert ML Kit eine Eingabe mit höherer Auflösung: Jedes Gesicht sollte mindestens 200 x 200 Pixel groß sein.

Wenn Sie Gesichter in einer Echtzeitanwendung erkennen, sollten Sie auch die Gesamtabmessungen der Eingabebilder berücksichtigen. Kleinere Bilder können schneller verarbeitet werden. Nehmen Sie daher Bilder mit niedrigeren Auflösungen auf, um die Latenz zu verringern. Beachten Sie jedoch die oben genannten Anforderungen an die Genauigkeit und achten Sie darauf, dass das Gesicht des Motivs so viel wie möglich einnimmt. Tipps zur Verbesserung der Echtzeitleistung

Ein schlechter Bildfokus kann auch die Genauigkeit beeinträchtigen. Wenn die Ergebnisse nicht akzeptabel sind, bitten Sie den Nutzer, ein neues Bild aufzunehmen.

Die Ausrichtung eines Gesichts relativ zur Kamera kann sich auch darauf auswirken, welche Gesichtsmerkmale ML Kit erkennt. Siehe Konzepte der Gesichtserkennung.

1. Gesichtserkennung konfigurieren

Wenn Sie die Standardeinstellungen des Gesichtserkennungsdienstes ändern möchten, bevor Sie die Gesichtserkennung auf ein Bild anwenden, geben Sie diese Einstellungen mit einem FaceDetectorOptions-Objekt an. Sie können die folgenden Einstellungen ändern:

Einstellungen
performanceMode fast (Standard) | accurate

Priorisieren Sie bei der Gesichtserkennung die Geschwindigkeit oder Genauigkeit.

landmarkMode none (Standard) | all

Gibt an, ob versucht werden soll, die "Sehenswürdigkeiten" im Gesicht – Augen, Ohren, Nase, Wangen, Mund – aller erkannten Gesichter zu erkennen.

contourMode none (Standard) | all

Gibt an, ob die Konturen von Gesichtsmerkmalen erkannt werden sollen. Es werden nur die Konturen des auffälligsten Gesichts erkannt.

classificationMode none (Standard) | all

Gibt an, ob Gesichter in Kategorien wie "Lächeln" oder "Offene Augen" klassifiziert werden sollen.

minFaceSize CGFloat (Standard: 0.1)

Legt die kleinste gewünschte Gesichtsgröße fest, ausgedrückt als Verhältnis der Breite des Kopfes zur Breite des Bildes.

isTrackingEnabled false (Standard) | true

Gibt an, ob Gesichter eine ID zugewiesen werden soll, mit der Gesichter bildübergreifend erfasst werden können.

Bei aktivierter Konturerkennung wird nur ein Gesicht erkannt und die Gesichtserkennung liefert keine nützlichen Ergebnisse. Aktivieren Sie aus diesem Grund und zur Verbesserung der Erkennungsgeschwindigkeit nicht gleichzeitig die Konturerkennung und die Gesichtserkennung.

Erstellen Sie beispielsweise ein FaceDetectorOptions-Objekt wie eines der folgenden Beispiele:

Swift

// High-accuracy landmark detection and face classification
let options = FaceDetectorOptions()
options.performanceMode = .accurate
options.landmarkMode = .all
options.classificationMode = .all

// Real-time contour detection of multiple faces
// options.contourMode = .all

Objective-C

// High-accuracy landmark detection and face classification
MLKFaceDetectorOptions *options = [[MLKFaceDetectorOptions alloc] init];
options.performanceMode = MLKFaceDetectorPerformanceModeAccurate;
options.landmarkMode = MLKFaceDetectorLandmarkModeAll;
options.classificationMode = MLKFaceDetectorClassificationModeAll;

// Real-time contour detection of multiple faces
// options.contourMode = MLKFaceDetectorContourModeAll;

2. Eingabebild vorbereiten

Übergeben Sie das Bild mit der Methode process(_:completion:) oder results(in:) als UIImage oder CMSampleBufferRef an FaceDetector, um Gesichter in einem Bild zu erkennen:

Erstellen Sie mit UIImage oder CMSampleBuffer ein VisionImage-Objekt.

Wenn Sie ein UIImage verwenden, gehen Sie so vor:

  • Erstellen Sie mit UIImage ein VisionImage-Objekt. Achten Sie darauf, den richtigen .orientation anzugeben.

    Swift

    let image = VisionImage(image: UIImage)
    visionImage.orientation = image.imageOrientation

    Objective-C

    MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image];
    visionImage.orientation = image.imageOrientation;

Wenn Sie ein CMSampleBuffer verwenden, gehen Sie so vor:

  • Gibt die Ausrichtung der Bilddaten an, die in CMSampleBuffer enthalten sind.

    So rufen Sie die Bildausrichtung ab:

    Swift

    func imageOrientation(
      deviceOrientation: UIDeviceOrientation,
      cameraPosition: AVCaptureDevice.Position
    ) -> UIImage.Orientation {
      switch deviceOrientation {
      case .portrait:
        return cameraPosition == .front ? .leftMirrored : .right
      case .landscapeLeft:
        return cameraPosition == .front ? .downMirrored : .up
      case .portraitUpsideDown:
        return cameraPosition == .front ? .rightMirrored : .left
      case .landscapeRight:
        return cameraPosition == .front ? .upMirrored : .down
      case .faceDown, .faceUp, .unknown:
        return .up
      }
    }
          

    Objective-C

    - (UIImageOrientation)
      imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                             cameraPosition:(AVCaptureDevicePosition)cameraPosition {
      switch (deviceOrientation) {
        case UIDeviceOrientationPortrait:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationLeftMirrored
                                                                : UIImageOrientationRight;
    
        case UIDeviceOrientationLandscapeLeft:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationDownMirrored
                                                                : UIImageOrientationUp;
        case UIDeviceOrientationPortraitUpsideDown:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationRightMirrored
                                                                : UIImageOrientationLeft;
        case UIDeviceOrientationLandscapeRight:
          return cameraPosition == AVCaptureDevicePositionFront ? UIImageOrientationUpMirrored
                                                                : UIImageOrientationDown;
        case UIDeviceOrientationUnknown:
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationFaceDown:
          return UIImageOrientationUp;
      }
    }
          
  • Erstelle ein VisionImage-Objekt mit dem Objekt CMSampleBuffer und der Ausrichtung:

    Swift

    let image = VisionImage(buffer: sampleBuffer)
    image.orientation = imageOrientation(
      deviceOrientation: UIDevice.current.orientation,
      cameraPosition: cameraPosition)

    Objective-C

     MLKVisionImage *image = [[MLKVisionImage alloc] initWithBuffer:sampleBuffer];
     image.orientation =
       [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                    cameraPosition:cameraPosition];

3. Instanz von FaceDetector abrufen

Rufen Sie eine Instanz von FaceDetector ab:

Swift

let faceDetector = FaceDetector.faceDetector(options: options)

Objective-C

MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
      

4. Bild verarbeiten

Übergeben Sie das Bild dann an die Methode process():

Swift

weak var weakSelf = self
faceDetector.process(visionImage) { faces, error in
  guard let strongSelf = weakSelf else {
    print("Self is nil!")
    return
  }
  guard error == nil, let faces = faces, !faces.isEmpty else {
    // ...
    return
  }

  // Faces detected
  // ...
}

Objective-C

[faceDetector processImage:image
                completion:^(NSArray<MLKFace *> *faces,
                             NSError *error) {
  if (error != nil) {
    return;
  }
  if (faces.count > 0) {
    // Recognized faces
  }
}];

5. Informationen zu erkannten Gesichtern erhalten

Wenn die Gesichtserkennung erfolgreich war, übergibt der Gesichtserkennung ein Array von Face-Objekten an den Abschluss-Handler. Jedes Face-Objekt repräsentiert ein Gesicht, das im Bild erkannt wurde. Für jedes Gesicht können Sie seine Begrenzungskoordinaten im Eingabebild sowie alle anderen Informationen abrufen, die Sie mit der Gesichtserkennung konfiguriert haben. Beispiel:

Swift

for face in faces {
  let frame = face.frame
  if face.hasHeadEulerAngleX {
    let rotX = face.headEulerAngleX  // Head is rotated to the uptoward rotX degrees
  }
  if face.hasHeadEulerAngleY {
    let rotY = face.headEulerAngleY  // Head is rotated to the right rotY degrees
  }
  if face.hasHeadEulerAngleZ {
    let rotZ = face.headEulerAngleZ  // Head is tilted sideways rotZ degrees
  }

  // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
  // nose available):
  if let leftEye = face.landmark(ofType: .leftEye) {
    let leftEyePosition = leftEye.position
  }

  // If contour detection was enabled:
  if let leftEyeContour = face.contour(ofType: .leftEye) {
    let leftEyePoints = leftEyeContour.points
  }
  if let upperLipBottomContour = face.contour(ofType: .upperLipBottom) {
    let upperLipBottomPoints = upperLipBottomContour.points
  }

  // If classification was enabled:
  if face.hasSmilingProbability {
    let smileProb = face.smilingProbability
  }
  if face.hasRightEyeOpenProbability {
    let rightEyeOpenProb = face.rightEyeOpenProbability
  }

  // If face tracking was enabled:
  if face.hasTrackingID {
    let trackingId = face.trackingID
  }
}

Objective-C

for (MLKFace *face in faces) {
  // Boundaries of face in image
  CGRect frame = face.frame;
  if (face.hasHeadEulerAngleX) {
    CGFloat rotX = face.headEulerAngleX;  // Head is rotated to the upward rotX degrees
  }
  if (face.hasHeadEulerAngleY) {
    CGFloat rotY = face.headEulerAngleY;  // Head is rotated to the right rotY degrees
  }
  if (face.hasHeadEulerAngleZ) {
    CGFloat rotZ = face.headEulerAngleZ;  // Head is tilted sideways rotZ degrees
  }

  // If landmark detection was enabled (mouth, ears, eyes, cheeks, and
  // nose available):
  MLKFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar];
  if (leftEar != nil) {
    MLKVisionPoint *leftEarPosition = leftEar.position;
  }

  // If contour detection was enabled:
  MLKFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom];
  if (upperLipBottomContour != nil) {
    NSArray<MLKVisionPoint *> *upperLipBottomPoints = upperLipBottomContour.points;
    if (upperLipBottomPoints.count > 0) {
      NSLog("Detected the bottom contour of the subject's upper lip.")
    }
  }

  // If classification was enabled:
  if (face.hasSmilingProbability) {
    CGFloat smileProb = face.smilingProbability;
  }
  if (face.hasRightEyeOpenProbability) {
    CGFloat rightEyeOpenProb = face.rightEyeOpenProbability;
  }

  // If face tracking was enabled:
  if (face.hasTrackingID) {
    NSInteger trackingID = face.trackingID;
  }
}

Beispiel für Gesichtskonturen

Wenn die Konturenerkennung aktiviert ist, erhalten Sie für jedes erkannte Gesichtsmerkmal eine Liste der Punkte. Diese Punkte geben die Form des Elements an. Weitere Informationen zur Darstellung von Konturen finden Sie unter Konzepte der Gesichtserkennung.

Die folgende Abbildung zeigt, wie diese Punkte einem Gesicht zugeordnet sind. Klicken Sie auf das Bild, um es zu vergrößern:

Beispiel eines erkannten Konturnetzes für ein Gesicht

Gesichtserkennung in Echtzeit

Wenn Sie die Gesichtserkennung in einer Echtzeitanwendung verwenden möchten, beachten Sie die folgenden Richtlinien, um die besten Framerates zu erzielen:

  • Konfigurieren Sie die Gesichtserkennung so, dass entweder die Gesichtskonturenerkennung oder die Klassifizierung und die Erkennung von Sehenswürdigkeiten verwendet werden, aber nicht beides:

    Konturerkennung
    Erkennung von Sehenswürdigkeiten
    Klassifizierung
    Erkennung von Sehenswürdigkeiten
    Konturerkennung und Sehenswürdigkeitenerkennung
    Konturerkennung und -klassifizierung
    Konturerkennung, Sehenswürdigkeitenerkennung und Klassifizierung

  • Aktivieren Sie den fast-Modus (standardmäßig aktiviert).

  • Nehmen Sie Bilder mit einer niedrigeren Auflösung auf. Beachten Sie jedoch auch die Anforderungen an die Bildabmessung dieser API.

  • Verwenden Sie zum Verarbeiten von Videobildern die synchrone results(in:)-API des Detektors. Rufen Sie diese Methode über die captureOutput(_, didOutput:from:)-Funktion von AVCaptureVideoDataOutputSampleBufferDelegate auf, um synchron Ergebnisse aus dem angegebenen Videoframe zu erhalten. Behalten Sie die alwaysDiscardsLateVideoFrames von AVCaptureVideoDataOutput als true bei, um Aufrufe an den Detektor zu drosseln. Wenn ein neuer Videoframe verfügbar wird, während der Detektor ausgeführt wird, wird er gelöscht.
  • Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken über das Eingabebild einzublenden, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern Sie dann das Bild und Overlay in einem einzigen Schritt. Dadurch wird für jeden verarbeiteten Eingabeframe nur einmal ein Rendering auf der Anzeigeoberfläche ausgeführt. Ein Beispiel finden Sie unter updatePreviewOverlayViewWithLastFrame im ML Kit-Schnellstartbeispiel.