Check out what’s new from Firebase at Google I/O 2022. Learn more

Erkennen Sie Gesichter mit ML Kit auf iOS

Sie können ML Kit verwenden, um Gesichter in Bildern und Videos zu erkennen.

Bevor Sie beginnen

  1. Wenn Sie Ihrer App Firebase noch nicht hinzugefügt haben, befolgen Sie dazu die Schritte im Leitfaden „Erste Schritte“ .
  2. Schließen Sie die ML Kit-Bibliotheken in Ihre Poddatei ein:
    pod 'Firebase/MLVision', '6.25.0'
    # If you want to detect face contours (landmark detection and classification
    # don't require this additional model):
    pod 'Firebase/MLVisionFaceModel', '6.25.0'
    
    Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, müssen Sie Ihr Xcode-Projekt mit seiner .xcworkspace .
  3. Importieren Sie in Ihrer App Firebase:

    Schnell

    import Firebase

    Ziel c

    @import Firebase;

Bildrichtlinien eingeben

Damit ML Kit Gesichter genau erkennen kann, müssen Eingabebilder Gesichter enthalten, die durch ausreichend Pixeldaten dargestellt werden. Im Allgemeinen sollte jedes Gesicht, das Sie in einem Bild erkennen möchten, mindestens 100 x 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 möglicherweise auch die Gesamtabmessungen der Eingabebilder berücksichtigen. Kleinere Bilder können schneller verarbeitet werden. Um die Latenz zu reduzieren, nehmen Sie Bilder mit niedrigeren Auflösungen auf (unter Berücksichtigung der oben genannten Genauigkeitsanforderungen) und stellen Sie sicher, dass das Gesicht des Motivs so viel wie möglich vom Bild einnimmt. Siehe auch Tipps zur Verbesserung der Echtzeitleistung .

Ein schlechter Bildfokus kann die Genauigkeit beeinträchtigen. Wenn Sie keine akzeptablen Ergebnisse erzielen, bitten Sie den Benutzer, das Bild erneut aufzunehmen.

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

1. Konfigurieren Sie den Gesichtsdetektor

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

Einstellungen
performanceMode fast (Standard) | accurate

Bevorzugen Sie Geschwindigkeit oder Genauigkeit bei der Erkennung von Gesichtern.

landmarkMode none (Standard) | all

Ob versucht werden soll, die „Wahrzeichen“ im Gesicht – Augen, Ohren, Nase, Wangen, Mund – aller erkannten Gesichter zu erkennen.

contourMode none (Standard) | all

Ob die Konturen von Gesichtszügen erkannt werden sollen. Konturen werden nur für das markanteste Gesicht in einem Bild erkannt.

classificationMode none (Standard) | all

Ob Gesichter in Kategorien wie „lächelnd“ und „offene Augen“ eingeteilt werden sollen oder nicht.

minFaceSize CGFloat (Standard: 0.1 )

Die Mindestgröße der zu erkennenden Gesichter im Verhältnis zum Bild.

isTrackingEnabled false (Standard) | true

Ob Gesichtern eine ID zugewiesen werden soll oder nicht, die verwendet werden kann, um Gesichter über Bilder hinweg zu verfolgen.

Beachten Sie, dass bei aktivierter Konturerkennung nur ein Gesicht erkannt wird, sodass die Gesichtsverfolgung keine brauchbaren Ergebnisse liefert. Aktivieren Sie aus diesem Grund und zur Verbesserung der Erkennungsgeschwindigkeit nicht sowohl die Konturerkennung als auch die Gesichtsverfolgung.

Erstellen Sie beispielsweise ein VisionFaceDetectorOptions Objekt wie in einem der folgenden Beispiele:

Schnell

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

// Real-time contour detection of multiple faces
let options = VisionFaceDetectorOptions()
options.contourMode = .all

Ziel c

// High-accuracy landmark detection and face classification
FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init];
options.performanceMode = FIRVisionFaceDetectorPerformanceModeAccurate;
options.landmarkMode = FIRVisionFaceDetectorLandmarkModeAll;
options.classificationMode = FIRVisionFaceDetectorClassificationModeAll;

// Real-time contour detection of multiple faces
FIRVisionFaceDetectorOptions *options = [[FIRVisionFaceDetectorOptions alloc] init];
options.contourMode = FIRVisionFaceDetectorContourModeAll;

