Guía de detección de rostro para iOS

La tarea Detector de rostros te permite detectar rostros en una imagen o un video. Puedes usar esta tarea para ubicar rostros y rasgos faciales en un marco. Para esta tarea, se utiliza un modelo de aprendizaje automático (AA) que funciona con imágenes únicas o un flujo continuo de imágenes. La tarea muestra las ubicaciones de los rostros, junto con la siguiente clave facial puntos: ojo izquierdo, ojo derecho, punta de la nariz, boca, tragión del ojo izquierdo y ojo derecho tragión.

La muestra de código descrita en estas instrucciones está disponible en GitHub. Puedes ver esta tarea en acción viendo este sitio web demo. Para ver más información sobre las capacidades, los modelos y las opciones de configuración de esta tarea, consulta la Descripción general.

Ejemplo de código

El código de ejemplo de MediaPipe Tasks es una implementación simple de un detector de rostros para iOS. En el ejemplo, se usa la cámara de un dispositivo Android físico para detectar en una transmisión de video por Internet continua. La app también puede detectar rostros en imágenes y videos de la galería del dispositivo.

Puedes usar la app como punto de partida para tu propia app para iOS o hacer referencia a ella. cuando se modifica una app existente. El código de ejemplo del detector de rostros se aloja en GitHub:

Descarga el código

En las siguientes instrucciones, se muestra cómo crear una copia local del ejemplo con la herramienta de línea de comandos git.

Para descargar el código de ejemplo, haz lo siguiente:

  1. Clona el repositorio de Git con el siguiente comando:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. De forma opcional, configura tu instancia de Git para que use un método de confirmación de la compra disperso solo los archivos de la app de ejemplo de Detector de rostros:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_detector/ios/
    

Después de crear una versión local del código de ejemplo, puedes instalar el MediaPipe, abre el proyecto con Xcode y ejecuta la app. Para consulta la Guía de configuración para iOS.

Componentes clave

Los siguientes archivos contienen el código fundamental para el ejemplo del detector de rostros. aplicación:

  • FaceDetectorService.swift: Inicializa el detector, controla la selección del modelo y ejecuta la inferencia en los datos de entrada.
  • CameraViewController: Implementa la IU para el modo de entrada de feed de la cámara en vivo y visualiza los resultados de la detección.
  • MediaLibraryViewController.swift: Implementa la IU para el modo de entrada de archivos de video y imagen estática, y visualiza los resultados de la detección.

Configuración

En esta sección, se describen los pasos clave para configurar tu entorno de desarrollo y proyectos de código para usar el Detector de rostros. Para obtener información general sobre cómo configurar tu entorno de desarrollo para usar tareas de MediaPipe, incluida la versión de la plataforma consulta la Guía de configuración para iOS.

Dependencias

El detector de rostros usa la biblioteca MediaPipeTasksVision, que debe instalarse con CocoaPods. La biblioteca es compatible con apps de Swift y Objective-C y no requiere ninguna configuración adicional específica de idioma.

Si necesitas instrucciones para instalar CocoaPods en macOS, consulta los CocoaPods guía de instalación. Obtén instrucciones para crear un Podfile con los Pods necesarios para tu consulta Cómo usar CocoaPods.

Agrega el Pod MediaPipeTasksVision en Podfile con el siguiente código:

target 'MyFaceDetectorApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Si tu app incluye objetivos de prueba de unidades, consulta la Guía de configuración de iOS para obtener más información sobre la configuración tu Podfile.

Modelo

La tarea MediaPipe Face Detector requiere un modelo entrenado que sea compatible con esta tarea. Si deseas obtener más información sobre los modelos entrenados disponibles para Para usar el detector de rostros, consulta la descripción general de la tarea: Modelos .

Selecciona y descarga un modelo, y agrégalo al directorio de tu proyecto con Xcode. Para obtener instrucciones sobre cómo agregar archivos a tu proyecto de Xcode, consulta Administra archivos y carpetas en tu código proyecto.

Usa la propiedad BaseOptions.modelAssetPath para especificar la ruta al modelo. del paquete de aplicación. Para ver un ejemplo de código, consulta la siguiente sección.

Crea la tarea

Puedes crear la tarea Detector de rostros llamando a uno de sus inicializadores. El El inicializador FaceDetector(options:) acepta valores para la configuración opciones de estado.

