Guia de detecção facial para iOS

A tarefa "Detector de rostos" permite detectar rostos em uma imagem ou vídeo. Você pode usar para localizar rostos e características faciais em um quadro. Esta tarefa usa um modelo de machine learning (ML) que funciona com imagens únicas ou um fluxo contínuo de imagens. A tarefa gera a localização de rostos com a seguinte chave facial pontos: olho esquerdo, olho direito, ponta do nariz, boca, tragúdio do olho esquerdo e olho direito trágião.

O exemplo de código descrito nestas instruções está disponível no GitHub. Para saber como essa tarefa funciona, acesse este site demonstração. Para mais informações sobre os recursos, modelos e opções de configuração do tarefa, consulte a Visão geral.

Exemplo de código

O código de exemplo do MediaPipe Tasks é uma implementação simples de um detector de rostos. para iOS. O exemplo usa a câmera de um dispositivo Android físico para detectar de rostos em um stream de vídeo contínuo. O app também pode detectar rostos em imagens e vídeos da galeria do dispositivo.

Você pode usar o app como ponto de partida para seu próprio app iOS ou consultá-lo ao modificar um aplicativo existente. O exemplo de código do detector de rostos está hospedado em GitHub.

Fazer o download do código

As instruções a seguir mostram como criar uma cópia local do exemplo. usando a ferramenta de linha de comando git.

Para fazer o download do código de exemplo:

  1. Clone o repositório git usando o seguinte comando:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opcionalmente, configure sua instância git para usar a finalização esparsa. Assim, você terá Apenas os arquivos do app de exemplo do Face Detector:

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

Depois de criar uma versão local do código de exemplo, você pode instalar o MediaPipe, abrir o projeto usando Xcode e executar o app. Para instruções, consulte o Guia de configuração do iOS.

Principais componentes

Os arquivos a seguir contêm o código essencial para o exemplo do Face Detector. aplicativo:

  • FaceDetectorService.swift: Inicializa o detector, processa a seleção do modelo e executa a inferência nos dados de entrada.
  • CameraViewController: Implementa a interface para o modo de entrada de transmissão da câmera em tempo real e visualiza os resultados da detecção.
  • MediaLibraryViewController.swift: Implementa a interface para o modo de entrada de arquivo de vídeo e imagem estática e visualiza os resultados da detecção.

Configuração

Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código para usar o Face Detector. Para informações gerais sobre como configurar sua ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo a versão da plataforma , consulte o Guia de configuração para iOS.

Dependências

O detector de rostos usa a biblioteca MediaPipeTasksVision, que precisa ser instalada usando o CocoaPods. A biblioteca é compatível com aplicativos Swift e Objective-C e não requer configuração específica do idioma.

Para instruções sobre como instalar o CocoaPods no macOS, consulte a documentação do CocoaPods guia de instalação (em inglês). Para instruções sobre como criar um Podfile com os pods necessários para aplicativo, consulte Usar CocoaPods.

Adicione o pod do MediaPipeTasksVision no Podfile usando o seguinte código:

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

Se o app incluir destinos de teste de unidade, consulte o Guia de configuração do iOS para mais informações sobre a configuração seu Podfile.

Modelo

A tarefa MediaPipe Face Detector requer um modelo treinado que seja compatível a essa tarefa. Para mais informações sobre os modelos treinados disponíveis para Detector de rostos, consulte a visão geral da tarefa Modelos .

Selecione e faça o download de um modelo e adicione-o ao diretório do projeto usando o Xcode. Para instruções sobre como adicionar arquivos ao seu projeto Xcode, consulte Como gerenciar arquivos e pastas no seu Xcode projeto.

Use a propriedade BaseOptions.modelAssetPath para especificar o caminho para o modelo. no seu pacote de apps. Para conferir um exemplo de código, consulte a próxima seção.

Criar a tarefa

Chame um dos inicializadores para criar a tarefa do detector de rostos. A O inicializador FaceDetector(options:) aceita valores para a configuração. .