2. Führen Sie den Gesichtsdetektor aus

Um Gesichter in einem Bild zu erkennen, übergeben Sie das Bild als UIImage oder CMSampleBufferRef an die Methode detect(in:) von VisionFaceDetector :

  1. Holen Sie sich eine Instanz von VisionFaceDetector :

    Schnell

    lazy var vision = Vision.vision()
    
    let faceDetector = vision.faceDetector(options: options)
    

    Ziel c

    FIRVision *vision = [FIRVision vision];
    FIRVisionFaceDetector *faceDetector = [vision faceDetector];
    // Or, to change the default settings:
    // FIRVisionFaceDetector *faceDetector =
    //     [vision faceDetectorWithOptions:options];
    
  2. Erstellen Sie ein VisionImage Objekt mit einem UIImage oder einem CMSampleBufferRef .

    So verwenden Sie ein UIImage :

    1. Drehen Sie das Bild bei Bedarf so, dass seine Eigenschaft imageOrientation .up .
    2. Erstellen Sie ein VisionImage -Objekt mit dem korrekt gedrehten UIImage . Geben Sie keine Rotationsmetadaten an – der Standardwert .topLeft muss verwendet werden.

      Schnell

      let image = VisionImage(image: uiImage)

      Ziel c

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithImage:uiImage];

    So verwenden Sie eine CMSampleBufferRef :

    1. Erstellen Sie ein VisionImageMetadata Objekt, das die Ausrichtung der im CMSampleBufferRef Puffer enthaltenen Bilddaten angibt.

      So erhalten Sie die Bildausrichtung:

      Schnell

      func imageOrientation(
          deviceOrientation: UIDeviceOrientation,
          cameraPosition: AVCaptureDevice.Position
          ) -> VisionDetectorImageOrientation {
          switch deviceOrientation {
          case .portrait:
              return cameraPosition == .front ? .leftTop : .rightTop
          case .landscapeLeft:
              return cameraPosition == .front ? .bottomLeft : .topLeft
          case .portraitUpsideDown:
              return cameraPosition == .front ? .rightBottom : .leftBottom
          case .landscapeRight:
              return cameraPosition == .front ? .topRight : .bottomRight
          case .faceDown, .faceUp, .unknown:
              return .leftTop
          }
      }

      Ziel c

      - (FIRVisionDetectorImageOrientation)
          imageOrientationFromDeviceOrientation:(UIDeviceOrientation)deviceOrientation
                                 cameraPosition:(AVCaptureDevicePosition)cameraPosition {
        switch (deviceOrientation) {
          case UIDeviceOrientationPortrait:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationLeftTop;
            } else {
              return FIRVisionDetectorImageOrientationRightTop;
            }
          case UIDeviceOrientationLandscapeLeft:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationBottomLeft;
            } else {
              return FIRVisionDetectorImageOrientationTopLeft;
            }
          case UIDeviceOrientationPortraitUpsideDown:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationRightBottom;
            } else {
              return FIRVisionDetectorImageOrientationLeftBottom;
            }
          case UIDeviceOrientationLandscapeRight:
            if (cameraPosition == AVCaptureDevicePositionFront) {
              return FIRVisionDetectorImageOrientationTopRight;
            } else {
              return FIRVisionDetectorImageOrientationBottomRight;
            }
          default:
            return FIRVisionDetectorImageOrientationTopLeft;
        }
      }

      Erstellen Sie dann das Metadatenobjekt:

      Schnell

      let cameraPosition = AVCaptureDevice.Position.back  // Set to the capture device you used.
      let metadata = VisionImageMetadata()
      metadata.orientation = imageOrientation(
          deviceOrientation: UIDevice.current.orientation,
          cameraPosition: cameraPosition
      )

      Ziel c

      FIRVisionImageMetadata *metadata = [[FIRVisionImageMetadata alloc] init];
      AVCaptureDevicePosition cameraPosition =
          AVCaptureDevicePositionBack;  // Set to the capture device you used.
      metadata.orientation =
          [self imageOrientationFromDeviceOrientation:UIDevice.currentDevice.orientation
                                       cameraPosition:cameraPosition];
    2. Erstellen Sie ein VisionImage Objekt mit dem CMSampleBufferRef Objekt und den Rotationsmetadaten:

      Schnell

      let image = VisionImage(buffer: sampleBuffer)
      image.metadata = metadata

      Ziel c

      FIRVisionImage *image = [[FIRVisionImage alloc] initWithBuffer:sampleBuffer];
      image.metadata = metadata;
  3. Übergeben Sie das Bild dann an die Methode detect(in:) :

    Schnell

    faceDetector.process(visionImage) { faces, error in
      guard error == nil, let faces = faces, !faces.isEmpty else {
        // ...
        return
      }
    
      // Faces detected
      // ...
    }
    

    Ziel c

    [faceDetector detectInImage:image
                     completion:^(NSArray<FIRVisionFace *> *faces,
                                  NSError *error) {
      if (error != nil) {
        return;
      } else if (faces != nil) {
        // Recognized faces
      }
    }];
    

