基于MediaPipe 和 TensorFlow.js的3D手势检测

最近看到Google发布了Tensorflow.js关于手势姿态检测模型的新版本,该模型改进了2D精度,支持3D,并具有同时预测双手关键点的新能力。晚上下班回来,把源码下载下来跑了一下demo,被这个精度惊艳到了。瞬间萌生了了一个想法,有了这个3D手势检测算法,那我是不是可以把佛山无影手的招式记录下来,然后把它教给机器人,然后让机器人给我当保镖!

先来看一下测试效果。

基于MediaPipe 和 TF.js的3D手势检测

哈哈哈,废话少说,还是来看看,今晚是怎么跑这个demo的吧。

这个TF是基于js写的,所以当然你需要安装node和yarn啦!

那么安装完这两个东西之后,我们就可以把这个tfjs-models给他下载下来:

git clone https://github.com/tensorflow/tfjs-models.git

下载下俩之后,直接运行是不行滴,需要替换掉里面的两个文件。

rm tfjs-models/hand-pose-detection/src/shared
cp -r tfjs-models/shared tfjs-models/hand-pose-detection/src

rm tfjs-models/hand-pose-detection/demos/live_video/src/shared
cp -r tfjs-models/shared tfjs-models/hand-pose-detection/demos/live_video/src
cp tfjs-models/hand-pose-detection/demos/shared/* tfjs-models/hand-pose-detection/demos/live_video/src/shared/

替换完成之后,我们就可以构建项目啦:

cd tfjs-models/hand-pose-detection/demos/live_video
rm -rf .cache dist node_modules
yarn build-dep
yarn
yarn watch

最后你会在控制台看到如下输出:

并且浏览器弹出如下提示对话框,但是请注意,该url是不行滴,还要加上模型参数才可以。

基于MediaPipe 和 TensorFlow.js的3D手势检测_第1张图片

在浏览器上输入 http://localhost:1234/?model=mediapipe_hands

你就可以看到这个测试demo啦

基于MediaPipe 和 TensorFlow.js的3D手势检测_第2张图片

手机端前置摄像头手势检测:

基于MediaPipe 和 TF.js的3D手势检测


当然,上面只是小试牛刀。你还可以用js、python或者在android手机中来调用上述模块。下面为官方用法。

官方使用方法

如何使用

  1. 第一步是导入库。你可以在你的html文件中使用

通过脚本标记

 

通过NPM

yarn add @tensorflow-models/hand-pose-detection

# Run below commands if you want to use TF.js runtime.
yarn add @tensorflow/tfjs-core @tensorflow/tfjs-converter
yarn add @tensorflow/tfjs-backend-webgl

# Run below commands if you want to use MediaPipe runtime.
yarn add @mediapipe/hands

如果是通过NPM安装的,需要先导入库:

import * as handPoseDetection from '@tensorflow-models/hand-pose-detection';

接下来创建检测器的实例:

const model = handPoseDetection.SupportedModels.MediaPipeHands;
const detectorConfig = {
  runtime: 'mediapipe', // or 'tfjs'
  modelType: 'full'
};
detector = await handPoseDetection.createDetector(model, detectorConfig);

选择一个适合您的应用程序需要的模型类型,有两个选项供您选择:lite和full。从lite到full,精度增加,而推理速度下降。

  1. 一旦你有了检测器,你就可以通过视频流或静态图像来检测姿态:
const video = document.getElementById('video');
const hands = await detector.estimateHands(video);

输出格式如下:手表示图像框中检测到的手预测的数组。对于每只手,该结构包含一个左右手倾向的预测(左或右)以及这个预测的置信度得分。还返回一个2D关键点数组,其中每个关键点包含x、y和名称。x, y表示手关键点在图像像素空间中的水平和垂直位置,name表示联合标签。除了2D关键点,我们还以公制尺度返回3D关键点(x, y, z值),原点以辅助关键点的形式。

[
  {
    score: 0.8,
    Handedness: 'Right',
    keypoints: [
      {x: 105, y: 107, name: "wrist"},
      {x: 108, y: 160, name: "pinky_finger_tip"},
      ...
    ]
    keypoints3D: [
      {x: 0.00388, y: -0.0205, z: 0.0217, name: "wrist"},
      {x: -0.025138, y: -0.0255, z: -0.0051, name: "pinky_finger_tip"},
      ...
    ]
  }
]

你可以参考我们的README了解更多关于API的细节。

深入了解

TF js手部姿态检测API的更新版本提高了2D关键点预测、判断左右手(分类输出是左手还是右手)的质量,并最大限度地减少了假阳性检测的数量。关于更新模型的更多细节可以在其最近的文章中找到: On-device Real-time Hand Gesture Recognition.

在TensorFlow.j发布BlazePose GHUM 3D之后,他们还在该版本中添加了metric-scale 3D关键点预测手部姿势检测,原点由一个辅助关键点表示,形成了食指、中指、无名指和小指的第一指节。我们的三维模型是基于一个名为GHUM的统计三维人体模型,该模型是使用大量的人体形状和运动的语料库构建的。

为了获得收姿势的真实情况,其将GHUM手模型拟合到现有的2D手数据集,并恢复真实世界的三维关键点坐标。优化GHUM手模型的形状和手位变量,使重建模型与图像证据对齐。这包括2D关键点对齐、形状和姿态正则化以及人体测量关节角度限制和模型自接触惩罚。

基于MediaPipe 和 TensorFlow.js的3D手势检测_第3张图片

模型质量

在这个新版本中,我们大大提高了模型的质量,并在美国手语(ASL)手势数据集上对它们进行了评估。按照 COCO keypoint challenge methodology建议,我们使用均值平均精度(mAP)作为2D屏幕坐标的评价指标。

基于MediaPipe 和 TensorFlow.js的3D手势检测_第4张图片

三维评价采用欧几里得三维度量空间的平均绝对误差,平均误差以厘米为单位。

Model Name 2D, mAP, % 3D, mean 3D error, cm
HandPose GHUM Lite 79.2 1.4
HandPose GHUM Full 83.8 1.3
Previous TensorFlow.js HandPose 66.5 N/A

浏览器性能

我们在多个设备上对模型进行了基准测试。所有基准测试都是用双手进行的。

MacBook Pro 15” 2019.

Intel core i9.

AMD Radeon Pro Vega 20 Graphics.

(FPS)
iPhone 11

(FPS)
Pixel 5

(FPS)
Desktop

Intel i9-10900K. Nvidia GTX 1070 GPU.

(FPS)
MediaPipe Runtime

With WASM & GPU Accel.
62 48 8 5
TensorFlow.js Runtime
With WebGL backend
36 31 15 12

要在你的设备上看到模型的FPS,请尝试我们的演示。你可以在演示UI中切换模型类型和运行时,看看什么最适合你的设备。

跨平台可用性

除了JavaScript手部姿势检测API,这些更新的手部模型也可以在MediaPipe Hands中作为一个现成的Android解决方案API和Python解决方案API使用,在Android Maven Repository和Python PyPI中分别有预构建的包。

例如,对于Android开发者来说,Maven包可以很容易地集成到Android Studio项目中,只需在项目的Gradle依赖项中添加以下内容:

dependencies {
    implementation 'com.google.mediapipe:solution-core:latest.release'
    implementation 'com.google.mediapipe:hands:latest.release'
}

MediaPipe Android解决方案被设计用于处理不同的使用场景,如处理实时摄像头feeds、视频文件以及静态图像。它还附带了一些实用工具,可以方便地将输出地标叠加到CPU图像(使用Canvas)或GPU(使用OpenGL)上。例如,下面的代码片段演示了如何使用它来处理实时摄像机feed并在屏幕上实时呈现输出:

// Creates MediaPipe Hands.
HandsOptions handsOptions =
    HandsOptions.builder()
        .setModelComplexity(1)
        .setMaxNumHands(2)
        .setRunOnGpu(true)
        .build();
Hands hands = new Hands(activity, handsOptions);

// Connects MediaPipe Hands to camera.
CameraInput cameraInput = new CameraInput(activity);
cameraInput.setNewFrameListener(textureFrame -> hands.send(textureFrame));

// Registers a result listener.
hands.setResultListener(
     handsResult -> {
        handsView.setRenderData(handsResult);
        handsView.requestRender();
      })

// Starts the camera to feed data to MediaPipe Hands.
handsView.post(this::startCamera);

要了解更多关于MediaPipe Android解决方案的信息,请参阅相关的文档,并使用示例Android Studio项目尝试它们。还可以访问MediaPipe Solutions获取更多跨平台解决方案。

参考文章

https://lrting.top/backend/ai/2258/

https://blog.tensorflow.org/2021/11/3D-handpose.html?m=1

你可能感兴趣的:(人工智能,目标检测,人工智能,tensorflow)