A tarefa do detector de rostos permite detectar rostos em uma imagem ou vídeo. Você pode usar essa tarefa para localizar rostos e características faciais em um frame. Esta tarefa usa um modelo de aprendizado de máquina (ML) que funciona com imagens únicas ou um fluxo contínuo de imagens. A tarefa gera locais do rosto, além dos seguintes pontos-chave faciais: olho esquerdo, olho direito, ponta do nariz, boca, canto do olho esquerdo e canto do olho direito.
O exemplo de código descrito nestas instruções está disponível no GitHub. Confira esta demonstração da Web para conferir essa tarefa em ação. Para mais informações sobre os recursos, modelos e opções de configuração desta tarefa, consulte a Visão geral.
Exemplo de código
O código de exemplo do MediaPipe Tasks é uma implementação simples de um app de detecção facial para iOS. O exemplo usa a câmera em um dispositivo Android físico para detectar rostos em um fluxo 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 se referir a ele ao modificar um app existente. O código de exemplo do Face Detector está hospedado no GitHub.
Fazer o download do código
As instruções a seguir mostram como criar uma cópia local do código de exemplo usando a ferramenta de linha de comando git.
Para fazer o download do código de exemplo:
- Clone o repositório do Git usando o seguinte comando: - git clone https://github.com/google-ai-edge/mediapipe-samples
- Como opção, configure sua instância do git para usar o checkout esparso, para que você tenha apenas os arquivos do app de exemplo do Detector de rostos: - cd mediapipe-samples 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, é possível instalar a biblioteca de tarefas do MediaPipe, abrir o projeto usando o Xcode e executar o app. Para instruções, consulte o Guia de configuração para iOS.
Principais componentes
Os arquivos a seguir contêm o código crucial para o exemplo de aplicativo do Detector de rostos:
- FaceDetectorService.swift: inicializa o detector, processa a seleção de modelos e executa a inferência nos dados de entrada.
- CameraViewController: implementa a interface do modo de entrada de feed de câmera ao vivo e visualiza os resultados da detecção.
- MediaLibraryViewController.swift: implementa a interface do modo de entrada de imagem e arquivo de vídeo e mostra os resultados da detecção.
Configuração
Esta seção descreve as principais etapas para configurar o ambiente de desenvolvimento e os projetos de código para usar o Detector de rosto. Para informações gerais sobre como configurar seu ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo os requisitos de versão da plataforma, consulte o Guia de configuração para iOS.
Dependências
O Detector de rosto usa a biblioteca MediaPipeTasksVision, que precisa ser instalada
usando o CocoaPods. A biblioteca é compatível com apps Swift e Objective-C
e não requer nenhuma configuração específica da linguagem.
Para instruções sobre como instalar o CocoaPods no macOS, consulte o Guia de instalação
do CocoaPods.
Para instruções sobre como criar um Podfile com os pods necessários para seu
app, consulte Como usar
CocoaPods.
Adicione o pod 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 para
iOS para mais informações sobre como configurar
o Podfile.
Modelo
A tarefa do detector de rosto do MediaPipe exige um modelo treinado compatível com essa tarefa. Para mais informações sobre os modelos treinados disponíveis para o Face Detector, consulte a seção "Modelos" da visão geral da tarefa.
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 projeto do Xcode, consulte Gerenciar arquivos e pastas no projeto do Xcode.
Use a propriedade BaseOptions.modelAssetPath para especificar o caminho para o modelo
no app bundle. Para conferir um exemplo de código, consulte a próxima seção.
Criar a tarefa
É possível criar a tarefa do detector de rosto chamando um dos inicializadores. O
inicializador FaceDetector(options:) aceita valores para as opções de
configuração.
Se você não precisar de um detector de rosto inicializado com opções de configuração
personalizadas, use o inicializador FaceDetector(modelPath:) para criar um
detector de rosto com as opções padrão. Para mais informações sobre as opções de configuração, consulte Visão geral da configuração.
A tarefa do detector de rostos oferece suporte a três tipos de dados de entrada: imagens estáticas, arquivos de vídeo
e transmissões de vídeo ao vivo. Por padrão, FaceDetector(modelPath:) inicializa uma
tarefa para imagens estáticas. Se você quiser que a tarefa seja inicializada para processar arquivos
de vídeo ou transmissões de vídeo ao vivo, use FaceDetector(options:) para especificar o modo de execução
do vídeo ou da transmissão ao vivo. O modo de transmissão ao vivo também requer a opção de configuração
faceDetectorLiveStreamDelegate, que permite que o
Face Detector envie resultados de detecção de rosto para o delegado de forma assíncrona.
Escolha a guia correspondente ao seu modo de execução para saber como criar a tarefa e executar a 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ê usa o modo de vídeo ou de transmissão ao vivo, o detector de rosto usa o rastreamento para evitar acionar o modelo de detecção em cada frame, o que ajuda a 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. Há três
      modos: IMAGE: o modo para entradas de imagem única. VÍDEO: o modo para quadros decodificados de um vídeo. LIVE_STREAM: o modo de uma transmissão ao vivo de dados de entrada, como de uma câmera. Nesse modo, o resultListener precisa ser chamado para configurar um listener para 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 de rosto 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 de rostos seja considerada sobreposta. | Float [0,1] | 0.3 | 
