编辑丨机器之心

近日,来自谷歌的研究者更新了用于实时姿态检测的项目,该项目包含 3 种 SOTA 模型,其中 MoveNet 模型可检测人体 17 个关键点、并以 50+ fps 在电脑和手机端运行;BlazePose 可检测人体 33 个关键点;PoseNet 可以检测人体多个姿态,每个姿态包含 17 个关键点。

不久之前谷歌研究院推出了最新的姿态检测模型 MoveNet,并在 TensorFlow.js 中推出了新的姿态检测 API,该模型可以非常快速、准确地检测人体的 17 个关键节点。这一开源项目对于姿态检测以及机器学习领域来说,是一件非常有意义的事。

最近,来自谷歌的研究者又更新了一个新的项目,该项目提供了包括 MoveNet 在内的多个可用于实时姿态检测的 SOTA 模型,目前该项目已有 3 种可选模型:

  • MoveNet:是一种速度快、准确率高的姿态检测模型,可检测人体的 17 个关键点,能够以 50+ fps 的速度在笔记本电脑和手机上运行。
  • BlazePose:MediaPipe BlazePose 可以检测人体 33 个关键点,除了 17 个 COCO 关键点之外,它还为脸部、手和脚提供了额外的关键点检测。
  • PoseNet:可以检测多个姿态,每个姿态包含 17 个关键点。

安卓 GPU使用状态监控 手机gpu实时监测_机器学习

项目地址:https://github.com/tensorflow/tfjs-models/tree/master/pose-detection

其中 MoveNet 模型效果是这样的:下图中MoveNet 在跟踪人锻炼过程中的运动,可以实时、准确的检测人体关键点。值得注意的是,此时 MoveNet 一次只针对一个人进行了优化。

安卓 GPU使用状态监控 手机gpu实时监测_编程语言_02

MoveNet 在移动应用程序中示例:

安卓 GPU使用状态监控 手机gpu实时监测_深度学习_03

在上述示例中,MoveNet 用到了 FormFit,FormFit 是一款数字健身教练项目,基于 MoveNet,可以实时分析人体姿态,评估运动时的姿势和范围。此外,MoveNet 的研究结果还可用于健康应用程序,甚至运动训练应用程序。

关于 MoveNet、BlazePose、PoseNet 更多的演示,请参考项目,都有对应的 Demo 示例。

人体关键点

COCO 17 个关键点所对应的人体部位包括:0: 鼻子、1: 左眼、2: 右眼、3: 左耳、4: 右耳、5: 左肩、6: 右肩、7: 左肘、8: 右肘、9: 左腕、10: 右腕、11: 左胯、12: 右胯、13: 左膝、14: 右膝、15: 左踝、16: 右踝。

安卓 GPU使用状态监控 手机gpu实时监测_机器学习_04

COCO 关键点:用于 MoveNet 和 PoseNet。

BlazePose 关键点:用于 MediaPipe BlazePose检测器,示例如下:

安卓 GPU使用状态监控 手机gpu实时监测_机器学习_05

MoveNet 介绍

目前,MoveNet 有两个版本以提供性能的权衡。Lightning 版本时效性更快,但是产生的结果可能准确率不高;Thunder 版本时效性稍微慢一点,但准确率更高;因此,我们可以看到 Thunder 模型的关键点得分通常会比 Lightning 略高。

MoveNet 可以做什么?首先,它是一个高速位置跟踪器。

由于 MoveNet 是一个预训练模型,所以设置好以后即可使用。MoveNet 能够跟踪人体的 17 个关节点(如脚踝、膝盖、肩膀、手肘、手腕、耳朵、眼睛和鼻子等)。这些关键点与 (x, y)坐标系相关联,并且在每次调用「detector.estimatePoses(*some video element*)」时更新。

当在程序循环中反复调用该函数时,我们可以实时获得所有关键点的 (x, y) 坐标。返回的每个 (x, y) 关键点坐标都与一个分数相关联,该分数代表 MoveNet 对读数准确率的置信度。分数介于 0-1 之间,其中 0 和 1 这两个极端几乎是无法实现的,但这也意味着分数越接近 1,模型的置信度越好,越能说明读出的关键点位置越接近真实的人体关键点。

安卓 GPU使用状态监控 手机gpu实时监测_编程语言_06

传统方案(上)与 MoveNet(下)在高难度姿态检测上的对比结果,传统方案会跟丢关键点,而 MoveNet 不会。

如何使用?

总体来说,使用该项目分为两步:

首先需要从 SupportedModels 中选择一个模型来创建检测器,模型包括 MoveNet、BlazePose、PoseNet。如下代码是创建 MoveNet 检测器:

const model = poseDetection.SupportedModels.MoveNet;
const detector = await poseDetection.createDetector(model);

然后使用所创建检测器来检测姿态。

const poses = await detector.estimatePoses(image);

这样将会返回姿态列表,该列表包含检测到的图像中每个个体的姿态。对于单人模型,列表中只有一个元素。目前,只有 PoseNet 支持多姿态估计。如果模型不能检测到任何姿态,列表将为空。

每个姿态包含一个置信度得分和一组关键点。PoseNet 和 MoveNet 都返回 17 个关键点,Mediapipe BlazePose 返回 33 个关键点。每个关键点包含 x, y,得分和名字。

示例输出如下所示:

[
  {
    score: 0.8,
    keypoints: [
      {x: 230, y: 220, score: 0.9, name: "nose"},
      {x: 212, y: 190, score: 0.8, name: "left_eye"},
      ...
]
  }
]

x,y 代表图像中实际关键点位置,如果你想标准化关键点位置,你可以使用

「poseDetection.calculator.keypointsToNormalizedKeypoints(keypoints, imageSize)」方法将 x,y 转换到 [0, 1] 范围。得分范围是 0 到 1,它表示模型对关键点的置信度。通常情况下,不应该使用置信度低的关键点。每个应用程序可能需要自定义置信度阈值。

对于要求高精度的应用程序,这里建议使用较大的置信度;相反,需要高召回率的应用程序可能会选择降低阈值。模型之间的置信度没有校准,因此设置一个合适的置信度阈值可能需要一些实验。