Puedes usar ML Kit para detectar rostros en imágenes y videos.
Probar
- Prueba la app de ejemplo para ver un ejemplo de uso de esta API.
- Prueba el código con el codelab.
Antes de comenzar
- Incluye los siguientes pods del ML Kit en tu Podfile:
pod 'GoogleMLKit/FaceDetection', '3.2.0'
- Después de instalar o actualizar los Pods de tu proyecto, abre el proyecto de Xcode con su
.xcworkspace
. El ML Kit es compatible con Xcode 12.4 o versiones posteriores.
Lineamientos para imágenes de entrada
Para el reconocimiento facial, debes usar una imagen con una dimensión de al menos 480 × 360 píxeles. Para que el Kit de AA detecte rostros con precisión, las imágenes de entrada deben contener rostros representados con datos de píxeles suficientes. En general, cada rostro que quieras detectar en una imagen debe tener al menos 100 x 100 píxeles. Si quieres detectar el contorno de los rostros, el ML Kit requiere una entrada de mayor resolución: cada rostro debe tener al menos 200 x 200 píxeles.
Si detectas rostros en una aplicación en tiempo real, te recomendamos que también consideres las dimensiones generales de las imágenes de entrada. Las imágenes más pequeñas se pueden procesar más rápido. Por lo tanto, para reducir la latencia, captura imágenes con resoluciones más bajas, pero ten en cuenta los requisitos de precisión que se mencionaron antes y asegúrate de que el rostro del sujeto ocupe la mayor parte de la imagen posible. Consulta también las sugerencias para mejorar el rendimiento en tiempo real.
Un enfoque de imagen deficiente también puede afectar la exactitud. Si no obtienes resultados aceptables, pídele al usuario que vuelva a capturar la imagen.
La orientación de un rostro en relación con la cámara también puede afectar las características que detecta el ML Kit. Consulta Conceptos de detección de rostro.
1. Configura el detector de rostros
Antes de aplicar la detección de rostro a una imagen, especifica la configuración con un objetoFaceDetectorOptions
si quieres modificar la configuración predeterminada del detector de rostros. Puedes cambiar las siguientes opciones de configuración:
Configuración | |
---|---|
performanceMode |
fast (predeterminado) | accurate
Da prioridad a la velocidad o a la precisión en la detección de rostros. |
landmarkMode |
none (predeterminado) | all
Indica si se debe intentar detectar "puntos de referencia" faciales (ojos, orejas, nariz, mejillas, boca) de todos los rostros detectados. |
contourMode |
none (predeterminado) | all
Indica si se deben detectar los contornos de los rasgos faciales. Solo se detectan los contornos de los rostros más destacados de una imagen. |
classificationMode |
none (predeterminado) | all
Indica si se deben clasificar los rostros en categorías como "sonriente" y "ojos abiertos". |
minFaceSize |
CGFloat (predeterminado: 0.1 )
Configura el tamaño de rostro más pequeño que desees, expresado como la proporción entre el ancho de la cabeza y el ancho de la imagen. |
isTrackingEnabled |
false (predeterminado) | true
Indica si se deben asignar ID a los rostros, que se pueden usar para hacer un seguimiento de los rostros en distintas imágenes. Ten en cuenta que, cuando la detección de contorno está habilitada, solo se detectará un rostro, por lo que el seguimiento de rostros no producirá resultados útiles. Por este motivo, y para mejorar la velocidad de detección, no habilites la detección de contorno y el seguimiento de rostros a la vez. |
Por ejemplo, compila un objeto FaceDetectorOptions
como uno de los ejemplos siguientes:
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. Prepara la imagen de entrada
Para detectar rostros en una imagen, pasa la imagen comoUIImage
o CMSampleBufferRef
a FaceDetector
usando el método process(_:completion:)
o results(in:)
:
Crea un objeto VisionImage
mediante una UIImage
o CMSampleBuffer
.
Si usas un UIImage
, sigue estos pasos:
- Crea un objeto
VisionImage
con laUIImage
. Asegúrate de especificar el.orientation
correcto.Swift
let image = VisionImage(image: UIImage) visionImage.orientation = image.imageOrientation
Objective‑C
MLKVisionImage *visionImage = [[MLKVisionImage alloc] initWithImage:image]; visionImage.orientation = image.imageOrientation;
Si usas un CMSampleBuffer
, sigue estos pasos:
-
Especifica la orientación de los datos de imagen que contiene
CMSampleBuffer
.Para obtener la orientación de la imagen, haz lo siguiente:
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; } }
- Crea un objeto
VisionImage
con el objetoCMSampleBuffer
y la orientación: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. Obtén una instancia de FaceDetector
Obtén una instancia de FaceDetector
:
Swift
let faceDetector = FaceDetector.faceDetector(options: options)
Objective‑C
MLKFaceDetector *faceDetector = [MLKFaceDetector faceDetectorWithOptions:options];
4. Procesa la imagen
Por último, pasa la imagen al métodoprocess()
:
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. Obtén información sobre los rostros detectados
Si la operación de detección de rostro se ejecuta correctamente, el detector de rostros pasará un arreglo de objetosFace
al controlador de finalización. Cada objeto Face
representa un rostro que se detectó en la imagen. Para cada rostro, puedes obtener las coordenadas de sus límites en la imagen de entrada, junto con cualquier otra información que encuentre el detector de rostros según la configuración que le asignaste. Por ejemplo:
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; } }
Ejemplo de contornos de rostro
Cuando la detección de contorno de rostro se encuentra habilitada, obtienes una lista de puntos por cada rasgo facial que se detectó. Estos puntos representan la forma del componente. Consulta Conceptos de detección de rostros para obtener más información sobre cómo se representan los contornos.
En la siguiente imagen, se ilustra cómo se asignan estos puntos a un rostro. Haz clic en la imagen para ampliarla:
Detección de rostro en tiempo real
Si quieres usar la detección de rostro en una aplicación en tiempo real, sigue estos lineamientos para lograr la mejor velocidad de fotogramas:
Configura el detector de rostros para usar la detección de contorno facial o la clasificación y detección de puntos de referencia, pero no ambos:
Detección de contorno
Detección de puntos de referencia
Clasificación
Detección y clasificación de puntos de referencia
Detección de contorno y de puntos de referencia
Detección y clasificación de contornos
Detección de contorno y de puntos de referencia, y clasificaciónHabilita el modo
fast
(habilitado de forma predeterminada).Considera capturar imágenes con una resolución más baja. Sin embargo, también ten en cuenta los requisitos de dimensiones de imágenes de esta API.
- Para procesar fotogramas de video, usa la API síncrona
results(in:)
del detector. Llama a este método desde la funcióncaptureOutput(_, didOutput:from:)
deAVCaptureVideoDataOutputSampleBufferDelegate
para obtener resultados de un fotograma de video determinado de manera síncrona. Mantén elalwaysDiscardsLateVideoFrames
deAVCaptureVideoDataOutput
comotrue
para limitar las llamadas al detector. Si hay un fotograma de video nuevo disponible mientras se ejecuta el detector, se descartará. - Si usas la salida del detector para superponer gráficos en la imagen de entrada, primero obtén el resultado del ML Kit y, luego, procesa la imagen y la superposición en un solo paso. De esta manera, renderizas en la superficie de visualización solo una vez por cada fotograma de entrada procesado. Consulta updatePreviewOverlayViewWithLastFrame en la muestra de inicio rápido del Kit de AA para ver un ejemplo.