Si no necesitas que un detector de rostros se inicialice con una configuración personalizada, haz lo siguiente: puedes usar el inicializador FaceDetector(modelPath:) para crear un Detector de rostros con las opciones predeterminadas. Para obtener más información sobre la configuración consulta Descripción general de la configuración.

La tarea Detector de rostros admite 3 tipos de datos de entrada: imágenes fijas y archivos de video. y transmisiones de video en vivo. De forma predeterminada, FaceDetector(modelPath:) inicializa un de imágenes fijas. Si quieres que tu tarea se inicialice para procesar videos o transmisiones de video en vivo, usa FaceDetector(options:) para especificar el video o el modo de ejecución de transmisión en vivo. El modo de transmisión en vivo también requiere opción de configuración faceDetectorLiveStreamDelegate, que habilita la El detector de rostros proporciona resultados de detección de rostro al delegado de forma asíncrona.

Elige la pestaña que corresponda a tu modo de ejecución para ver cómo crear la tarea y ejecutar inferencias.

Swift

Imagen

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .image

let faceDetector = try FaceDetector(options: options)
    

Video

import MediaPipeTasksVision

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .video

let faceDetector = try FaceDetector(options: options)
    

Transmisión en vivo

import MediaPipeTasksVision

// Class that conforms to the `FaceDetectorLiveStreamDelegate` protocol and
// implements the method that the face detector calls once it finishes
// detecting faces in each input frame.
class FaceDetectorResultProcessor: NSObject, FaceDetectorLiveStreamDelegate {

  func faceDetector(
    _ faceDetector: FaceDetector,
    didFinishDetection result: FaceDetectorResult?,
    timestampInMilliseconds: Int,
    error: Error?) {

    // Process the face detection result or errors here.

  }
}

let modelPath = Bundle.main.path(
  forResource: "model",
  ofType: "tflite")

let options = FaceDetectorOptions()
options.baseOptions.modelAssetPath = modelPath
options.runningMode = .liveStream

// Assign an object of the class to the `faceDetectorLiveStreamDelegate`
// property.
let processor = FaceDetectorResultProcessor()
options.faceDetectorLiveStreamDelegate = processor

let faceDetector = try FaceDetector(options: options)
    

Objective-C

Imagen

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeImage;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

Video

@import MediaPipeTasksVision;

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeVideo;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

Transmisión en vivo

@import MediaPipeTasksVision;

// Class that conforms to the `MPPFaceDetectorLiveStreamDelegate` protocol
// and implements the method that the face detector calls once it finishes
// detecting faces in each input frame.

@interface APPFaceDetectorResultProcessor : NSObject 

@end

@implementation APPFaceDetectorResultProcessor

-   (void)faceDetector:(MPPFaceDetector *)faceDetector
    didFinishDetectionWithResult:(MPPFaceDetectorResult *)faceDetectorResult
         timestampInMilliseconds:(NSInteger)timestampInMilliseconds
                           error:(NSError *)error {

    // Process the face detector result or errors here.

}

@end

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model"
                                                      ofType:@"tflite"];

MPPFaceDetectorOptions *options = [[MPPFaceDetectorOptions alloc] init];
options.baseOptions.modelAssetPath = modelPath;
options.runningMode = MPPRunningModeLiveStream;

// Assign an object of the class to the `faceDetectorLiveStreamDelegate`
// property.
APPFaceDetectorResultProcessor *processor = [APPFaceDetectorResultProcessor new];
options.faceDetectorLiveStreamDelegate = processor;

MPPFaceDetector *faceDetector =
      [[MPPFaceDetector alloc] initWithOptions:options error:nil];
    

Nota: Si usas el modo de video o de transmisión en vivo, el detector de rostros usa para evitar activar el modelo de detección en cada fotograma, lo que ayuda reducir la latencia.

Opciones de configuración

Esta tarea tiene las siguientes opciones de configuración para las apps para iOS:

Nombre de la opción Descripción Rango de valores Valor predeterminado
runningMode Establece el modo de ejecución de la tarea. Existen tres modos:

IMAGE: Es el modo para entradas de una sola imagen.

VIDEO: es el modo de los fotogramas decodificados de un video.

