A tarefa "MediaPipe Pose extraser" permite detectar pontos de referência de corpos humanos em uma imagem ou um 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 poses corporais em coordenadas de imagem e em coordenadas mundiais tridimensionais.
O exemplo de código descrito nestas instruções está disponível no GitHub. 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 simples de um app "Pose stageer" para Android. No exemplo, a câmera de um dispositivo Android físico é usada para detectar poses em um stream de vídeo contínuo. O app também pode detectar poses em imagens e vídeos da galeria de dispositivos.
Você pode usar o app como ponto de partida para seu próprio app Android ou se referir a ele ao modificar um app já existente. O código de exemplo "Pose Stadiumer" está hospedado no GitHub (em inglês).
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 git usando o seguinte comando:
git clone https://github.com/google-ai-edge/mediapipe-samples
- Como opção, configure sua instância git para usar a finalização da compra esparsa para que você tenha
apenas os arquivos do app de exemplo Pose extras:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/pose_landmarker/android
Depois de criar uma versão local do código de exemplo, você poderá importar o projeto para o Android Studio e executar o app. Para conferir instruções, consulte o Guia de configuração para Android.
Principais componentes
Os arquivos a seguir contêm o código essencial para este aplicativo de exemplo de pontos de referência:
- PoseLandmarkerHelper.kt: inicializa o ponto de referência de poses, processa o modelo e delega a seleção.
- CameraFragment.kt: gerencia a câmera do dispositivo e processa os dados de entrada de imagem e vídeo.
- GalleryFragment.kt: interage com
OverlayView
para mostrar a imagem ou o vídeo de saída. - OverlayView.kt: implementa a exibição das poses detectadas.
Configuração
Nesta seção, descrevemos as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código para usar o Pose extras. Para ter informações gerais sobre como configurar seu ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo requisitos de versão da plataforma, consulte o Guia de configuração para Android.
Dependências
A tarefa "Posse de ponto de referência" usa a biblioteca com.google.mediapipe:tasks-vision
. Adicione esta dependência ao arquivo build.gradle
do seu app Android:
dependencies {
implementation 'com.google.mediapipe:tasks-vision:latest.release'
}
Modelo
A tarefa "MediaPipe Pose extras" requer um pacote de modelos treinados e compatível com ela. Para mais informações sobre os modelos treinados disponíveis para o "Pose extras", consulte a visão geral da tarefa Seção de modelos.
Selecione, faça o download do modelo e armazene-o no diretório do projeto:
<dev-project-root>/src/main/assets
Especifique o caminho do modelo no parâmetro ModelAssetPath
. No
código de exemplo, o modelo é definido no
arquivo
PoseLandmarkerHelper.kt
:
val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)
Criar a tarefa
A tarefa MediaPipe Pose extras usa a função createFromOptions()
para configurar a
tarefa. A função createFromOptions()
aceita valores para as opções de
configuração. Para mais informações sobre as opções de configuração, consulte Opções de
configuração.
O ponto de referência de postura é compatível com os seguintes tipos de dados de entrada: imagens estáticas, arquivos de vídeo e streams de vídeo ao vivo. Ao criar a tarefa, é necessário especificar o modo de execução correspondente ao tipo de dados de entrada. Escolha a guia do tipo de dados de entrada para saber como criar a tarefa.
Imagem
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setRunningMode(RunningMode.IMAGE) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
Video
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setRunningMode(RunningMode.VIDEO) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
Transmissão ao vivo
val baseOptionsBuilder = BaseOptions.builder().setModelAssetPath(modelName) val baseOptions = baseOptionBuilder.build() val optionsBuilder = poseLandmarker.poseLandmarkerOptions.builder() .setBaseOptions(baseOptionsBuilder.build()) .setMinPoseDetectionConfidence(minPoseDetectionConfidence) .setMinTrackingConfidence(minPoseTrackingConfidence) .setMinPosePresenceConfidence(minposePresenceConfidence) .setNumPoses(maxNumPoses) .setResultListener(this::returnLivestreamResult) .setErrorListener(this::returnLivestreamError) .setRunningMode(RunningMode.LIVE_STREAM) val options = optionsBuilder.build() poseLandmarker = poseLandmarker.createFromOptions(context, options)
A implementação de código de exemplo "Pose Highlighter" permite que o usuário alterne entre
modos de processamento. A abordagem torna o código de criação da tarefa mais complicado e
pode não ser apropriada para seu caso de uso. É possível conferir esse código na função setupPoseLandmarker()
no arquivo PoseLandmarkerHelper.kt
.
Opções de configuração
Esta tarefa tem as seguintes opções de configuração para apps Android:
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. VIDEO: o modo para frames decodificados de um vídeo. LIVE_STREAM: é o modo para 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. |
{IMAGE, VIDEO, LIVE_STREAM } |
IMAGE |
numposes |
O número máximo de poses que podem ser detectadas pelo ponto de referência da postura. | Integer > 0 |
1 |
minPoseDetectionConfidence |
A pontuação de confiança mínima para que a detecção de poses seja considerada bem-sucedida. | Float [0.0,1.0] |
0.5 |
minPosePresenceConfidence |
A pontuação de confiança mínima da pontuação de presença de poses na detecção de pontos de referência de poses. | Float [0.0,1.0] |
0.5 |
minTrackingConfidence |
A pontuação de confiança mínima para que o rastreamento de poses seja considerado bem-sucedido. | Float [0.0,1.0] |
0.5 |
outputSegmentationMasks |
Define se o "Pose extras" gera uma máscara de segmentação para a pose detectada. | Boolean |
False |
resultListener |
Define o listener de resultado para receber os resultados do ponto de referência de forma assíncrona quando o elemento "Pose extras" 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 |
errorListener |
Define um listener de erro opcional. | ErrorListener |
N/A |
preparar dados
O Pose Pointser funciona com imagens, arquivos de vídeo e streams de vídeo ao vivo. A tarefa lida com o pré-processamento da entrada de dados, incluindo redimensionamento, rotação e normalização de valores.
O código a seguir demonstra como transferir dados para processamento. Esses exemplos incluem detalhes sobre como lidar com dados de imagens, arquivos de vídeo e streams de vídeo ao vivo.
Imagem
import com.google.mediapipe.framework.image.BitmapImageBuilder import com.google.mediapipe.framework.image.MPImage // Convert the input Bitmap object to an MPImage object to run inference val mpImage = BitmapImageBuilder(image).build()
Video
import com.google.mediapipe.framework.image.BitmapImageBuilder import com.google.mediapipe.framework.image.MPImage val argb8888Frame = if (frame.config == Bitmap.Config.ARGB_8888) frame else frame.copy(Bitmap.Config.ARGB_8888, false) // Convert the input Bitmap object to an MPImage object to run inference val mpImage = BitmapImageBuilder(argb8888Frame).build()
Transmissão ao vivo
import com.google.mediapipe.framework.image.BitmapImageBuilder import com.google.mediapipe.framework.image.MPImage // Convert the input Bitmap object to an MPImage object to run inference val mpImage = BitmapImageBuilder(rotatedBitmap).build()
No código de exemplo do "Pose extras", a preparação de dados é processada no
arquivo
PoseLandmarkerHelper.kt
.
Executar a tarefa
Dependendo do tipo de dados com que você está trabalhando, use o
método poseLandmarker.detect...()
específico para esse tipo de dados. Use
detect()
para imagens individuais, detectForVideo()
para frames em arquivos de vídeo
e detectAsync()
para streams de vídeo. Ao realizar detecções em um
stream de vídeo, execute-as em uma linha de execução separada para evitar
o bloqueio dela.
Os exemplos de código a seguir mostram exemplos simples de como executar o "Pose stageer" nesses modos de dados diferentes:
Imagem
val result = poseLandmarker.detect(mpImage)
Video
val timestampMs = i * inferenceIntervalMs poseLandmarker.detectForVideo(mpImage, timestampMs) .let { detectionResult -> resultList.add(detectionResult) }
Transmissão ao vivo
val mpImage = BitmapImageBuilder(rotatedBitmap).build() val frameTime = SystemClock.uptimeMillis() poseLandmarker.detectAsync(mpImage, frameTime)
Observe o seguinte:
- Ao executar no modo de vídeo ou de transmissão ao vivo, é necessário fornecer o carimbo de data/hora do frame de entrada para a tarefa "Posse de ponto de referência".
- Quando executada no modo de imagem ou vídeo, a tarefa "Pose extras" bloqueia a linha de execução atual até terminar de processar a imagem ou o frame de entrada. Para evitar o bloqueio da interposição do usuário, execute o processamento em uma linha de execução em segundo plano.
- Quando executada no modo de transmissão ao vivo, a tarefa "Posse de ponto de referência" retorna imediatamente e não bloqueia a linha de execução atual. Ele vai invocar o listener de resultados com o resultado da detecção sempre que terminar de processar um frame de entrada.
No código de exemplo "Pose vCenter", as funções detect
, detectForVideo
e
detectAsync
são definidas no
arquivo
PoseLandmarkerHelper.kt
.
Gerenciar e mostrar resultados
O ponto de referência de postura retorna um objeto poseLandmarkerResult
para cada execução de
detecção. O objeto de resultado contém coordenadas para cada ponto de referência de pose.
Veja a seguir um exemplo dos dados de saída dessa 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 (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 pela largura da imagem (x
) e altura (y
).z
: a profundidade do ponto de referência, com origem no ponto médio dos quadris. Quanto menor o valor, mais próximo o ponto de referência estará da câmera. A magnitude de z usa aproximadamente a mesma escala quex
.visibility
: a probabilidade do ponto de referência ser 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 do ponto de referência ser 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 a uma pessoa detectada. A imagem a seguir é uma máscara de segmentação da saída da tarefa:
O código de exemplo "Pose Stadium" demonstra como mostrar os resultados retornados
da tarefa. Consulte a
classe OverlayView
para saber mais.