Detecta rostros con ML Kit en iOS

Puedes usar ML Kit para detectar rostros en imágenes y videos.

Probar

Antes de comenzar

  1. Incluye los siguientes pods del ML Kit en tu Podfile:
    pod 'GoogleMLKit/FaceDetection', '3.2.0'
    
  2. 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 Objeto FaceDetectorOptions. 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 objeto UIImage 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 con UIImage. 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 Objeto CMSampleBuffer 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étodo process():

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 objetos Face 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:

ejemplo de malla de contorno de rostro detectada

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ón

  • Habilita 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 De AVCaptureVideoDataOutputSampleBufferDelegate La función captureOutput(_, didOutput:from:) para obtener resultados de un video determinado de forma síncrona marco. Mantener de AVCaptureVideoDataOutput alwaysDiscardsLateVideoFrames como true 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.