Se você não precisa que um detector de rostos seja inicializado com configurações personalizadas você pode usar o inicializador FaceDetector(modelPath:) para criar um Face Detector com as opções padrão. Para mais informações sobre configurações opções, consulte Visão geral da configuração.

A tarefa Detector de rostos é compatível com três tipos de dados de entrada: imagens estáticas e arquivos de vídeo. e transmissões de vídeo ao vivo. Por padrão, FaceDetector(modelPath:) inicializa uma para imagens estáticas. Se você quiser que sua tarefa seja inicializada para processar vídeos arquivos ou streams de vídeo ao vivo, use FaceDetector(options:) para especificar o ou no modo de corrida ao vivo. O modo de transmissão ao vivo também requer faceDetectorLiveStreamDelegate, que ativa O detector facial fornece resultados de detecção facial ao delegado de maneira assíncrona.

Escolha a guia correspondente ao modo de corrida para saber como criar a tarefa e executar inferência.

Swift

Imagem

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)
    

Vídeo

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)
    

Transmissão ao 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

Imagem

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

Vídeo

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

Transmissão ao 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];
    

Observação:se você usar o modo de vídeo ou de transmissão ao vivo, o Detector de rostos usa o rastreamento para evitar o acionamento do modelo de detecção em cada frame, e reduzir a latência.

Opções de configuração

Esta tarefa tem as seguintes opções de configuração para apps iOS:

Nome da opção Descrição Intervalo de valor Valor padrão
runningMode Define o modo de execução da tarefa. Existem três modos:

IMAGEM: o modo para entradas de imagem única.

VÍDEO: o modo para frames decodificados de um vídeo.

LIVE_STREAM: o modo de transmissão ao vivo da entrada dados de uma câmera, por exemplo. Neste modo, resultListener deve ser chamado para configurar um listener e receber resultados de forma assíncrona.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
minDetectionConfidence A pontuação de confiança mínima para que a detecção facial seja considerada bem-sucedida. Float [0,1] 0.5
minSuppressionThreshold O limite mínimo de supressão não máxima para que a detecção facial seja considerada sobreposta. Float [0,1] 0.3

Configuração da transmissão ao vivo

Quando o modo de execução está definido como transmissão ao vivo, o Detector de rostos exige que o opção de configuração faceDetectorLiveStreamDelegate adicional, que permite o detector facial para fornecer resultados de detecção de forma assíncrona. O delegado implementa método faceDetector(_:didFinishDetection:timestampInMilliseconds:error:), que o Detector de rostos chama depois de processar os resultados da detecção facial cada frame.

Nome da opção Descrição Intervalo de valor Valor padrão
faceDetectorLiveStreamDelegate Permite que o Detector de rostos receba resultados de detecção facial de forma assíncrona. no modo de transmissão ao vivo. A classe cuja instância é definida para essa propriedade deve implementar faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) . Não relevante Não definido

Preparar dados

É necessário converter a imagem ou o frame de entrada em um objeto MPImage antes e passando para o detector de rostos. MPImage oferece suporte a diferentes tipos de imagens do iOS formatos e pode usá-los em qualquer modo em execução para inferência. Para mais informações sobre MPImage, consulte API MPImage

Escolha um formato de imagem iOS com base no seu caso de uso e no modo de execução que seu exigido pelo aplicativo.MPImage aceita UIImage, CVPixelBuffer e CMSampleBuffer formatos de imagem do iOS.

UIImage

O formato UIImage é adequado para os seguintes modos de execução:

  • Imagens: imagens de um pacote de apps, galeria do usuário ou sistema de arquivos formatados como UIImage imagens podem ser convertidas em um objeto MPImage.

  • Vídeos: use AVAssetImageGenerator para extrair frames de vídeo CGImage formato e converta-as em imagens 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];
    

O exemplo inicializa um MPImage com o UIImage.Orientation.Up orientação. É possível inicializar um MPImage com qualquer um dos UIImage.Orientation e a distribuição dos valores dos dados. O detector de rostos não oferece suporte a orientações espelhadas como .upMirrored, .downMirrored, .leftMirrored e .rightMirrored.

