姿势特征点检测指南(Android 版)

通过 MediaPipe 姿势特征点标记器任务,您可以检测图像中人体的特征点,或 视频。您可以使用此任务来识别身体的关键位置、分析姿势、 以及对动作进行分类。此任务使用机器学习 (ML) 模型, 处理单一图片或视频。该任务会输出图片中的身体姿势特征点 坐标和三维世界坐标。

您可在 GitHub 如需详细了解功能、模型和配置选项 部分,请参阅概览

代码示例

MediaPipe Tasks 示例代码是姿势特征点的简单实现 Android 版应用。该示例使用 Android 实体设备上的相机 连续视频串流中的姿势。该应用还可以检测姿势 从设备图库中选择图片和视频

您可以用该应用作为基础来开发自己的 Android 应用,也可以指代该应用 对现有应用进行了修改。姿势特征点器示例代码托管在 GitHub

下载代码

以下说明介绍了如何创建示例的本地副本 使用 git 命令行工具运行 git 代码库。

<ph type="x-smartling-placeholder">

如需下载示例代码,请执行以下操作:

  1. 使用以下命令克隆 git 代码库:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. (可选)配置您的 git 实例以使用稀疏检出,这样您 仅提供姿势特征符示例应用的文件:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/pose_landmarker/android
    

创建示例代码的本地版本后,您可以导入项目 进入 Android Studio 并运行应用。有关说明,请参阅适用于 Android 设备

关键组件

以下文件包含此姿势地标示例的关键代码 应用:

设置

本部分介绍了设置开发环境和 专门用于使用姿势特征点 (Pose Markerer) 的代码项目。有关 设置开发环境以使用 MediaPipe 任务,包括 平台版本要求,请参阅适用于 Android 设备

<ph type="x-smartling-placeholder">

依赖项

姿势地标器任务使用 com.google.mediapipe:tasks-vision 库。将 将此依赖项添加到 Android 应用的 build.gradle 文件中:

dependencies {
    implementation 'com.google.mediapipe:tasks-vision:latest.release'
}

型号

MediaPipe 姿势地标器任务需要一个与以下对象兼容的经过训练的模型包: 此任务。如需详细了解姿势特征点工具可用的经过训练的模型, 请参阅任务概览的“模型”部分

选择并下载模型,并将其存储在项目目录中:

<dev-project-root>/src/main/assets

ModelAssetPath 参数中指定模型的路径。在 示例代码,则模型是在 PoseLandmarkerHelper.kt 文件:

val modelName = "pose_landmarker_lite.task"
baseOptionsBuilder.setModelAssetPath(modelName)

创建任务

MediaPipe 姿势地标器任务使用 createFromOptions() 函数来设置 任务。createFromOptions() 函数接受配置的值 选项。如需详细了解配置选项,请参阅配置选项 选项

姿势特征点器支持以下输入数据类型:静态图片、视频 文件以及实时视频流。你需要指定跑步模式 与输入数据类型相对应的日期。选择标签页 输入数据类型,了解如何创建任务。

映像

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)
    

视频

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)
    

直播

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)
    

姿势地标器示例代码实现可让用户在 处理模式这种方法使得任务创建代码更加复杂, 可能不适合您的用例。您可以在 setupPoseLandmarker() 函数, PoseLandmarkerHelper.kt 文件。

配置选项

此任务具有以下适用于 Android 应用的配置选项:

选项名称 说明 值范围 默认值
runningMode 设置任务的运行模式。有三个 模式:

IMAGE:单图输入的模式。

VIDEO:视频已解码帧的模式。

LIVE_STREAM:输入流媒体直播模式 例如来自相机的数据。 在此模式下,resultListener 必须为 调用以设置监听器以接收结果 异步执行。
{IMAGE, VIDEO, LIVE_STREAM} IMAGE
numposes 通过 姿势特征点。 Integer > 0 1
minPoseDetectionConfidence 姿势检测要计算的最低置信度分数 则视为成功 Float [0.0,1.0] 0.5
minPosePresenceConfidence 姿势存在的最低置信度分数 得分。 Float [0.0,1.0] 0.5
minTrackingConfidence 姿势跟踪的最低置信度分数 才会被视为成功 Float [0.0,1.0] 0.5
outputSegmentationMasks 姿势特征点是否针对检测到的对象输出分割掩码 姿势。 Boolean False
resultListener 设置结果监听器以接收地标器结果 姿势地标器处于直播模式时异步执行。 仅在跑步模式设为“LIVE_STREAM”时才能使用 ResultListener N/A
errorListener 设置一个可选的错误监听器。 ErrorListener N/A

准备数据

姿势地标器适用于图片、视频文件和直播视频流。任务 处理数据输入预处理,包括调整大小、旋转和值 标准化。

以下代码演示了如何移交数据进行处理。这些 示例包括关于如何处理来自图片、视频文件和实时 视频流。

映像

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()
    

视频

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()
    

直播

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()
    

在姿势特征符示例代码中,数据准备在 PoseLandmarkerHelper.kt 文件。

运行任务

根据您处理的数据类型,使用 poseLandmarker.detect...() 方法。使用 detect() 表示单张图片,detectForVideo() 表示视频文件中的帧, detectAsync() 表示视频流。当您在 Google Analytics 4 上 则务必在单独的线程中运行检测, 阻塞用户插入线程。

以下代码示例展示如何运行姿势特征点标记的简单示例 数据模式:

映像

val result = poseLandmarker.detect(mpImage)
    

视频

val timestampMs = i * inferenceIntervalMs

poseLandmarker.detectForVideo(mpImage, timestampMs)
    .let { detectionResult ->
        resultList.add(detectionResult)
    }
    

直播

val mpImage = BitmapImageBuilder(rotatedBitmap).build()
val frameTime = SystemClock.uptimeMillis()

poseLandmarker.detectAsync(mpImage, frameTime)
    

请注意以下几点:

  • 在视频模式或直播模式下投放广告时,您必须提供 姿势地标器任务的输入帧的时间戳。
  • 在图片模式或视频模式下运行时,姿势地标器任务会阻塞 当前线程,直到它处理完输入图像或帧。接收者 避免阻止用户干预,在后台执行处理 线程。
  • 在直播模式下运行时,姿势地标器任务会返回 而且不会阻塞当前线程它将调用结果 并在每次处理完一个监听器后都返回检测结果 输入帧。

在姿势特征点示例代码中,detectdetectForVideodetectAsync 函数在 PoseLandmarkerHelper.kt 文件。

处理和显示结果

姿势特征点器会针对每次检测返回一个 poseLandmarkerResult 对象 运行。结果对象包含每个姿势地标的坐标。

以下示例展示了此任务的输出数据:

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)

输出结果同时包含标准化坐标 (Landmarks) 和世界坐标 坐标 (WorldLandmarks)。

输出包含以下标准化坐标 (Landmarks):

  • xy:由 图片宽度 (x) 和高度 (y)。

  • z:地标深度,臀部中点的深度作为 来源。值越小,地标就越靠近镜头。通过 z 的量级使用的比例与 x 大致相同。

  • visibility:地标在图片中可见的可能性。

输出包含以下世界坐标 (WorldLandmarks):

  • xyz:真实的三维坐标(以米为单位), 作为原点。

  • visibility:地标在图片中可见的可能性。

下图直观显示了任务输出:

可选的分割掩码表示每个像素 。下图是 任务输出:

姿势地标器示例代码演示了如何显示返回的结果 请参阅 OverlayView 类以了解更多详情。