A tarefa MediaPipe Face Scoreer permite detectar pontos de referência de rostos e expressões faciais em imagens e vídeos. Você pode usar essa tarefa para identificar expressões faciais humanas, aplicar filtros e efeitos faciais e criar avatares virtuais. Essa tarefa usa modelos de machine learning (ML) que podem funcionar com imagens únicas, vídeos ou um fluxo contínuo de imagens. A tarefa gera pontos de referência tridimensionais faciais, pontuações de formas mistas (coeficientes que representam expressões faciais) para inferir superfícies faciais detalhadas em tempo real e matrizes de transformação para realizar as transformações necessárias para a renderização de efeitos.
O exemplo de código descrito nestas instruções está disponível no GitHub. Confira esta demonstração na Web para ver essa tarefa em ação. Para mais informações sobre os recursos, modelos e opções de configuração dessa tarefa, consulte a Visão geral.
Exemplo de código
O código de exemplo do MediaPipe Tasks é uma implementação básica de um app de marco de rostos para iOS. O exemplo usa a câmera em um dispositivo iOS físico para detectar pontos de referência faciais em uma transmissão de vídeo contínua. O app também pode detectar características faciais em imagens e vídeos da galeria do dispositivo.
Você pode usar o app como ponto de partida para o seu app iOS ou se referir a ele ao modificar um app existente. O código de exemplo do Face Landmarker 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 Face Landmarker:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/face_landmarker/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 abaixo contêm o código crucial para o exemplo de aplicativo Face Landmarker:
- FaceLandmarkerService.swift: inicializa o Face Landmarker, processa a seleção de modelo e executa a inferência nos dados de entrada.
- CameraViewController.swift: implementa a interface do modo de entrada de feed de câmera ao vivo e visualiza os resultados.
- MediaLibraryViewController.swift: implementa a interface para os modos de entrada de imagem e arquivo de vídeo e visualiza os resultados.
Configuração
Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código para usar o Face Landmarker. 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 Face Markdown usa a biblioteca MediaPipeTasksVision
, que precisa ser instalada
com 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 'MyFaceLandmarkerApp' 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 MediaPipe Face Landmarker requer um pacote de modelo treinado que seja compatível com essa tarefa. Para mais informações sobre os modelos treinados disponíveis para o Face Pointser, consulte a visão geral da tarefa Seção 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 projeto do Xcode, consulte Como 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 de detecção de pontos de referência do rosto chamando um dos inicializadores dela. O inicializador
FaceLandmarker(options:)
aceita valores para as opções de
configuração.
Se você não precisar que um Face Markdown com opções de configuração personalizadas seja inicializado com opções de configuração
personalizadas, use o inicializador FaceLandmarker(modelPath:)
para criar um
Face Markdown com as opções padrão. Para mais informações sobre as opções de configuração, consulte a Visão geral da configuração.
A tarefa Face Landmarker 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, FaceLandmarker(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 FaceLandmarker(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
faceLandmarkerLiveStreamDelegate
extra, que permite que o
Face Marcer forneça resultados desse tipo ao delegado de forma assíncrona.
Escolha a guia correspondente ao 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: "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)
Vídeo
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)
Transmissão ao 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
Imagem
@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];
Vídeo
@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];
Transmissão ao 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];
Observação:se você usar o modo de vídeo ou de transmissão ao vivo, o Face Markdown vai usar o rastreamento para evitar o acionamento do 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 para a tarefa. O Face Landmarker tem três modos:
IMAGE: 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 de dados de entrada, como de uma câmera. Nesse modo, "faceLandmarkerLiveStreamDelegate" precisa ser definido como uma instância de uma classe que implementa "FaceLandmarkerLiveStreamDelegate" para receber os resultados da detecção de pontos de referência do rosto de forma assíncrona. |
{RunningMode.image, RunningMode.video, RunningMode.liveStream} | {RunningMode.image} |
numFaces |
O número máximo de rostos que podem ser detectados pelo Face Landmarker. A suavização só é aplicada quando numFaces é definida como 1. | Número inteiro maior que 0 | 1 |
minFaceDetectionConfidence |
A pontuação de confiança mínima para que a detecção de rosto seja considerada bem-sucedida. | Ponto flutuante [0.0,1.0] | 0,5 |
minFacePresenceConfidence |
A pontuação de confiança mínima da pontuação de presença do rosto na detecção de ponto de referência do rosto. | Float [0.0,1.0] | 0,5 |
minTrackingConfidence |
A pontuação de confiança mínima para que o rastreamento de rosto seja considerado bem-sucedido. | Float [0.0,1.0] | 0,5 |
outputFaceBlendshapes |
Se o FaceLandmarker vai gerar blendshapes faciais. As blendshapes do rosto são usadas para renderizar o modelo de rosto 3D. | Booleano | falso |
outputFacialTransformationMatrixes |
Define se FaceLandmarker gera a matriz de transformação facial. O FaceLandmarker usa a matriz para transformar os pontos de referência do rosto de um modelo canônico para o rosto detectado, para que os usuários possam aplicar efeitos nos pontos de referência detectados. | Booleano | falso |
Quando o modo de execução está definido como LIVE_STREAM
, o Face Landmarker requer a
opção de configuração faceLandmarkerLiveStreamDelegate
adicional, que
permite que o Face Landmarker forneça resultados de detecção de pontos de referência do rosto
de forma assíncrona. O delegado precisa implementar o
método faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
,
que o Face Landmarker chama após processar os resultados da detecção de
pontos de referência faciais em cada frame.
Nome da opção | Descrição | Intervalo de valor | Valor padrão |
---|---|---|---|
faceLandmarkerLiveStreamDelegate |
Permite que o Face Landmarker receba os resultados da detecção de pontos de referência do rosto de forma assíncrona no modo de transmissão ao vivo. A classe que tem a
instância definida para essa propriedade precisa implementar o
método
faceLandmarker(_: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 Face Landmarker. MPImage
oferece suporte a diferentes tipos de formatos de imagem
do iOS e pode usá-los em qualquer modo em 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
exigido 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: imagens de um pacote de apps, uma galeria do usuário ou um sistema de arquivos formatadas como imagens
UIImage
podem ser convertidas em um objetoMPImage
.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 uma MPImage
com a orientação
UIImage.Orientation.Up
padrão. É possível inicializar uma MPImage
com qualquer um dos valores
UIImage.Orientation
compatíveis. O marco facial não oferece suporte a orientações espelhadas, como .upMirrored
,
.downMirrored
, .leftMirrored
, .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
CVPixelBuffer
após algum processamento usando o frameworkCoreImage
do iOS podem ser enviados para o Face Landmarker no modo de execução de imagem.Vídeos: os frames de vídeo podem ser convertidos para o formato
CVPixelBuffer
para processamento e, em seguida, enviados para o marco de rostos 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
CVPixelBuffer
para processamento antes de serem enviados ao Face Markdown 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 do desenvolvedor da Apple
CMSampleBuffer (em inglês).
Executar a tarefa
Para executar o Face Landmarker, 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:)
Os exemplos de código a seguir mostram exemplos básicos de como executar o Face Landmarker nesses diferentes modos de execução:
Swift
Imagem
let result = try faceLandmarker.detect(image: image)
Vídeo
let result = try faceLandmarker.detect( videoFrame: image, timestampInMilliseconds: timestamp)
Transmissão ao vivo
try faceLandmarker.detectAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
Imagem
MPPFaceLandmarkerResult *result = [faceLandmarker detectImage:image error:nil];
Vídeo
MPPFaceLandmarkerResult *result = [faceLandmarker detectVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Transmissão ao vivo
BOOL success = [faceLandmarker detectAsyncImage:image timestampInMilliseconds:timestamp error:nil];
O exemplo de código do Face Landmarker 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, você também precisa fornecer o carimbo de data/hora do frame de entrada para a tarefa "Face Markdowner".
Quando executada no modo de imagem ou vídeo, a tarefa do Face Landmarker 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. Se o app for criado usando Swift, você também poderá usar a concorrência do Swift para a execução de linhas de execução em segundo plano.
Quando executada no modo de transmissão ao vivo, a tarefa "Face Markdowner" retorna imediatamente e não bloqueia a linha de execução atual. Ele invoca o método
faceLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
com o resultado da detecção de pontos de referência facial após o processamento de cada frame de entrada. O Face Landmarker 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 depois de processá-los.
Processar e mostrar resultados
Ao executar a inferência, o Face Landmarker retorna uma FaceLandmarkerResult
, que
contém uma malha de rosto para cada rosto detectado, com coordenadas para cada ponto de referência
do rosto. Opcionalmente, o objeto de resultado também pode conter blendshapes, que
denotam expressões faciais, e matrizes de transformação facial para aplicar efeitos
faciais nos pontos de referência detectados.
Confira a seguir um exemplo dos dados de saída desta tarefa:
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]
...
A imagem abaixo mostra uma visualização da saída da tarefa:
O código de exemplo do Face Landmarker demonstra como mostrar os resultados retornados pela tarefa. Consulte FaceOverlay.swift para mais detalhes.