Guida al rilevamento dei punti di riferimento del viso per iOS

L'attività MediaPipe Face Landmarker consente di rilevare punti di riferimento e espressioni facciali in immagini e video. Puoi utilizzare questa attività per identificare le espressioni facciali umane, applicare filtri ed effetti e creare avatar virtuali. Questa attività utilizza modelli di machine learning (ML) in grado di funzionare con immagini singole, video o un flusso continuo di immagini. L'attività genera punti di riferimento del viso tridimensionali, scorci di blendshape (coefficienti che rappresentano l'espressione facciale) per dedurre superfici facciali dettagliate in tempo reale e matrici di trasformazione per eseguire le trasformazioni necessarie per il rendering degli effetti.

L'esempio di codice descritto in queste istruzioni è disponibile su GitHub. Puoi vedere questa attività in azione visualizzando questa demo web. Per saperne di più sulle funzionalità, sui modelli e sulle opzioni di configurazione di questa attività, consulta la Panoramica.

Esempio di codice

Il codice di esempio di MediaPipe Tasks è un'implementazione di base di un'app di rilevamento dei punti di riferimento del viso per iOS. L'esempio utilizza la fotocamera di un dispositivo iOS fisico per rilevare i punti di riferimento dei volti in uno stream video continuo. L'app può anche rilevare i punti di riferimento dei volti nelle immagini e nei video della galleria.

Puoi utilizzare l'app come punto di partenza per la tua app per iOS o farvi riferimento quando modifichi un'app esistente. Il codice di esempio di Face Landmarker è ospitato su GitHub.

Scarica il codice

Le istruzioni riportate di seguito mostrano come creare una copia locale del codice di esempio utilizzando lo strumento a riga di comando git.

Per scaricare il codice di esempio:

  1. Clona il repository git utilizzando questo comando:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Facoltativamente, configura l'istanza Git in modo da utilizzare il pagamento sparso, in modo da avere solo i file per l'app di esempio Face Lookout:

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

Dopo aver creato una versione locale del codice di esempio, puoi installare la libreria di attività MediaPipe, aprire il progetto utilizzando Xcode ed eseguire l'app. Per le istruzioni, consulta la Guida alla configurazione per iOS.

Componenti chiave

I seguenti file contengono il codice fondamentale per l'applicazione di esempio Face Landmarker:

  • FaceLandmarkerService.swift: inizializza il rilevamento dei punti di riferimento del volto, gestisce la selezione del modello ed esegue l'inferenza sui dati di input.
  • CameraViewController.swift: implementa l'interfaccia utente per la modalità di immissione del feed della videocamera in diretta e visualizza i risultati.
  • MediaLibraryViewController.swift: implementa l'interfaccia utente per le modalità di inserimento di file di immagini e video e visualizza i risultati.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e i progetti di codice per utilizzare Face Landmarker. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'utilizzo delle attività MediaPipe, inclusi i requisiti della versione della piattaforma, consulta la guida alla configurazione per iOS.

Dipendenze

Face Landmarker utilizza la libreria MediaPipeTasksVision, che deve essere installata utilizzando CocoaPods. La libreria è compatibile con le app Swift e Objective-C e non richiede alcuna configurazione aggiuntiva specifica per il linguaggio.

Per istruzioni su come installare CocoaPods su macOS, consulta la guida all'installazione di CocoaPods. Per istruzioni su come creare un elemento Podfile con i pod necessari per la tua app, consulta Utilizzare CocoaPods.

Aggiungi il pod MediaPipeTasksVision in Podfile utilizzando il seguente codice:

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

Se la tua app include target di test di unità, consulta la guida alla configurazione per iOS per ulteriori informazioni sulla configurazione di Podfile.

Modello

L'attività Punti di riferimento volti di MediaPipe richiede un bundle di modelli addestrato che sia compatibile con questa attività. Per saperne di più sui modelli addestrati disponibili per Face Landmarker, consulta la sezione Modelli della panoramica dell'attività.

Seleziona e scarica un modello e aggiungilo alla directory del progetto utilizzando Xcode. Per istruzioni su come aggiungere file al progetto Xcode, consulta Gestire file e cartelle nel progetto Xcode.

Utilizza la proprietà BaseOptions.modelAssetPath per specificare il percorso del modello nel tuo app bundle. Per un esempio di codice, consulta la sezione successiva.

Crea l'attività

Puoi creare l'attività di rilevamento dei punti di riferimento del viso chiamando uno dei relativi inizializzatori. L'inizializzazione FaceLandmarker(options:) accetta valori per le opzioni di configurazione.

Se non hai bisogno di un rilevamento dei punti di riferimento del viso inizializzato con opzioni di configurazione personalizzate, puoi utilizzare l'inizializzatore FaceLandmarker(modelPath:) per creare un rilevamento dei punti di riferimento del viso con le opzioni predefinite. Per ulteriori informazioni sulle opzioni di configurazione, consulta la Panoramica della configurazione.

L'attività di rilevamento dei punti di riferimento del viso supporta tre tipi di dati di input: immagini fisse, file video e live streaming video. Per impostazione predefinita, FaceLandmarker(modelPath:) inizializza un'attività per le immagini fisse. Se vuoi che l'attività venga inizializzata per elaborare file video o stream video in diretta, utilizza FaceLandmarker(options:) per specificare la modalità di esecuzione del video o del live streaming. La modalità di live streaming richiede anche l'opzione di configurazione faceLandmarkerLiveStreamDelegate aggiuntiva, che consente a Face Taper di fornire al delegato risultati in modo asincrono.

Scegli la scheda corrispondente alla tua modalità di esecuzione per vedere come creare l'attività ed eseguire l'inferenza.

Swift

Immagine

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)
    