3. Erhalten Sie Informationen über erkannte Gesichter

Wenn die Gesichtserkennungsoperation erfolgreich ist, übergibt der Gesichtsdetektor ein Array von VisionFace Objekten an den Abschluss-Handler. Jedes VisionFace Objekt stellt ein Gesicht dar, das im Bild erkannt wurde. Für jedes Gesicht können Sie seine Begrenzungskoordinaten im Eingabebild sowie alle anderen Informationen abrufen, die Sie für die Suche des Gesichtsdetektors konfiguriert haben. Beispielsweise:

Schnell

for face in faces {
  let frame = face.frame
  if face.hasHeadEulerAngleY {
    let rotY = face.headEulerAngleY  // Head is rotated to the right rotY degrees
  }
  if face.hasHeadEulerAngleZ {
    let rotZ = face.headEulerAngleZ  // Head is rotated upward 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
  }
}

Ziel c

for (FIRVisionFace *face in faces) {
  // Boundaries of face in image
  CGRect frame = face.frame;

  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):
  FIRVisionFaceLandmark *leftEar = [face landmarkOfType:FIRFaceLandmarkTypeLeftEar];
  if (leftEar != nil) {
    FIRVisionPoint *leftEarPosition = leftEar.position;
  }

  // If contour detection was enabled:
  FIRVisionFaceContour *upperLipBottomContour = [face contourOfType:FIRFaceContourTypeUpperLipBottom];
  if (upperLipBottomContour != nil) {
    NSArray<FIRVisionPoint *> *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 Sie die Gesichtskonturerkennung aktiviert haben, erhalten Sie eine Liste mit Punkten für jedes erkannte Gesichtsmerkmal. Diese Punkte repräsentieren die Form des Features. Einzelheiten zur Darstellung von Konturen finden Sie in der Übersicht über Gesichtserkennungskonzepte .

Das folgende Bild zeigt, wie diese Punkte einem Gesicht zugeordnet werden (zum Vergrößern auf das Bild klicken):

Gesichtserkennung in Echtzeit

Wenn Sie die Gesichtserkennung in einer Echtzeitanwendung verwenden möchten, befolgen Sie diese Richtlinien, um die besten Frameraten zu erzielen:

  • Konfigurieren Sie den Gesichtsdetektor so, dass er entweder die Gesichtskonturerkennung oder die Klassifizierung und Landmarkenerkennung verwendet, aber nicht beides:

    Konturerkennung
    Landmarkenerkennung
    Einstufung
    Orientierungspunkterkennung und -klassifizierung
    Konturerkennung und Landmarkenerkennung
    Konturerkennung und -klassifizierung
    Konturerkennung, Orientierungspunkterkennung und Klassifizierung

  • fast aktivieren (standardmäßig aktiviert).

  • Erwägen Sie, Bilder mit einer niedrigeren Auflösung aufzunehmen. Beachten Sie jedoch auch die Anforderungen an die Bildgröße dieser API.

  • Drosselrufe an den Detektor. Wenn ein neuer Videoframe verfügbar wird, während der Detektor läuft, löschen Sie den Frame.
  • Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf das Eingabebild zu legen, rufen Sie zuerst das Ergebnis von ML Kit ab, rendern Sie dann das Bild und überlagern Sie es in einem einzigen Schritt. Dadurch rendern Sie für jeden Eingabeframe nur einmal auf der Anzeigeoberfläche. Ein Beispiel finden Sie in den Klassen previewOverlayView und FIRDetectionOverlayView in der Showcase-Beispiel-App.