Configuração de transmissão ao vivo
Quando o modo de execução está definido como transmissão ao vivo, o detector facial exige a
opção de configuração faceDetectorLiveStreamDelegate adicional, que permite
que o detector forneça resultados de detecção de forma assíncrona. O delegado
implementa o
método faceDetector(_:didFinishDetection:timestampInMilliseconds:error:),
que o Face Detector chama após processar os resultados da detecção facial para
cada frame.
| Nome da opção | Descrição | Intervalo de valor | Valor padrão | 
|---|---|---|---|
| faceDetectorLiveStreamDelegate | Permite que o detector de rosto receba resultados de detecção de rosto de forma assíncrona
    no modo de transmissão ao vivo. A classe com a instância definida para essa propriedade precisa
    implementar o método 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 de
transmiti-lo ao detector de rosto. O MPImage oferece suporte a diferentes tipos de formatos de imagem
do iOS e pode usá-los em qualquer modo de execução para inferência. Para mais
informações sobre MPImage, consulte a
API MPImage.
Escolha um formato de imagem do iOS com base no seu caso de uso e no modo de execução
requerido pelo aplicativo.MPImage aceita os formatos de imagem UIImage, CVPixelBuffer e
CMSampleBuffer do iOS.
UIImage
O formato UIImage é adequado para os seguintes modos de execução:
- Imagens: as imagens de um pacote de apps, galeria de usuários ou sistema de arquivos formatadas como - UIImagepodem ser convertidas em um objeto- MPImage.
- Vídeos: use AVAssetImageGenerator para extrair frames de vídeo no formato CGImage e converta-os 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 a orientação
padrão UIImage.Orientation.Up. É possível inicializar uma MPImage com qualquer um dos valores
UIImage.Orientation
compatíveis. O detector de rosto não oferece suporte a orientações espelhadas, como .upMirrored, .downMirrored, .leftMirrored e .rightMirrored.
Para mais informações sobre UIImage, consulte a documentação para desenvolvedores da Apple
de UIImage (em inglês).
CVPixelBuffer
O formato CVPixelBuffer é adequado para aplicativos que geram frames
e usam o framework CoreImage
do iOS para processamento.
O formato CVPixelBuffer é adequado para os seguintes modos de execução:
- Imagens: apps que geram imagens - CVPixelBufferapós algum processamento usando o framework- CoreImagedo iOS podem ser enviados ao detector de rosto no modo de execução de imagem.
- Vídeos: os frames de vídeo podem ser convertidos para o formato - CVPixelBufferpara processamento e, em seguida, enviados ao Face Detector no modo de vídeo.
- Transmissão ao vivo: os apps que usam uma câmera do iOS para gerar frames podem ser convertidos no formato - CVPixelBufferpara processamento antes de serem enviados ao Detector de faces 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 CVPixelBuffer, consulte a documentação
para desenvolvedores da Apple
CVPixelBuffer.
CMSampleBuffer
O formato CMSampleBuffer armazena amostras de mídia de um tipo uniforme e é
adequado para o modo de execução de transmissões ao vivo. Os frames ao vivo das câmeras do iOS são
enviados de forma assíncrona no formato CMSampleBuffer pelo
AVCaptureVideoDataOutput do 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];
Para mais informações sobre CMSampleBuffer, consulte a documentação
para desenvolvedores da Apple
CMSampleBuffer (em inglês).
Executar a tarefa
Para executar o detector de rosto, use o método detect() específico para o modo de execução
atribuído:
- Imagem estática: detect(image:)
- Vídeo: detect(videoFrame:timestampInMilliseconds:)
- Transmissão ao vivo: detectAsync(image:timestampInMilliseconds:)
O Face Detector retorna os rostos detectados na imagem ou no frame de entrada.
Os exemplos de código a seguir mostram exemplos simples de como executar o Detector de rostos nesses 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 rosto mostra as implementações de cada um desses modos
com mais detalhes detect(image:), detect(videoFrame:timestampInMilliseconds:)
e detectAsync(image:timestampInMilliseconds:). O código de exemplo permite que o
usuário alterne entre modos de processamento que podem não ser necessários para seu caso de
uso.
Observe o seguinte:
- Ao executar no modo de vídeo ou de transmissão ao vivo, também é necessário fornecer o carimbo de data/hora do frame de entrada para a tarefa do detector de rosto. 
- Quando executada no modo de imagem ou vídeo, a tarefa do detector de rosto bloqueia a linha de execução atual até que ela termine de processar a imagem ou o frame de entrada. Para evitar o bloqueio da linha de execução atual, execute o processamento em uma linha de execução em segundo plano usando os frameworks Dispatch ou NSOperation do iOS. 
- Quando executada no modo de transmissão ao vivo, a tarefa do detector de rosto retorna imediatamente e não bloqueia a linha de execução atual. Ele invoca o método - faceDetector(_:didFinishDetection:timestampInMilliseconds:error:)com o resultado da detecção de rosto após o processamento de cada frame de entrada. O Face Detector invoca esse método de forma assíncrona em uma fila de envio serial dedicada. Para mostrar os resultados na interface do usuário, envie os resultados para a fila principal após o processamento. Se a função- detectAsyncfor chamada quando a tarefa do detector de rosto estiver ocupada processando outro frame, o detector de rosto vai ignorar o novo frame de entrada.
Processar e mostrar resultados
Ao executar a inferência, a tarefa do detector de rostos retorna um objeto FaceDetectorResult
que contém as caixas delimitadoras dos rostos detectados e uma pontuação de
confiança para cada rosto detectado.
Confira a seguir 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 a seguir 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. Confira o exemplo de código para saber mais.