Guida al rilevamento dei volti per iOS

L'attività Rilevamento dei volti ti consente di rilevare i volti in un'immagine o in un video. Puoi utilizzare questa attività per individuare i volti e le caratteristiche del viso all'interno di un'inquadratura. Questa attività utilizza un modello di machine learning (ML) che funziona con singole immagini o uno stream continuo di immagini. L'attività mostra le posizioni dei volti, insieme ai seguenti punti chiave facciali: occhio sinistro, occhio destro, punta del naso, bocca, tragione dell'occhio sinistro e tragione dell'occhio destro.

L'esempio di codice descritto in queste istruzioni è disponibile su GitHub. Puoi vedere questa attività in azione visualizzando questa demo web. Per ulteriori informazioni 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 è una semplice implementazione di un'app di rilevamento di volti per iOS. L'esempio utilizza la fotocamera di un dispositivo Android fisico per rilevare i volti in uno stream video continuo. L'app è in grado di rilevare anche i volti nelle immagini e nei video della galleria del dispositivo.

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 Detector è 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 il seguente 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 Detector:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/face_detector/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 Rilevatore di volti:

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

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e i progetti di codice per utilizzare Rilevamento di volti. 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 Detector 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 Podfile con i pod necessari per la tua app, consulta Utilizzare CocoaPods.

Aggiungi il pod MediaPipeTasksVision in Podfile utilizzando il seguente codice:

target 'MyFaceDetectorApp' 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 del tuo Podfile.

Modello

L'attività Rilevamento volti di MediaPipe richiede un modello addestrato compatibile con questa attività. Per ulteriori informazioni sui modelli addestrati disponibili per il riconoscimento facciale, consulta la sezione Modelli della panoramica delle attività.

Seleziona e scarica un modello e aggiungilo alla directory del progetto utilizzando Xcode. Per istruzioni su come aggiungere file al progetto Xcode, consulta la sezione Gestione di 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à Rilevamento volti chiamando uno dei relativi inizializzatori. L'inizializzazione FaceDetector(options:) accetta valori per le opzioni di configurazione.

Se non hai bisogno di un Rilevamento volti inizializzato con opzioni di configurazione personalizzate, puoi utilizzare l'inizializzatore FaceDetector(modelPath:) per creare un Rilevamento volti con le opzioni predefinite. Per ulteriori informazioni sulle opzioni di configurazione, consulta Panoramica della configurazione.

L'attività Rilevamento volti supporta tre tipi di dati di input: immagini fisse, file video e live streaming video. Per impostazione predefinita, FaceDetector(modelPath:) inizializza un compito per le immagini fisse. Se vuoi che l'attività venga inizializzata per elaborare file video o stream video in diretta, utilizza FaceDetector(options:) per specificare la modalità di esecuzione del video o del live streaming. La modalità live streaming richiede anche l'opzione di configurazione faceDetectorLiveStreamDelegate aggiuntiva, che consente al riconoscimento facciale di fornire i risultati del rilevamento facciale al delegato in modo asincrono.

Scegli la scheda corrispondente alla modalità di esecuzione per scoprire come creare il compito e eseguire l'inferenza.

Swift

Immagine

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)
    

Live streaming

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

Immagine

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

Live streaming

@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: se usi la modalità video o la modalità live streaming, Rilevamento dei volti 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à offre 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à. Esistono tre modalità:

IMMAGINE: la modalità per l'inserimento di singole immagini.

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

LIVE_STREAM: la modalità per un live streaming di dati di input, ad esempio da una videocamera. In questa modalità, resultListener deve essere chiamato per configurare un ascoltatore per ricevere i risultati in modo asincrono.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
minDetectionConfidence Il punteggio di confidenza minimo affinché il rilevamento dei volti abbia successo. Float [0,1] 0.5
minSuppressionThreshold La soglia minima di soppressione non massima per il rilevamento dei volti da considerare sovrapposti. Float [0,1] 0.3