Live streaming

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

Immagine

@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];
    

Live streaming

@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: se utilizzi la modalità video o la modalità live streaming, Face Landmarker utilizza il monitoraggio per evitare di attivare il modello di rilevamento su ogni fotogramma, il che contribuisce a ridurre la latenza.

Opzioni di configurazione

Questa attività include le seguenti opzioni di configurazione per le app per iOS:

Nome opzione Descrizione Intervallo di valori Valore predefinito
runningMode Imposta la modalità di esecuzione dell'attività. Face Taper prevede tre modalità:

IMAGE: la modalità per gli input di immagini singole.

VIDEO: la modalità per i fotogrammi decodificati di un video.

LIVE_STREAM: la modalità per un live streaming dei dati di input, ad esempio da una videocamera. In questa modalità, "faceLandmarkerLiveStreamDelegate" deve essere impostato su un'istanza di una classe che implementa "FaceLandmarkerLiveStreamDelegate" per ricevere i risultati dell'esecuzione del rilevamento dei punti di riferimento del volto in modo asincrono.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} {RunningMode.image}
numFaces Il numero massimo di volti che possono essere rilevati dall'elemento Face Landmarker. La funzionalità di spianamento viene applicata solo quando numFaces è impostato su 1. Numero intero > 0 1
minFaceDetectionConfidence Il punteggio di attendibilità minimo per il rilevamento del volto da considerare positivo. Numero in virgola mobile [0,0,1,0] 0,5
minFacePresenceConfidence Il punteggio di attendibilità minimo del punteggio di presenza del volto nel rilevamento dei punti di riferimento del volto. Numero in virgola mobile [0,0,1,0] 0,5
minTrackingConfidence Il punteggio di attendibilità minimo per il rilevamento del volto da considerare positivo. Numero in virgola mobile [0,0,1,0] 0,5
outputFaceBlendshapes Indica se FaceLandmarker genera blendshape del viso. Le blendshape del volto vengono utilizzate per il rendering del modello 3D del volto. Bool falso
outputFacialTransformationMatrixes Indica se FaceLandmarker restituisce la matrice di trasformazione facciale. FaceLandmarker utilizza la matrice per trasformare i punti di riferimento dei volti da un modello canonico del volto al volto rilevato, in modo che gli utenti possano applicare effetti sui punti di riferimento rilevati. Bool falso

Quando la modalità di esecuzione è impostata su LIVE_STREAM, il rilevamento dei punti di riferimento del volto richiede l'opzione di configurazione aggiuntiva faceLandmarkerLiveStreamDelegate, che consente al rilevamento dei punti di riferimento del volto di fornire risultati in modo asincrono. Il delegato deve implementare il metodo faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:), chiamato da Face Landmarker dopo l'elaborazione dei risultati del rilevamento dei punti di riferimento del volto su ogni frame.

Nome opzione Descrizione Intervallo di valori Valore predefinito
faceLandmarkerLiveStreamDelegate Consente a Face Landmarker di ricevere i risultati dell'esecuzione del rilevamento dei punti di riferimento del volto in modo asincrono in modalità live streaming. La classe di cui è impostata l'istanza su questa proprietà deve implementare il metodo faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:). Non applicabile Non impostato

Preparazione dei dati

Devi convertire l'immagine o il fotogramma di input in un oggetto MPImage prima di passarlo a Face Taper. MPImage supporta diversi tipi di formati di immagine iOS e può utilizzarli in qualsiasi modalità di esecuzione per l'inferenza. Per ulteriori informazioni su MPImage, consulta l'API MPImage.

Scegli un formato dell'immagine iOS in base al caso d'uso e alla modalità di esecuzione richiesta dall'applicazione.MPImage accetta i formati dell'immagine UIImage, CVPixelBuffer e CMSampleBuffer iOS.

UIImage

Il formato UIImage è adatto alle seguenti modalità di corsa:

  • Immagini: le immagini di un app bundle, di una galleria utente o di un file system formattate come immagini UIImage possono essere convertite in un oggetto MPImage.

  • Video: utilizza AVAssetImageGenerator per estrarre i frame video nel formato CGImage, quindi convertili in immagini 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];
    

