Vous pouvez utiliser ML Kit pour détecter les visages dans des images et des vidéos.
Essayer
- Testez l'application exemple pour voir un exemple d'utilisation de cette API.
- Essayez de coder vous-même dans cet atelier de programmation.
Avant de commencer
- Incluez les pods ML Kit suivants dans votre Podfile :
pod 'GoogleMLKit/FaceDetection', '3.2.0'
- Après avoir installé ou mis à jour les pods de votre projet, ouvrez votre projet Xcode à l'aide de son fichier
.xcworkspace
. ML Kit est compatible avec Xcode 12.4 ou version ultérieure.
Consignes pour les images d'entrée
Pour la reconnaissance faciale, vous devez utiliser une image d'au moins 480 x 360 pixels. Pour que ML Kit puisse détecter avec précision les visages, les images d'entrée doivent contenir des visages représentés par un volume de données de pixels suffisant. En règle générale, la taille de chaque visage à détecter dans une image doit être d'au moins 100 x 100 pixels. Si vous souhaitez détecter les contours de visages, ML Kit nécessite une entrée de résolution plus élevée: chaque face doit faire au moins 200 x 200 pixels.
Si vous détectez des visages dans une application en temps réel, vous pouvez également prendre en compte les dimensions globales des images d'entrée. Les images de petite taille peuvent être traitées plus rapidement. Pour réduire la latence, capturez des images à des résolutions inférieures, mais gardez à l'esprit les exigences de précision ci-dessus et assurez-vous que le visage du sujet occupe autant de place que possible dans l'image. Consultez également nos conseils pour améliorer les performances en temps réel.
Une mise au point médiocre peut également avoir un impact sur la précision. Si vous n'obtenez pas de résultats acceptables, demandez à l'utilisateur de reprendre l'image.
L'orientation d'un visage par rapport à la caméra peut également avoir une incidence sur les caractéristiques faciales détectées par ML Kit. Consultez la page Concepts de détection de visages.
1. Configurer la détection de visages
Avant d'appliquer la détection des visages à une image, si vous souhaitez modifier l'un des paramètres par défaut du détecteur de visages, spécifiez-le avec un objetFaceDetectorOptions
. Vous pouvez modifier les paramètres suivants:
Paramètres | |
---|---|
performanceMode |
fast (par défaut) | accurate
Privilégiez la vitesse ou la précision lors de la détection des visages. |
landmarkMode |
none (par défaut) | all
Indique s'il faut tenter de détecter les points de repère faciaux (yeux, oreilles, nez, joues et bouche) de tous les visages détectés. |
contourMode |
none (par défaut) | all
Détecter ou non les contours des traits du visage Les contours ne sont détectés que pour le visage le plus proéminent dans une image. |
classificationMode |
none (par défaut) | all
Indique si les visages doivent être classés dans des catégories telles que "souriant" et "yeux ouverts". |
minFaceSize |
CGFloat (par défaut: 0.1 )
Définit la plus petite taille de visage souhaitée, exprimée sous la forme du rapport entre la largeur de la tête et la largeur de l'image. |
isTrackingEnabled |
false (par défaut) | true
Indique si les visages doivent être attribués ou non à un ID, qui peut être utilisé pour suivre les visages sur l'ensemble des images. Notez que lorsque la détection du contour est activée, un seul visage est détecté. Le suivi des visages ne génère donc pas de résultats utiles. C'est pourquoi, et afin d'améliorer la vitesse de détection, n'activez pas à la fois la détection du contour et le suivi des visages. |
Par exemple, créez un objet FaceDetectorOptions
comme dans l'un des exemples suivants:
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. Préparer l'image d'entrée
Pour détecter les visages dans une image, transmettez l'image en tant queUIImage
ou CMSampleBufferRef
à FaceDetector
à l'aide de la méthode process(_:completion:)
ou results(in:)
:
Créez un objet VisionImage
à l'aide d'un UIImage
ou d'un CMSampleBuffer
.
Si vous utilisez un UIImage
, procédez comme suit:
- Créez un objet
VisionImage
avecUIImage
. Veillez à spécifier le bon.orientation
.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective-C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Si vous utilisez un CMSampleBuffer
, procédez comme suit:
-
Spécifiez l'orientation des données d'image contenues dans le fichier
CMSampleBuffer
.Pour obtenir l'orientation de l'image:
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; } }
- Créez un objet
VisionImage
à l'aide de l'objetCMSampleBuffer
et de l'orientation: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. Obtenir une instance de FaceDetector
Obtenez une instance de FaceDetector
:
Swift
let faceDetector = FaceDetector.faceDetector(options: options)
Objective-C
MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
4. Traiter l'image
Transmettez ensuite l'image à la méthodeprocess()
:
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. Obtenir des informations sur les visages détectés
Si l'opération de détection de visages aboutit, le détecteur de visages transmet un tableau d'objetsFace
au gestionnaire d'achèvement. Chaque objet Face
représente un visage détecté dans l'image. Pour chaque visage, vous pouvez obtenir ses coordonnées de délimitation dans l'image d'entrée, ainsi que toute autre information que vous avez configurée par le détecteur de visages. Exemple :
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; } }
Exemple de contours du visage
Lorsque la détection du contour du visage est activée, vous obtenez une liste de points pour chaque caractéristique du visage détectée. Ces points représentent la forme de l'élément géographique. Pour en savoir plus sur la représentation des contours, consultez la page Concepts de détection de visages.
L'image suivante montre comment ces points correspondent à un visage. Cliquez sur l'image pour l'agrandir:
Détection des visages en temps réel
Si vous souhaitez utiliser la détection de visages dans une application en temps réel, suivez ces consignes pour obtenir les meilleures fréquences d'images:
Configurez le détecteur de visages pour qu'il utilise soit la détection du contour du visage, soit la classification et la détection des points de repère, mais pas les deux:
Détection de contours
Détection de points de repère
Classification
Détection et classification de points de repère
Détection de contours et détection de points de repère
Détection et classification de contours
Détection et classification de contoursActivez le mode
fast
(activé par défaut).Envisagez de capturer des images à une résolution inférieure. Toutefois, gardez également à l'esprit les exigences de cette API concernant les dimensions d'image.
- Pour traiter les images vidéo, utilisez l'API synchrone
results(in:)
du détecteur. Appelez cette méthode à partir de la fonctioncaptureOutput(_, didOutput:from:)
deAVCaptureVideoDataOutputSampleBufferDelegate
pour obtenir de manière synchrone les résultats de l'image vidéo donnée. Conservez la valeuralwaysDiscardsLateVideoFrames
deAVCaptureVideoDataOutput
définie surtrue
pour limiter les appels au détecteur. Si une nouvelle image vidéo devient disponible alors que le détecteur est en cours d'exécution, elle sera ignorée. - Si vous utilisez la sortie du détecteur pour superposer des graphiques sur l'image d'entrée, obtenez d'abord le résultat de ML Kit, puis affichez l'image et la superposition en une seule étape. Ainsi, vous n'effectuez le rendu sur la surface d'affichage qu'une seule fois pour chaque trame d'entrée traitée. Consultez la section updatePreviewOverlayViewWithLastFrame dans l'exemple de démarrage rapide de ML Kit pour en voir un exemple.