A tarefa Pose Scoreer permite detectar pontos de referência de corpos humanos em uma imagem ou vídeo. Você pode usar essa tarefa para identificar as principais localizações do corpo, analisar a postura, e categorizar movimentos. Essa tarefa usa modelos de machine learning (ML) que funcionam com imagens ou vídeos únicos. A tarefa gera pontos de referência de posições do corpo na imagem e em coordenadas mundiais tridimensionais.
Estas instruções mostram como usar o Pose Scoreer com apps iOS. O código o exemplo descrito nestas instruções está disponível em GitHub.
Para saber como essa tarefa funciona, acesse este site demonstração. Para mais informações sobre recursos, modelos e opções de configuração, desta tarefa, consulte a Visão geral.
Exemplo de código
O código de exemplo de tarefas do MediaPipe é uma implementação básica de um ponto de referência de posições para iOS. O exemplo usa a câmera de um dispositivo físico com iOS para detectar detectar poses em um stream de vídeo contínuo. O app também pode detectar poses 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 código de exemplo do Pose Scoreer é 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:
Clone o repositório git usando o seguinte comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
Opcionalmente, configure sua instância git para usar a finalização esparsa. Assim, você terá somente os arquivos do app de exemplo Pose Scoreer:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/pose_landmarker/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 Pose Scoreer. aplicativo:
- PoseLandmarkerService.swift: Inicia o referência, 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 a pontos de referência.
- MediaLibraryViewController.swift: Implementa a interface para o modo de entrada de arquivo de vídeo e imagem estática e visualiza os pontos de referência.
Configuração
Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código para usar o Pose Scoreer. 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 Pose Scoreer 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 'MyPoseLandmarkerApp' 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 "Ponto de referência de poses do MediaPipe" requer um pacote treinado que seja compatível a essa tarefa. Para mais informações sobre os modelos treinados disponíveis para Faça uma pose de referência, consulte a visão geral da tarefa Modelos .
Use o download_models.sh
script
para fazer o download dos modelos e adicioná-los ao diretório do projeto usando Xcode. Para
para adicionar arquivos ao seu projeto Xcode, consulte Como gerenciar arquivos
e pastas no seu arquivo 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
É possível criar a tarefa "Pose Scoreer" chamando um dos inicializadores dele. O
O inicializador PoseLandmarker(options:)
aceita valores para a configuração.
.
Se você não precisa de um ponto de referência de posições inicializado com configuração personalizada
você pode usar o inicializador PoseLandmarker(modelPath:)
para criar um
Posicione o ponto de referência com as opções padrão. Para mais informações sobre configurações
opções, consulte Visão geral da configuração.
A tarefa Pose Scoreer é 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, PoseLandmarker(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 PoseLandmarker(options:)
para especificar o
ou no modo de corrida ao vivo. O modo de transmissão ao vivo também requer
poseLandmarkerLiveStreamDelegate
, que ativa
Posicione o marco para entregar os resultados da detecção de pontos de referência de poses ao delegado
de forma 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: "pose_landmarker", ofType: "task") let options = PoseLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.minPoseDetectionConfidence = minPoseDetectionConfidence options.minPosePresenceConfidence = minPosePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numPoses = numPoses let poseLandmarker = try PoseLandmarker(options: options)
Vídeo
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "pose_landmarker", ofType: "task") let options = PoseLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.minPoseDetectionConfidence = minPoseDetectionConfidence options.minPosePresenceConfidence = minPosePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numPoses = numPoses let poseLandmarker = try PoseLandmarker(options: options)
Transmissão ao vivo
import MediaPipeTasksVision // Class that conforms to the `PoseLandmarkerLiveStreamDelegate` protocol and // implements the method that the pose landmarker calls once it finishes // performing pose landmark detection in each input frame. class PoseLandmarkerResultProcessor: NSObject, PoseLandmarkerLiveStreamDelegate { func poseLandmarker( _ poseLandmarker: PoseLandmarker, didFinishDetection result: PoseLandmarkerResult?, timestampInMilliseconds: Int, error: Error?) { // Process the pose landmarker result or errors here. } } let modelPath = Bundle.main.path(forResource: "pose_landmarker", ofType: "task") let options = PoseLandmarkerOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.minPoseDetectionConfidence = minPoseDetectionConfidence options.minPosePresenceConfidence = minPosePresenceConfidence options.minTrackingConfidence = minTrackingConfidence options.numPoses = numPoses // Assign an object of the class to the `poseLandmarkerLiveStreamDelegate` // property. let processor = PoseLandmarkerResultProcessor() options.poseLandmarkerLiveStreamDelegate = processor let poseLandmarker = try PoseLandmarker(options: options)
Objective-C
Imagem
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"pose_landmarker" ofType:@"task"]; MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.minPoseDetectionConfidence = minPoseDetectionConfidence; options.minPosePresenceConfidence = minPosePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numPoses = numPoses; MPPPoseLandmarker *poseLandmarker = [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
Vídeo
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"pose_landmarker" ofType:@"task"]; MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.minPoseDetectionConfidence = minPoseDetectionConfidence; options.minPosePresenceConfidence = minPosePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numPoses = numPoses; MPPPoseLandmarker *poseLandmarker = [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
Transmissão ao vivo
@import MediaPipeTasksVision; // Class that conforms to the `MPPPoseLandmarkerLiveStreamDelegate` protocol // and implements the method that the pose landmarker calls once it finishes // performing pose landmarks= detection in each input frame. @interface APPPoseLandmarkerResultProcessor : NSObject@end @implementation APPPoseLandmarkerResultProcessor - (void)poseLandmarker:(MPPPoseLandmarker *)poseLandmarker didFinishDetectionWithResult:(MPPPoseLandmarkerResult *)poseLandmarkerResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the pose landmarker result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"pose_landmarker" ofType:@"task"]; MPPPoseLandmarkerOptions *options = [[MPPPoseLandmarkerOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.minPoseDetectionConfidence = minPoseDetectionConfidence; options.minPosePresenceConfidence = minPosePresenceConfidence; options.minTrackingConfidence = minTrackingConfidence; options.numPoses = numPoses; // Assign an object of the class to the `poseLandmarkerLiveStreamDelegate` // property. APPPoseLandmarkerResultProcessor *processor = [APPPoseLandmarkerResultProcessor new]; options.poseLandmarkerLiveStreamDelegate = processor; MPPPoseLandmarker *poseLandmarker = [[MPPPoseLandmarker alloc] initWithOptions:options error:nil];
Observação:se você usar o modo de vídeo ou de transmissão ao vivo, o ponto de referência de postura usará para evitar o acionamento do modelo de detecção de palma em cada frame, o que ajuda 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 |
---|---|---|---|
running_mode |
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, poseLandmarkerLiveStreamDelegate precisa ser definido como
uma instância de uma classe que implementa o
PoseLandmarkerLiveStreamDelegate para receber os resultados de
realizando detecção de ponto de referência de pose de forma assíncrona.
|
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
num_poses |
O número máximo de poses que podem ser detectadas pelo Faça uma pose de referência. | Integer > 0 |
1 |
min_pose_detection_confidence |
A pontuação de confiança mínima para que a detecção de pose seja considerada bem-sucedida. | Float [0.0,1.0] |
0.5 |
min_pose_presence_confidence |
A pontuação de confiança mínima da presença de pose na detecção de pontos de referência de poses. | Float [0.0,1.0] |
0.5 |
min_tracking_confidence |
A pontuação de confiança mínima para o rastreamento de pose para ser considerado bem-sucedido. | Float [0.0,1.0] |
0.5 |
output_segmentation_masks |
Define se o Pose Scoreer gera uma máscara de segmentação para o objeto detectado. pose | Boolean |
False |
result_callback |
Define o listener de resultados para receber os resultados do detector de ponto de referência.
de forma assíncrona quando o marcador de posição está no modo de transmissão ao vivo.
Só pode ser usado quando o modo de corrida está definido como LIVE_STREAM |
ResultListener |
N/A |
Configuração da transmissão ao vivo
Quando o modo de corrida está definido como transmissão ao vivo, o Pose Scoreer requer o
opção de configuração poseLandmarkerLiveStreamDelegate
extra, que
permite que o Pose Scoreer forneça resultados de detecção de poses de pontos de referência
de forma assíncrona. O delegado deve implementar o
método poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
,
que o posto de referência chama depois de processar os resultados da postura
detecção de pontos de referência em cada frame.
Nome da opção | Descrição | Intervalo de valor | Valor padrão |
---|---|---|---|
poseLandmarkerLiveStreamDelegate |
Permite que o marcador de posição receba os resultados da pose
detecção de pontos de referência de forma assíncrona no modo de transmissão ao vivo. A classe cuja
estiver definida como essa propriedade deve implementar o
poseLandmarker(_: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
passando para o Ponto de referência da postura. 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 objetoMPImage
.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 ponto de referência de posições não é compatível com 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 frameworkCoreImage
do iOS, podem ser enviadas ao Pose Scoreer na modo de execução de imagem.Vídeos: os quadros podem ser convertidos para o formato
CVPixelBuffer
para processamento e, em seguida, enviada para o ponto de referência de posições 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 Posicione o marco 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 ponto de referência de poses, use o método detect()
específico para o
modo de corrida:
- 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 simples de como executar o Pose Scoreer em estes diferentes modos de execução:
Swift
Imagem
let result = try poseLandmarker.detect(image: image)
Vídeo
let result = try poseLandmarker.detect( videoFrame: image, timestampInMilliseconds: timestamp)
Transmissão ao vivo
try poseLandmarker.detectAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
Imagem
MPPPoseLandmarkerResult *result = [poseLandmarker detectImage:image error:nil];
Vídeo
MPPPoseLandmarkerResult *result = [poseLandmarker detectVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Transmissão ao vivo
BOOL success = [poseLandmarker detectAsyncImage:image timestampInMilliseconds:timestamp error:nil];
O exemplo de código do Pose Scoreer 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 Pose Scoreer.
Quando executada no modo de imagem ou vídeo, a tarefa Pose Scoreer bloqueia o 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 executada no modo de transmissão ao vivo, a tarefa "Pose Scoreer" retorna imediatamente e não bloqueia a linha de execução atual. Ele invoca Método
poseLandmarker(_:didFinishDetection:timestampInMilliseconds:error:)
com o resultado do ponto de referência da pose após o processamento de cada frame de entrada. O O Pose Scoreer 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 odetectAsync
é chamada quando a tarefa "Ponto de referência de postura" está ocupada processando outro o frameer de posições ignora o novo frame de entrada.
Gerenciar e exibir resultados
Ao executar a inferência, a tarefa "Pose Scoreer" retorna um PoseLandmarkerResult
.
que contém as coordenadas de cada ponto de referência da pose.
Confira abaixo um exemplo dos dados de saída desta tarefa:
PoseLandmarkerResult:
Landmarks:
Landmark #0:
x : 0.638852
y : 0.671197
z : 0.129959
visibility : 0.9999997615814209
presence : 0.9999984502792358
Landmark #1:
x : 0.634599
y : 0.536441
z : -0.06984
visibility : 0.999909
presence : 0.999958
... (33 landmarks per pose)
WorldLandmarks:
Landmark #0:
x : 0.067485
y : 0.031084
z : 0.055223
visibility : 0.9999997615814209
presence : 0.9999984502792358
Landmark #1:
x : 0.063209
y : -0.00382
z : 0.020920
visibility : 0.999976
presence : 0.999998
... (33 world landmarks per pose)
SegmentationMasks:
... (pictured below)
A saída contém coordenadas normalizadas (Landmarks
) e coordenadas mundiais
coordenadas (WorldLandmarks
) para cada ponto de referência.
A saída contém as seguintes coordenadas normalizadas (Landmarks
):
x
ey
: coordenadas de ponto de referência normalizadas entre 0,0 e 1,0 pelo largura (x
) e altura (y
) da imagem.z
: a profundidade do ponto de referência, com a profundidade no ponto médio dos quadris como origem. Quanto menor o valor, mais perto o ponto de referência está da câmera. O a magnitude de z usa aproximadamente a mesma escala dex
.visibility
: a probabilidade de o ponto de referência ficar visível na imagem.
A saída contém as seguintes coordenadas mundiais (WorldLandmarks
):
x
,y
ez
: coordenadas tridimensionais reais em metros, com o ponto médio dos quadris como origem.visibility
: a probabilidade de o ponto de referência ficar visível na imagem.
A imagem abaixo mostra uma visualização da saída da tarefa:
A máscara de segmentação opcional representa a probabilidade de cada pixel pertencer para uma pessoa detectada. A imagem a seguir é uma máscara de segmentação da saída da tarefa:
O código de exemplo do Pose Scoreer demonstra como exibir o Pose Scoreer. resultados.