LIVE_STREAM: Es el modo para una transmisión en vivo de entradas. datos, como los de una cámara. En este modo, resultListener debe se llama para configurar un objeto de escucha que reciba resultados de forma asíncrona.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
minDetectionConfidence La puntuación de confianza mínima para que la detección de rostro se considere correcta. Float [0,1] 0.5
minSuppressionThreshold El umbral mínimo de supresión no máxima para que la detección de rostros se considere superpuesta. Float [0,1] 0.3

Configuración de la transmisión en vivo

Cuando el modo de ejecución está configurado para transmisión en vivo, el detector de rostros requiere opción de configuración faceDetectorLiveStreamDelegate adicional, que permite para que el detector de rostros brinde resultados de detección de manera asíncrona. El delegado implementa método faceDetector(_:didFinishDetection:timestampInMilliseconds:error:), a la que llama el detector de rostros después de procesar los resultados de la detección de rostros cada fotograma.

Nombre de la opción Descripción Rango de valores Valor predeterminado
faceDetectorLiveStreamDelegate Permite que el detector de rostros reciba resultados de detección de rostro de forma asíncrona. en modo de transmisión en vivo. La clase cuya instancia se establezca en esta propiedad debe implementar la faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) . No aplicable Sin establecer

Preparar los datos

Antes de convertir la imagen o el marco de entrada en un objeto MPImage, y la pasas al Detector de rostros. MPImage es compatible con diferentes tipos de imágenes de iOS y puede usarlos en cualquier modo de ejecución para inferencia. Para ver más información sobre MPImage, consulta la API de MPImage

Elige un formato de imagen de iOS según tu caso de uso y el modo de ejecución la aplicación lo requiera.MPImage acepta las UIImage, CVPixelBuffer y CMSampleBuffer Formatos de imagen de iOS.

UIImage

El formato UIImage es adecuado para los siguientes modos de ejecución:

  • Imágenes: imágenes de un paquete de aplicación, una galería de usuarios o un sistema de archivos con el siguiente formato: Las imágenes UIImage se pueden convertir en un objeto MPImage.

  • Videos: Usa AVAssetImageGenerator para extraer fotogramas de video CGImage y, luego, conviértelas en imágenes UIImage.

Swift

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(uiImage: image)
    

Objective-C

// Load an image on the user's device as an iOS `UIImage` object.

// Convert the `UIImage` object to a MediaPipe's Image object having the default
// orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

En el ejemplo, se inicializa un MPImage con el valor predeterminado. UIImage.Orientation.Up orientación. Puedes inicializar un MPImage con cualquiera de los UIImage.Orientation de salida. El detector de rostros no admite orientaciones duplicadas, como .upMirrored, .downMirrored, .leftMirrored y .rightMirrored

Para obtener más información sobre UIImage, consulta UIImage Apple Developer. Documentación.

CVPixelBuffer

El formato CVPixelBuffer es adecuado para aplicaciones que generan fotogramas Usa CoreImage de iOS. de infraestructura para el procesamiento.

El formato CVPixelBuffer es adecuado para los siguientes modos de ejecución:

  • Imágenes: apps que generan imágenes de CVPixelBuffer después de cierto procesamiento con el framework CoreImage de iOS se pueden enviar al Detector de rostros en el el modo de ejecución de imagen.

  • Videos: Los fotogramas de video se pueden convertir al formato CVPixelBuffer para y luego se envían al detector de rostros en modo de video.

  • transmisión en vivo: se pueden convertir las apps que usan una cámara de iOS para generar fotogramas en el formato CVPixelBuffer para procesarlos antes de enviarlos Detector de rostros en modo de transmisión en vivo.

Swift

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(pixelBuffer: pixelBuffer)
    

Objective-C

// Obtain a CVPixelBuffer.

// Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
    

Para obtener más información sobre CVPixelBuffer, consulta CVPixelBuffer Apple Desarrollador Documentación.

CMSampleBuffer

El formato CMSampleBuffer almacena muestras de contenido multimedia de un tipo uniforme y es adecuado para el modo de ejecución de transmisión en vivo. Los fotogramas en vivo de las cámaras iOS entregado de forma asíncrona en formato CMSampleBuffer por iOS AVCaptureVideoDataOutput.

Swift

// Obtain a CMSampleBuffer.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default
// orientation `UIImage.Orientation.up`.
let image = try MPImage(sampleBuffer: sampleBuffer)
    

Objective-C

// Obtain a `CMSampleBuffer`.

// Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the
// default orientation `UIImageOrientationUp`.
MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
    

