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 por tu cuenta 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 a través de su
.xcworkspace
El Kit de AA 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 que están representados con datos de píxeles suficientes. En general, cada rostro que quieras para detectar en una imagen debe ser de, al menos, 100x100 píxeles. Si quieres detectar los contornos de los rostros, ML Kit requiere una entrada de mayor resolución: cada rostro debe ser de al menos 200x200 píxeles.
Si detectas rostros en una aplicación en tiempo real, también deberías para considerar las dimensiones generales de las imágenes de entrada. Las imágenes más pequeñas pueden procesan más rápido. Por lo tanto, para reducir la latencia, capturar imágenes con resoluciones más bajas, pero mantener tenga en cuenta los requisitos de exactitud anteriores y asegúrese de que la el rostro del sujeto ocupe la mayor parte posible de la imagen. Consulta también sugerencias para mejorar el rendimiento en tiempo real.
Un enfoque de imagen deficiente también puede afectar la precisión. Si no obtienes una puntuación aceptable solicítale 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 qué de atributos que detecta 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, si quieres cambiar alguna de las configuración predeterminada del detector de rostros, especifícalas con una ObjetoFaceDetectorOptions
. Puedes cambiar
los siguientes parámetros de configuración:
Configuración | |
---|---|
performanceMode |
fast (predeterminado) | accurate
Prefiere la velocidad o la precisión en la detección de rostros. |
landmarkMode |
none (predeterminado) | all
Si se debe intentar detectar "puntos de referencia" faciales: ojos, orejas, nariz, mejillas y boca, de todos los rostros detectados. |
contourMode |
none (predeterminado) | all
Indica si se deben detectar los contornos de rasgos faciales. Los contornos son detectada solo para el rostro más prominente en una imagen. |
classificationMode |
none (predeterminado) | all
Si se deben clasificar los rostros en categorías como "sonriente" y "ojos abiertos". |
minFaceSize |
CGFloat (valor predeterminado: 0.1 )
Establece el tamaño de rostro más pequeño deseado, expresado como la proporción de la ancho de la cabeza al 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. rostros entre las imágenes. Ten en cuenta que cuando la detección de contorno está habilitada, solo se ve un rostro detectada, por lo que el seguimiento de rostros no produce resultados útiles. Para este y para mejorar la velocidad de detección, no habilites ambas funciones y seguimiento de rostro. |
Por ejemplo, compila un FaceDetectorOptions
.
como uno de los siguientes ejemplos:
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 como un objetoUIImage
o
CMSampleBufferRef
a FaceDetector
con el
Método process(_:completion:)
o results(in:)
:
Crea un objeto VisionImage
con un objeto UIImage
o
CMSampleBuffer
Si usas un UIImage
, sigue estos pasos:
- Crea un objeto
VisionImage
conUIImage
. 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:
-
Especificar la orientación de los datos de imagen que se incluyen en la
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 elemento ObjetoCMSampleBuffer
y 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 pasa un array. de objetosFace
al controlador de finalización. Cada
El objeto Face
representa un rostro que se detectó en la imagen. Para
para cada rostro, puedes obtener las coordenadas de sus límites en la imagen de entrada, además de
y 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 está habilitada, obtienes una lista de puntos por cada rasgo facial que se detectó. Estos puntos representan la forma de la . Ver Rostro Conceptos de detección para obtener detalles sobre cómo se definen los contornos representados.
En la siguiente imagen, se muestra cómo se asignan estos puntos a un rostro, haz clic en el 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 pasos: pautas para lograr la mejor velocidad de fotogramas:
Configura el detector de rostros para que use detección de contorno facial o 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 contorno
Detección de contorno y de puntos de referencia, y clasificaciónHabilita el modo
fast
(habilitado de forma predeterminada).Intenta 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. Llamada este método desde el DeAVCaptureVideoDataOutputSampleBufferDelegate
La funcióncaptureOutput(_, didOutput:from:)
para obtener resultados de un video determinado de forma síncrona marco. Mantener deAVCaptureVideoDataOutput
alwaysDiscardsLateVideoFrames
comotrue
para limitar las llamadas al detector Si un nuevo cliente El fotograma estará disponible mientras se ejecute el detector, que se descartará. - Si usas la salida del detector para superponer gráficos la imagen de entrada, primero obtén el resultado del ML Kit y, luego, renderiza la imagen y superponerla en un solo paso. De esta manera, renderizas en la superficie de visualización. solo una vez por cada trama de entrada procesada. Consulta updatePreviewOverlayViewWithLastFrame. en la muestra de inicio rápido del Kit de AA para ver un ejemplo.