Configurazione del live streaming

Quando la modalità di esecuzione è impostata su live streaming, il Rilevamento volti richiede l'opzione di configurazione aggiuntiva faceDetectorLiveStreamDelegate, che consente al Rilevamento volti di fornire i risultati di rilevamento in modo asincrono. Il delegato implementa il metodo faceDetector(_:didFinishDetection:timestampInMilliseconds:error:), chiamato dal Rilevamento dei volti dopo l'elaborazione dei risultati del rilevamento dei volti per ogni fotogramma.

Nome opzione Descrizione Intervallo di valori Valore predefinito
faceDetectorLiveStreamDelegate Consente a Rilevamento dei volti di ricevere i risultati del rilevamento dei volti in modo asincrono in modalità live streaming. La classe di cui l'istanza è impostata su questa proprietà deve implementare il metodo faceDetector(_: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 passare al riconoscimento facciale. MPImage supporta diversi tipi di formati di immagini 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 per le seguenti modalità di esecuzione:

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

  • Video: utilizza AVAssetImageGenerator per estrarre fotogrammi video nel formato CGImage, poi 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. Il rilevatore di volti non supporta gli orientamenti speculari, ad esempio .upMirrored, .downMirrored, .leftMirrored e .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'elaborazione utilizzando il framework CoreImage di iOS possono essere inviate al riconoscimento facciale in modalità di esecuzione delle immagini.

  • Video: i frame video possono essere convertiti in formato CVPixelBuffer per l'elaborazione e poi inviati a Rilevamento di volti 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 Rilevamento di volti 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 su CVPixelBuffer.

CMSampleBuffer

Il formato CMSampleBuffer memorizza i sample di media di un tipo uniforme ed è adatto alla modalità di esecuzione del live streaming. I frame in tempo reale delle videocamere iOS vengono caricati in modo asincrono nel formato CMSampleBuffer da AVCaptureVideoDataOutput di iOS.

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

Esegui l'attività

Per eseguire il Rilevamento volti, utilizza il metodo detect() specifico per la modalità di esecuzione assegnata:

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

Il riconoscimento facciale restituisce i volti rilevati all'interno dell'immagine o della cornice di input.

I seguenti esempi di codice mostrano esempi semplici di come eseguire Rilevamento volti in queste diverse modalità di esecuzione:

Swift

Immagine

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

Video

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

Live streaming

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

Objective-C

Immagine

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

Video

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

Live streaming

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

L'esempio di codice del rilevatore di volti 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 esegui l'operazione in modalità video o live streaming, devi anche fornire il timestamp del frame di input all'attività Rilevamento volti.

  • Quando viene eseguita in modalità immagine o video, l'attività riconoscimento facciale blocca il thread corrente finché non termina l'elaborazione dell'immagine o del frame di input. Per evitare di bloccare il thread corrente, esegui l'elaborazione in un thread in background utilizzando i framework iOS Dispatch o NSOperation.

  • Quando viene eseguita in modalità live streaming, l'attività di rilevamento dei volti restituisce immediatamente e non blocca il thread corrente. Richiama il metodo faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) con il risultato del rilevamento dei volti dopo l'elaborazione di ogni frame di input. Il rilevatore di volti richiama 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. Se la funzione detectAsync viene chiamata quando l'attività Rilevamento volti è impegnata a elaborare un altro frame, Rilevamento volti ignora il nuovo frame di input.

Gestire e visualizzare i risultati

Dopo l'esecuzione dell'inferenza, l'attività Rilevamento dei volti restituisce un oggetto FaceDetectorResult che contiene i riquadri di delimitazione dei volti rilevati e un voto di confidenza per ciascun volto rilevato.

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

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)

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

Per l'immagine senza riquadri di delimitazione, consulta l'immagine originale.

Il codice di esempio del rilevatore di volti mostra come visualizzare i risultati. Per maggiori dettagli, consulta l'esempio di codice.