Para mais informações sobre o UIImage, consulte a página do desenvolvedor de imagens de usuário Documentação.

CVPixelBuffer

O formato CVPixelBuffer é adequado para aplicativos que geram frames e usar a interface CoreImage do iOS para processamento.

O formato CVPixelBuffer é adequado para os seguintes modos de execução:

  • Imagens: apps que geram imagens de CVPixelBuffer após algum processamento. usando o framework CoreImage do iOS podem ser enviadas ao Face Detector na modo de execução de imagem.

  • Vídeos: os quadros podem ser convertidos para o formato CVPixelBuffer para e enviado para o detector de rostos no modo de vídeo.

  • Transmissão ao vivo: apps que usam a câmera do iOS para gerar frames podem ser convertidos no formato CVPixelBuffer para processamento antes de ser enviado ao Detector de rostos no modo de transmissão ao 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 mais informações sobre o CVPixelBuffer, consulte a documentação da Apple CVPixelBuffer Desenvolvedor Documentação.

CMSampleBuffer

O formato CMSampleBuffer armazena amostras de mídia de um tipo uniforme de mídia e é adequado para o modo de transmissão ao vivo. Os frames ao vivo das câmeras do iOS são enviados de forma assíncrona no formato CMSampleBuffer pelo 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 mais informações sobre o CMSampleBuffer, consulte a documentação da Apple do CMSampleBuffer Desenvolvedor Documentação.

Executar a tarefa

Para executar o Detector de rostos, use o método detect() específico ao modo de corrida:

  • Imagem estática: detect(image:)
  • Vídeo: detect(videoFrame:timestampInMilliseconds:)
  • Transmissão ao vivo: detectAsync(image:timestampInMilliseconds:)

O detector de rostos retorna os rostos detectados na imagem ou frame de entrada.

Os exemplos de código a seguir mostram exemplos simples de como executar o Face Detector no estes diferentes modos de execução:

Swift

Imagem

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

Vídeo

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

Transmissão ao vivo

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

Objective-C

Imagem

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

Vídeo

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

Transmissão ao vivo

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

O exemplo de código do detector de rostos mostra as implementações de cada um desses modos. em mais detalhes detect(image:), detect(videoFrame:timestampInMilliseconds:), e detectAsync(image:timestampInMilliseconds:). O código de exemplo permite que que o usuário alterne entre os modos de processamento que podem não ser necessários caso.

Observe o seguinte:

  • Ao executar no modo de vídeo ou de transmissão ao vivo, você também precisa fornecer o carimbo de data/hora do frame de entrada para a tarefa "Face Detector".

  • Quando executado no modo de imagem ou vídeo, a tarefa Detector de rostos bloqueia os linha de execução atual até terminar de processar a imagem ou frame de entrada. Para evite o bloqueio da linha de execução atual, execute o processamento em segundo plano conversa usando iOS Dispatch ou NSOperation frameworks.

  • Quando executado no modo de transmissão ao vivo, a tarefa do Detector de rostos retorna imediatamente. e não bloqueia a linha de execução atual. Ele invoca Método faceDetector(_:didFinishDetection:timestampInMilliseconds:error:) com o resultado da detecção facial após o processamento de cada frame de entrada. A O Face Detector invoca esse método de forma assíncrona em um número de série dedicado fila de despacho. Para exibir resultados na interface do usuário, envie o para a fila principal após o processamento dos resultados. Se o detectAsync é chamada quando a tarefa do Detector de rostos está ocupada processando outro o Face Detector ignorará o novo frame de entrada.

Gerenciar e exibir resultados

Ao executar a inferência, a tarefa do detector de rostos retorna um FaceDetectorResult. que contém as caixas delimitadoras para os rostos detectados e um valor de uma pontuação para cada rosto detectado.

Confira abaixo um exemplo dos dados de saída desta tarefa:

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)

A imagem abaixo mostra uma visualização da saída da tarefa:

Para a imagem sem caixas delimitadoras, consulte a imagem original.

O código de exemplo do detector de rostos demonstra como mostrar os resultados. Consulte a exemplo de código para mais detalhes.