Mit dem ML Kit können Sie Gesichter in Bildern und Videos erkennen.
Testen
- Probieren Sie die Beispiel-App aus, um sich ein Anwendungsbeispiel dieser API anzusehen.
- Probiere den Code selbst mit dem Codelab aus.
Hinweis
- Fügen Sie die folgenden ML Kit-Pods in Ihre Podfile ein:
pod 'GoogleMLKit/FaceDetection', '3.2.0'
- Nachdem Sie die Pods Ihres Projekts installiert oder aktualisiert haben, öffnen Sie das Xcode-Projekt mit dessen
.xcworkspace
. ML Kit wird ab Xcode Version 12.4 unterstützt.
Richtlinien für Eingabebilder
Für die Gesichtserkennung sollten Sie ein Bild mit einer Größe von mindestens 480 x 360 Pixeln verwenden. Damit ML Kit Gesichter richtig erkennen kann, müssen Eingabebilder Gesichter enthalten, die durch genügend Pixeldaten dargestellt werden. Im Allgemeinen sollte jedes Gesicht, das Sie in einem Bild erkennen möchten, mindestens 100 × 100 Pixel haben. Wenn die Konturen von Gesichtern erkannt werden sollen, ist für ML Kit eine hochauflösendere Eingabe erforderlich: 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 lassen sich schneller verarbeiten. So können Sie die Latenz reduzieren, indem Sie Bilder mit niedrigerer Auflösung aufnehmen. Beachten Sie jedoch die oben genannten Anforderungen an die Genauigkeit und achten Sie darauf, dass das Gesicht des Objekts so viel wie möglich einnimmt. Weitere Informationen finden Sie unter Tipps zur Verbesserung der Echtzeitleistung.
Ein schlechter Bildfokus kann sich auch auf die Genauigkeit auswirken. Wenn du keine akzeptablen Ergebnisse erhältst, bitte den Nutzer, das Bild noch einmal 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
Bevor Sie die Gesichtserkennung auf ein Bild anwenden, müssen Sie diese mit einemFaceDetectorOptions
-Objekt festlegen, wenn Sie eine der Standardeinstellungen des Gesichtserkennungssystems ändern möchten. Sie können die folgenden Einstellungen ändern:
Einstellungen | |
---|---|
performanceMode |
fast (Standard) | accurate
Bevorzugen Sie Geschwindigkeit oder Genauigkeit bei der Gesichtserkennung. |
landmarkMode |
none (Standard) | all
Gibt an, ob versucht wird, alle erkannten Gesichtsmerkmale wie Augen, Ohren, Nase, Wangen oder Mund zu erkennen. |
contourMode |
none (Standard) | all
Gibt an, ob die Konturen der Gesichtszüge erkannt werden sollen. Konturen werden nur für das auffälligste Gesicht in einem Bild erkannt. |
classificationMode |
none (Standard) | all
Gibt an, ob Gesichter in Kategorien klassifiziert werden sollen, z. B. „Lächeln“ oder „Augen geöffnet“. |
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 einer ID zugewiesen werden sollen, mit der Gesichter über Bilder hinweg verfolgt werden kann. Beachten Sie, dass bei aktivierter Konturerkennung nur ein Gesicht erkannt wird. Die Gesichtserkennung liefert also keine nützlichen Ergebnisse. Aus diesem Grund und zur Verbesserung der Erkennungsgeschwindigkeit sollten Sie nicht sowohl die Konturerkennung als auch die Gesichtsverfolgung aktivieren. |
Erstellen Sie beispielsweise ein FaceDetectorOptions
-Objekt wie eines der folgenden:
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
Um Gesichter in einem Bild zu erkennen, übergeben Sie das Bild alsUIImage
oder CMSampleBufferRef
mit der Methode process(_:completion:)
oder results(in:)
an FaceDetector
:
Erstellen Sie ein VisionImage
-Objekt mit einem UIImage
oder einem CMSampleBuffer
.
Wenn Sie UIImage
verwenden, gehen Sie so vor:
- Erstellen Sie ein
VisionImage
-Objekt mitUIImage
. Achten Sie darauf, die richtige.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 CMSampleBuffer
verwenden, gehen Sie so vor:
-
Gib die Ausrichtung der Bilddaten an, die in
CMSampleBuffer
enthalten sind.So erhalten Sie die Bildausrichtung:
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; } }
- Erstellen Sie ein
VisionImage
-Objekt mit dem ObjektCMSampleBuffer
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 dann das Bild an die Methodeprocess()
:
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 abrufen
Wenn die Gesichtserkennung erfolgreich ist, übergibt der Gesichtserkennungsassistent ein Array vonFace
-Objekten an den Abschluss-Handler. Jedes Face
-Objekt stellt ein Gesicht dar, das im Bild erkannt wurde. Für jedes Gesicht können Sie die Begrenzungskoordinaten im Eingabebild sowie alle anderen Informationen abrufen, die Sie anhand des Gesichtsdetektors ermittelt 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 Gesichtskonturerkennung aktiviert ist, wird für jedes erkannte Gesicht eine Liste mit Punkten angezeigt. Diese Punkte stellen die Form des Features dar. Weitere Informationen zur Darstellung von Konturen finden Sie unter Konzepte für die Gesichtserkennung.
In der folgenden Abbildung ist zu sehen, wie diese Punkte einem Gesicht zugeordnet sind. Klicken Sie auf das Bild, um es zu vergrößern:
Gesichtserkennung in Echtzeit
Wenn Sie die Gesichtserkennung in einer Echtzeitanwendung verwenden möchten, beachten Sie die folgenden Best Practices, um die besten Framerates zu erzielen:
Konfigurieren Sie den Gesichtserkennung so, dass entweder die Gesichtserkennung oder die Klassifizierung und die Erkennung von Sehenswürdigkeiten verwendet werden, aber nicht beides:
Konturerkennung
Erkennung von Sehenswürdigkeiten
Klassifizierung
Erkennung und Klassifizierung von Sehenswürdigkeiten
Konturerkennung und Sehenswürdigkeitenerkennung
Konturerkennung und -klassifizierung
Konturerkennung, Sehenswürdigkeiten und KlassifizierungModus „
fast
“ aktivieren (standardmäßig aktiviert).Bilder mit einer geringeren Auflösung aufnehmen Beachten Sie jedoch die Anforderungen an die Bildabmessungen dieser API.
- Verwenden Sie zur Verarbeitung von Videoframes die synchrone API des Detektors
results(in:)
. Rufen Sie diese Methode über diecaptureOutput(_, didOutput:from:)
-Funktion derAVCaptureVideoDataOutputSampleBufferDelegate
auf, um synchron Ergebnisse aus dem angegebenen Videoframe zu erhalten. Behalten SiealwaysDiscardsLateVideoFrames
vonAVCaptureVideoDataOutput
alstrue
bei, um Aufrufe an den Detektor zu drosseln. Wenn während der Ausführung des Detektors ein neuer Videoframe verfügbar ist, wird er verworfen. - Wenn Sie die Ausgabe des Detektors verwenden, um Grafiken auf dem Eingabebild einzublenden, rufen Sie zuerst das Ergebnis aus ML Kit ab und rendern dann das Bild und das Overlay in einem einzigen Schritt. Dadurch wird die Anzeige für jeden verarbeiteten Eingabeframe nur einmal auf der Anzeigeoberfläche gerendert. Ein Beispiel findest du in der Kurzanleitung zu updatePreviewOverlayViewWithLastFrame.