Para obtener más información sobre CMSampleBuffer, consulta CMSampleBuffer en Apple. Desarrollador Documentación.

Ejecuta la tarea

Para ejecutar el detector de rostros, usa el método detect() específico del detector de rostros asignado. modo de ejecución:

  • Imagen fija: detect(image:)
  • Video: detect(videoFrame:timestampInMilliseconds:)
  • Transmisión en vivo: detectAsync(image:timestampInMilliseconds:)

El detector de rostros muestra los rostros detectados en la imagen o el marco de entrada.

A continuación, se muestran ejemplos de código simples para ejecutar el detector de rostros en estos diferentes modos de ejecución:

Swift

Imagen

let result = try faceDetector.detect(image: image)
    

Video

let result = try faceDetector.detect(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Transmisión en vivo

try faceDetector.detectAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Imagen

MPPFaceDetectorResult *result = [faceDetector detectInImage:image
                                                      error:nil];
    

Video

MPPFaceDetectorResult *result = [faceDetector detectInVideoFrame:image
                                         timestampInMilliseconds:timestamp
                                                           error:nil];
    

Transmisión en vivo

BOOL success = [faceDetector detectAsyncInImage:image
                        timestampInMilliseconds:timestamp
                                          error:nil];
    

En el ejemplo de código del detector de rostros, se muestran las implementaciones de cada uno de estos modos. con más detalle detect(image:), detect(videoFrame:timestampInMilliseconds:), y detectAsync(image:timestampInMilliseconds:). El código de ejemplo permite que la que el usuario cambie entre los modos de procesamiento, lo cual puede no ser necesario para su uso para determinar si este es el caso.

Ten en cuenta lo siguiente:

  • Cuando se ejecute en modo de video o de transmisión en vivo, también debes proporcionar la marca de tiempo del marco de entrada para la tarea Detector de rostros.

  • Cuando se ejecuta en modo de imagen o video, la tarea Detector de rostros bloquea subproceso actual hasta que termine de procesar la imagen o el marco de entrada. Para Evita bloquear el subproceso actual y ejecuta el procesamiento en segundo plano subproceso con iOS Despachador o NSOperation de seguridad en la nube.

  • Cuando se ejecuta en modo de transmisión en vivo, la tarea Detector de rostros muestra inmediatamente y no bloquea el subproceso actual. Invoca la función Método faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) con el resultado de la detección de rostro después de procesar cada fotograma de entrada. El El detector de rostros invoca este método de forma asíncrona en un número de serie dedicado de la fila de despacho. Para mostrar resultados en la interfaz de usuario, envía el los resultados a la cola principal después de procesarlos. Si el elemento detectAsync se llama a la función cuando la tarea Detector de rostros está ocupada procesando otra fotograma, el Detector de rostros ignorará el nuevo marco de entrada.

Cómo controlar y mostrar resultados

Después de ejecutar la inferencia, la tarea del detector de rostros muestra un FaceDetectorResult. que contiene los cuadros delimitadores para los rostros detectados y un valor de puntuación de cada rostro detectado.

A continuación, se muestra un ejemplo de los datos de salida de esta tarea:

FaceDetectionResult:
  Detections:
    Detection #0:
      BoundingBox:
        origin_x: 126
        origin_y: 100
        width: 463
        height: 463
      Categories:
        Category #0:
          index: 0
          score: 0.9729152917861938
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.18298381567001343
          y: 0.2961040139198303
        NormalizedKeypoint #1:
          x: 0.3302789330482483
          y: 0.29289937019348145
        ... (6 keypoints for each face)
    Detection #1:
      BoundingBox:
        origin_x: 616
        origin_y: 193
        width: 430
        height: 430
      Categories:
        Category #0:
          index: 0
          score: 0.9251380562782288
      NormalizedKeypoints:
        NormalizedKeypoint #0:
          x: 0.6151331663131714
          y: 0.3713381886482239
        NormalizedKeypoint #1:
          x: 0.7460576295852661
          y: 0.38825345039367676
        ... (6 keypoints for each face)

En la siguiente imagen, se muestra una visualización del resultado de la tarea:

Si la imagen no tiene cuadros delimitadores, consulta la imagen original.

En el código de ejemplo del detector de rostros, se indica cómo mostrar los resultados. Consulta la ejemplo de código para obtener más detalles.