La tarea de MediaPipe Face Landmarker te permite detectar puntos de referencia faciales y expresiones faciales en imágenes y videos. Puedes usar esta tarea para identificar expresiones faciales humanas, aplicar filtros faciales y efectos, y crear avatares virtuales. Esta tarea usa modelos de aprendizaje automático (AA) que pueden funcionar con imágenes individuales, videos o un flujo continuo de imágenes. La tarea genera puntos de referencia faciales en 3 dimensiones, puntuaciones de formas de combinación (coeficientes que representan la expresión facial) para inferir superficies faciales detalladas en tiempo real y matrices de transformación para realizar las transformaciones necesarias para la renderización de efectos.
La muestra de código que se describe en estas instrucciones está disponible en GitHub. Puedes ver esta tarea en acción en esta demo web. Para obtener más información sobre las funciones, 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 básica de una app de Face Landmarker para iOS. En el ejemplo, se usa la cámara de un dispositivo iOS físico para detectar puntos de referencia de rostros en una transmisión de video continua. También detecta puntos de referencia de 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 consultarla cuando modifiques una app existente. El código de ejemplo de Face Landmarker se aloja en GitHub.
Descarga el código
En las siguientes instrucciones, se muestra cómo crear una copia local del código de ejemplo con la herramienta de línea de comandos git.
Para descargar el código de ejemplo, sigue estos pasos:
Clona el repositorio de git con el siguiente comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
De manera opcional, configura tu instancia de git para usar el control de revisión disperso, de modo que solo tengas los archivos de la app de ejemplo de Face Landmarker:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/face_landmarker/ios
Después de crear una versión local del código de ejemplo, puedes instalar la biblioteca de tareas de MediaPipe, abrir el proyecto con Xcode y ejecutar la app. Para obtener instrucciones, consulta la Guía de configuración para iOS.
Componentes clave
Los siguientes archivos contienen el código fundamental de la aplicación de ejemplo de Face Landmarker:
- FaceLandmarkerService.swift: Inicializa el marcador de posición de rostro, controla la selección del modelo y ejecuta inferencias en los datos de entrada.
- CameraViewController.swift: Implementa la IU del modo de entrada del feed de la cámara en vivo y visualiza los resultados.
- MediaLibraryViewController.swift: Implementa la IU para los modos de entrada de archivos de imagen fija y video, y visualiza los resultados.
Configuración
En esta sección, se describen los pasos clave para configurar tu entorno de desarrollo y proyectos de código para usar Face Landmarker. Si deseas obtener información general sobre cómo configurar tu entorno de desarrollo para usar tareas de MediaPipe, incluidos los requisitos de la versión de la plataforma, consulta la Guía de configuración para iOS.
Dependencias
Face Landmarker usa la biblioteca MediaPipeTasksVision
, que se debe instalar con CocoaPods. La biblioteca es compatible con apps de Swift y Objective-C,
y no requiere ninguna configuración adicional específica del lenguaje.
Para obtener instrucciones para instalar CocoaPods en MacOS, consulta la guía de instalación de CocoaPods.
Si quieres obtener instrucciones a fin de crear un Podfile
con los Pods necesarios para tu
app, consulta Usa
CocoaPods.
Agrega el pod MediaPipeTasksVision
en Podfile
con el siguiente código:
target 'MyFaceLandmarkerApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
Si tu app incluye destinos de pruebas de unidades, consulta la Guía de configuración para iOS para obtener información adicional sobre cómo configurar tu Podfile
.
Modelo
La tarea MediaPipe Face Landmarker requiere un paquete de modelos entrenados que sea compatible con esta tarea. Si deseas obtener más información sobre los modelos entrenados disponibles para Face Landmarker, consulta la sección Modelos de descripción general de la tarea.
Selecciona y descarga un modelo, y agrégalo al directorio de tu proyecto con Xcode. Si quieres obtener instrucciones para agregar archivos a tu proyecto de Xcode, consulta Administra archivos y carpetas en tu proyecto de Xcode.
Usa la propiedad BaseOptions.modelAssetPath
para especificar la ruta de acceso al modelo en tu paquete de aplicación. Para ver un ejemplo de código, consulta la siguiente sección.
Crea la tarea
Para crear la tarea de Face Landmarker, llama a uno de sus inicializadores. El inicializador FaceLandmarker(options:)
acepta valores para las opciones de configuración.
Si no necesitas que se inicialice un Face Landmarker con opciones de configuración personalizadas, puedes usar el inicializador FaceLandmarker(modelPath:)
para crear un Face Landmarker con las opciones predeterminadas. Para obtener más información sobre las opciones de configuración, consulta Descripción general de la configuración.
La tarea de marcador de rostro admite 3 tipos de datos de entrada: imágenes fijas, archivos de video y transmisiones de video en vivo. De forma predeterminada, FaceLandmarker(modelPath:)
inicializa una tarea para imágenes estáticas. Si deseas que tu tarea se inicialice para procesar archivos de video o transmisiones de video en vivo, usa FaceLandmarker(options:)
para especificar el modo de ejecución del video o la transmisión en vivo. El modo de transmisión en vivo también requiere la opción de configuración adicional faceLandmarkerLiveStreamDelegate
, que permite que el detector de puntos de referencia faciales entregue resultados al delegado de forma asíncrona.
Elige la pestaña correspondiente a tu modo de ejecución para ver cómo crear la tarea y ejecutar la inferencia.
Swift
Imagen
import MediaPipeTasksVision let modelPath = Bundle.main.path( forResource: "face_landmarker", ofType: "task") let options = FaceLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.minFaceDetectionConfidence = minFaceDetectionConfidence options.minFacePresenceConfidence = minFacePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numFaces = numFaces let faceLandmarker = try FaceLandmarker(options: options)
Video
import MediaPipeTasksVision let modelPath = Bundle.main.path( forResource: "face_landmarker", ofType: "task") let options = FaceLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.minFaceDetectionConfidence = minFaceDetectionConfidence options.minFacePresenceConfidence = minFacePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numFaces = numFaces let faceLandmarker = try FaceLandmarker(options: options)
Transmisión en vivo
import MediaPipeTasksVision // Class that conforms to the `FaceLandmarkerLiveStreamDelegate` protocol and // implements the method that the face landmarker calls once it finishes // performing face landmark detection in each input frame. class FaceLandmarkerResultProcessor: NSObject, FaceLandmarkerLiveStreamDelegate { func faceLandmarker( _ faceLandmarker: FaceLandmarker, didFinishDetection result: FaceLandmarkerResult?, timestampInMilliseconds: Int, error: Error?) { // Process the face landmarker result or errors here. } } let modelPath = Bundle.main.path( forResource: "face_landmarker", ofType: "task") let options = FaceLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.minFaceDetectionConfidence = minFaceDetectionConfidence options.minFacePresenceConfidence = minFacePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numFaces = numFaces // Assign an object of the class to the `faceLandmarkerLiveStreamDelegate` // property. let processor = FaceLandmarkerResultProcessor() options.faceLandmarkerLiveStreamDelegate = processor let faceLandmarker = try FaceLandmarker(options: options)
Objective-C
Imagen
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker" ofType:@"task"]; MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.minFaceDetectionConfidence = minFaceDetectionConfidence; options.minFacePresenceConfidence = minFacePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numFaces = numFaces; MPPFaceLandmarker *faceLandmarker = [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
Video
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker" ofType:@"task"]; MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.minFaceDetectionConfidence = minFaceDetectionConfidence; options.minFacePresenceConfidence = minFacePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numFaces = numFaces; MPPFaceLandmarker *faceLandmarker = [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
Transmisión en vivo
@import MediaPipeTasksVision; // Class that conforms to the `MPPFaceLandmarkerLiveStreamDelegate` protocol // and implements the method that the face landmarker calls once it finishes // performing face landmark detection in each input frame. @interface APPFaceLandmarkerResultProcessor : NSObject@end @implementation APPFaceLandmarkerResultProcessor - (void)faceLandmarker:(MPPFaceLandmarker *)faceLandmarker didFinishDetectionWithResult:(MPPFaceLandmarkerResult *)faceLandmarkerResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the face landmarker result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"face_landmarker" ofType:@"task"]; MPPFaceLandmarkerOptions *options = [[MPPFaceLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.minFaceDetectionConfidence = minFaceDetectionConfidence; options.minFacePresenceConfidence = minFacePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numFaces = numFaces; // Assign an object of the class to the `faceLandmarkerLiveStreamDelegate` // property. APPFaceLandmarkerResultProcessor *processor = [APPFaceLandmarkerResultProcessor new]; options.faceLandmarkerLiveStreamDelegate = processor; MPPFaceLandmarker *faceLandmarker = [[MPPFaceLandmarker alloc] initWithOptions:options error:nil];
Nota: Si usas el modo de video o el modo de transmisión en vivo, Face Landmarker usa el seguimiento para evitar activar el modelo de detección en cada fotograma, lo que ayuda a 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. El marcador de posición de rostro tiene tres modos:
IMAGEN: El modo para entradas de imagen única. VIDEO: Es el modo para los fotogramas decodificados de un video. LIVE_STREAM: Es el modo de transmisión en vivo de datos de entrada, como los de una cámara. En este modo, "faceLandmarkerLiveStreamDelegate" se debe establecer en una instancia de una clase que implemente "FaceLandmarkerLiveStreamDelegate" para recibir los resultados de la detección de puntos de referencia facial de forma asíncrona. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream} | {RunningMode.image} |
numFaces |
La cantidad máxima de rostros que puede detectar el marcador de posición de rostros. El suavizado solo se aplica cuando numFaces se establece en 1. | Número entero > 0 | 1 |
minFaceDetectionConfidence |
La puntuación de confianza mínima para que la detección de rostros se considere exitosa. | Número de punto flotante [0.0,1.0] | 0.5 |
minFacePresenceConfidence |
Es la puntuación de confianza mínima de la puntuación de presencia de rostro en la detección de puntos de referencia del rostro. | Número de punto flotante [0.0,1.0] | 0.5 |
minTrackingConfidence |
Es la puntuación de confianza mínima para que el seguimiento de rostros se considere exitoso. | Número de punto flotante [0.0,1.0] | 0.5 |
outputFaceBlendshapes |
Indica si FaceLandmarker genera formas de combinación de rostros. Las formas de combinación de rostros se usan para renderizar el modelo de rostro 3D. | Bool | falso |
outputFacialTransformationMatrixes |
Indica si FaceLandmarker genera la matriz de transformación facial. FaceLandmarker usa la matriz para transformar los puntos de referencia del rostro de un modelo de rostro canónico al rostro detectado, de modo que los usuarios puedan aplicar efectos en los puntos de referencia detectados. | Bool | falso |
Cuando el modo de ejecución se establece en LIVE_STREAM
, el detector de puntos de referencia faciales requiere la opción de configuración adicional faceLandmarkerLiveStreamDelegate
, que le permite entregar resultados de detección de puntos de referencia faciales de forma asíncrona. El delegado debe implementar el método faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
, al que llama el detector de puntos de referencia de rostro después de procesar los resultados de la detección de puntos de referencia de rostro en cada fotograma.
Nombre de la opción | Descripción | Rango de valores | Valor predeterminado |
---|---|---|---|
faceLandmarkerLiveStreamDelegate |
Permite que Face Landmarker reciba los resultados de la detección de puntos de referencia faciales de forma asíncrona en el modo de transmisión en vivo. La clase cuya instancia se establece en esta propiedad debe implementar el método faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) . |
No aplicable | Sin establecer |
Preparar los datos
Debes convertir la imagen o el marco de entrada en un objeto MPImage
antes de pasarlo al Marcador de puntos de referencia de rostros. MPImage
admite diferentes tipos de formatos de imagen de iOS y puede usarlos en cualquier modo de ejecución para la inferencia. Para obtener 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 que requiere tu aplicación.MPImage
acepta los formatos de imagen de iOS UIImage
, CVPixelBuffer
y CMSampleBuffer
.
UIImage
El formato UIImage
es adecuado para los siguientes modos de ejecución:
Imágenes: Las imágenes de un paquete de aplicación, una galería de usuarios o un sistema de archivos con formato
UIImage
se pueden convertir en un objetoMPImage
.Videos: Usa AVAssetImageGenerator para extraer fotogramas de video al formato CGImage y, luego, conviértelos 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 la orientación predeterminada UIImage.Orientation.Up. Puedes inicializar un objeto MPImage
con cualquiera de los valores de UIImage.Orientation compatibles. Face Landmarker no admite orientaciones reflejadas, como .upMirrored
, .downMirrored
, .leftMirrored
, .rightMirrored
.
Para obtener más información sobre UIImage
, consulta la documentación para desarrolladores de Apple sobre UIImage.
CVPixelBuffer
El formato CVPixelBuffer
es adecuado para aplicaciones que generan fotogramas y usan el framework CoreImage de iOS para el procesamiento.
El formato CVPixelBuffer
es adecuado para los siguientes modos de ejecución:
Imágenes: las apps que generan imágenes
CVPixelBuffer
después de cierto procesamiento con el frameworkCoreImage
de iOS se pueden enviar al marcador de rostros en el modo de ejecución de imágenes.Videos: Los fotogramas de video se pueden convertir al formato
CVPixelBuffer
para su procesamiento y, luego, enviarse al Marcador de rostros en modo de video.Transmisión en vivo: Las apps que usan una cámara de iOS para generar fotogramas se pueden convertir al formato
CVPixelBuffer
a fin de procesarlos antes de enviarlos al marcador de rostro 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 la documentación para desarrolladores de Apple de CVPixelBuffer.
CMSampleBuffer
El formato CMSampleBuffer
almacena muestras de contenido multimedia de un tipo de contenido multimedia uniforme y es adecuado para el modo de ejecución de transmisiones en vivo. AVCaptureVideoDataOutput de iOS entrega de forma asíncrona los fotogramas en vivo de las cámaras de iOS en el formato CMSampleBuffer
.
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 la documentación para desarrolladores de Apple de CMSampleBuffer.
Ejecuta la tarea
Para ejecutar el marcador de rostro, usa el método detect()
específico del modo de ejecución asignado:
- Imagen fija:
detect(image:)
- Video:
detect(videoFrame:timestampInMilliseconds:)
- Transmisión en vivo:
detectAsync(image:timestampInMilliseconds:)
En las siguientes muestras de código, se muestran ejemplos básicos de cómo ejecutar Face Landmarker en estos diferentes modos de ejecución:
Swift
Imagen
let result = try faceLandmarker.detect(image: image)
Video
let result = try faceLandmarker.detect( videoFrame: image, timestampInMilliseconds: timestamp)
Transmisión en vivo
try faceLandmarker.detectAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
Imagen
MPPFaceLandmarkerResult *result = [faceLandmarker detectImage:image error:nil];
Video
MPPFaceLandmarkerResult *result = [faceLandmarker detectVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Transmisión en vivo
BOOL success = [faceLandmarker detectAsyncImage:image timestampInMilliseconds:timestamp error:nil];
En el ejemplo de código de Face Landmarker, 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 al
usuario cambiar entre modos de procesamiento que pueden no ser necesarios para tu caso de
uso.
Ten en cuenta lo siguiente:
Cuando ejecutas en modo de video o de transmisión en vivo, también debes proporcionar la marca de tiempo del fotograma de entrada para la tarea Face Landmarker.
Cuando se ejecuta en modo de imagen o video, la tarea de Face Landmarker bloquea el subproceso actual hasta que termina de procesar la imagen o el fotograma de entrada. Para evitar bloquear el subproceso actual, ejecuta el procesamiento en un subproceso en segundo plano con los frameworks Dispatch o NSOperation de iOS. Si tu app se creó con Swift, también puedes usar Swift Concurrency para la ejecución de subprocesos en segundo plano.
Cuando se ejecuta en el modo de transmisión en vivo, la tarea de Face Landmarker se muestra de inmediato y no bloquea el subproceso actual. Invoca el método
faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
con el resultado de la detección de puntos de referencia faciales después de procesar cada fotograma de entrada. El localizador de marcadores faciales invoca este método de forma asíncrona en una cola de envío serial dedicada. Para mostrar los resultados en la interfaz de usuario, envíalos a la cola principal después de procesarlos.
Cómo controlar y mostrar los resultados
Cuando se ejecuta la inferencia, el Face Landmarker muestra un FaceLandmarkerResult
que contiene una malla de rostro para cada rostro detectado, con coordenadas para cada punto de referencia de rostro. De manera opcional, el objeto de resultado también puede contener formas de combinación, que denotan expresiones faciales, y matrices de transformación facial para aplicar efectos faciales en los puntos de referencia detectados.
A continuación, se muestra un ejemplo de los datos de resultado de esta tarea:
FaceLandmarkerResult:
face_landmarks:
NormalizedLandmark #0:
x: 0.5971359014511108
y: 0.485361784696579
z: -0.038440968841314316
NormalizedLandmark #1:
x: 0.3302789330482483
y: 0.29289937019348145
z: -0.09489090740680695
... (478 landmarks for each face)
face_blendshapes:
browDownLeft: 0.8296722769737244
browDownRight: 0.8096957206726074
browInnerUp: 0.00035583582939580083
browOuterUpLeft: 0.00035752105759456754
... (52 blendshapes for each face)
facial_transformation_matrixes:
[9.99158978e-01, -1.23036895e-02, 3.91213447e-02, -3.70770246e-01]
[1.66496094e-02, 9.93480563e-01, -1.12779640e-01, 2.27719707e+01]
...
En la siguiente imagen, se muestra una visualización del resultado de la tarea:
El código de ejemplo de Face Landmarker muestra cómo mostrar los resultados que muestra la tarea. Consulta FaceOverlay.swift para obtener más información.