L'esempio inizializza un MPImage con l'orientamento predefinito UIImage.Orientation.Up. Puoi inizializzare un MPImage con uno dei valori supportati di UIImage.Orientation. Face Landmarker non supporta orientamenti con mirroring come .upMirrored, .downMirrored, .leftMirrored, .rightMirrored.

Per ulteriori informazioni su UIImage, consulta la documentazione per sviluppatori Apple su UIImage.

CVPixelBuffer

Il formato CVPixelBuffer è adatto per le applicazioni che generano frame e utilizzano il framework CoreImage di iOS per l'elaborazione.

Il formato CVPixelBuffer è adatto per le seguenti modalità di esecuzione:

  • Immagini: le app che generano immagini CVPixelBuffer dopo un po' di elaborazione utilizzando il framework CoreImage di iOS possono essere inviate a Face Taper in modalità di esecuzione delle immagini.

  • Video: i fotogrammi video possono essere convertiti nel formato CVPixelBuffer per l'elaborazione e quindi inviati a Face Taper in modalità video.

  • live streaming: le app che utilizzano una fotocamera iOS per generare frame possono essere convertite in formato CVPixelBuffer per l'elaborazione prima di essere inviate al Face Landmarker in modalità live streaming.

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];
    

Per ulteriori informazioni su CVPixelBuffer, consulta la documentazione per sviluppatori Apple di CVPixelBuffer.

CMSampleBuffer

Il formato CMSampleBuffer memorizza i sample di media di un tipo uniforme ed è adatto alla modalità di esecuzione del live streaming. I fotogrammi in diretta delle fotocamere iOS vengono trasmessi in modo asincrono nel formato CMSampleBuffer da 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];
    

Per ulteriori informazioni su CMSampleBuffer, consulta la documentazione per sviluppatori Apple su CMSampleBuffer.

Esegui l'attività

Per eseguire il rilevamento dei punti di riferimento del volto, utilizza il metodo detect() specifico per la modalità di esecuzione assegnata:

  • Immagine fissa: detect(image:)
  • Video: detect(videoFrame:timestampInMilliseconds:)
  • Live streaming: detectAsync(image:timestampInMilliseconds:)

I seguenti esempi di codice mostrano esempi di base di come eseguire Face Lookouter in queste diverse modalità di esecuzione:

Swift

Immagine

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

Video

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

Live streaming

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

Objective-C

Immagine

MPPFaceLandmarkerResult *result =
  [faceLandmarker detectImage:image error:nil];
    

Video

MPPFaceLandmarkerResult *result =
  [faceLandmarker detectVideoFrame:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

Live streaming

BOOL success =
  [faceLandmarker detectAsyncImage:image
           timestampInMilliseconds:timestamp
                             error:nil];
    

L'esempio di codice Face Lookouter mostra le implementazioni di ciascuna di queste modalità in modo più dettagliato detect(image:), detect(videoFrame:timestampInMilliseconds:) e detectAsync(image:timestampInMilliseconds:). Il codice di esempio consente all'utente di passare da una modalità di elaborazione all'altra, che potrebbe non essere necessaria per il tuo caso d'uso.

Tieni presente quanto segue:

  • Quando corri in modalità video o live streaming, devi anche fornire il timestamp del fotogramma di input all'attività Punti di riferimento volti.

  • Quando viene eseguita in modalità immagine o video, l'attività di rilevamento dei punti di riferimento del volto blocca il thread corrente fino al termine dell'elaborazione dell'immagine o dell'inquadratura di input. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un thread in background utilizzando i framework iOS Dispatch o NSOperation. Se l'app è stata creata utilizzando Swift, puoi anche utilizzare Swift Concurrency per l'esecuzione di thread in background.

  • Quando viene eseguita in modalità live streaming, l'attività di rilevamento dei punti di riferimento del volto restituisce immediatamente il risultato e non blocca il thread corrente. Richiama il metodo faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:) con il risultato del rilevamento dei punti di riferimento del volto dopo l'elaborazione di ogni frame di input. Il rilevamento dei punti di riferimento del viso invoca questo metodo in modo asincrono in una coda di elaborazione seriale dedicata. Per visualizzare i risultati nell'interfaccia utente, inviali alla coda principale dopo averli elaborati.

Gestire e visualizzare i risultati

Dopo aver eseguito l'inferenza, il rilevamento dei punti di riferimento del viso restituisce un FaceLandmarkerResult che contiene un mesh del viso per ogni volto rilevato, con le coordinate di ciascun punto di riferimento del viso. Facoltativamente, l'oggetto risultato può contenere anche blendshape, che indicano le espressioni facciali, e matrici di trasformazione facciale per applicare effetti sul viso ai punti di riferimento rilevati.

Di seguito è riportato un esempio dei dati di output di questa attività:

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]
    ...

L'immagine seguente mostra una visualizzazione dell'output dell'attività:

Il codice di esempio di Face Landmarker mostra come visualizzare i risultati restituiti dall'attività. Per maggiori dettagli, consulta FaceOverlay.swift.