有了 TensorFlow.js,浏览器中也可以实时人体姿势估计

2018/05/12 · CSS ·
TensorFlow

原文出处:
TensorFlow   译文出处:云水木石   

与谷歌创意实验室合作,我很高兴地宣布发布TensorFlow.js版本的PoseNet,这是一种机器学习模型,允许在浏览器中进行实时人体姿势估计。您可以访问 尝试一下在线演示。

图片 1

图片 2

PoseNet可以使用单姿态或多姿态算法检测图像和视频中的人物形象 –
全部来自浏览器。

那么,问题来了,什么是姿态估计?姿态估计是指在图像和视频中检测人物的计算机视觉技术,以便人们可以确定某个人的肘部在图像中出现的位置。需要澄清的是,这项技术并不能识别谁在图像中

没有任何与识别身份相关的个人身份信息。该算法仅仅估计关键身体关节的位置。

好吧,为什么这是令人兴奋的开始? 姿态估计有很多用途,从对身体做出反应的交互式安装到增强现实、动画、健身用途等等。我们希望此模型的辅助能力能够激励更多的开发人员和制造商尝试将姿态检测应用到他们自己的项目中。虽然许多可选的姿态检测系统已经开源,但都需要专门的硬件和/或相机,以及相当多的系统设置。PoseNet运行在TensorFlow.js上,任何拥有摄像头的PC或手机的人都可以在网络浏览器中体验这种技术。 而且由于我们已经开源了这个模型,JavaScript开发人员可以用几行代码来使用这个技术。更重要的是,这实际上可以帮助保护用户隐私。由于TensorFlow.js上的PoseNet在浏览器中运行,因此任何姿态数据都不会留在用户的计算机上。


Android4.4(KitKat)开始,使用Chrome开发者工具可以帮助我们在原生的Android应用中远程调试WebView网页内容。具体步骤如下:

目录

PoseNet入门

PoseNet可用于估计单个姿势或多个姿势,这意味着该算法的一个版本只能检测图像/视频中的一个人,而另一个版本可以检测图像/视频中的多个人。为什么会有两个版本?单人姿势检测器更快,更简单,但图像中只能有一个主体(稍后会深入探讨)。我们先探讨更容易使用的单个姿势。

在上层看来,姿势估计发生在两个阶段:

  1. 输入RGB图像到卷积神经网络。
  2. 使用单姿态或多姿态解码算法来解码姿势、构建置信度得分、关键点位置和来自模型输出的关键点置信度得分。

等等,这些关键词的含义是什么? 让我们回顾一下最重要的:

  • 姿势 –
    在最上层看来,PoseNet将返回一个姿势对象,其中包含每个检测到的人物的关键点列表和实例层的置信度分数。

图片 3

PoseNet返回检测到的每个人的置信度值以及检测到的每个姿势关键点。图片来源:“Microsoft
Coco:上下文数据集中的通用对象”,。

  • 姿势置信度 –
    这决定了对姿势估计的整体置信度。它介于0.0和1.0之间。它可以用来隐藏不够确定的姿势。
  • 关键点 –
    估计的人体姿势的一部分,例如鼻子、右耳、左膝、右脚等。它包含位置和关键点置信度分数。PoseNet目前可检测到下图所示的17个关键点:

图片 4

PosNet检测的17个姿势关键点。

  • 关键点置信度得分 –
    这决定了估计关键点位置精度的置信度。它介于0.0和1.0之间。它可以用来隐藏不够确定的关键点。
  • 关键点位置 – 检测到的关键点在原始输入图像中的x和y二维坐标。

(1)设置Webview调试模式

  • 一个数值保存复选框的值
    • 前言
    • 准备知识 ——
      位与运算
    • 设计
    • 回显
    • 示例
    • 总结

第1步:导入TensorFlow.js和PoseNet库

将模型的复杂性抽象化并将功能封装为易于使用的方法,这放面已经做了很多工作。让我们回顾一下如何配置PoseNet项目的基础知识。

该库可以通过npm安装:

npm install @tensorflow-models/posnet

1
npm install @tensorflow-models/posnet

使用es6模块导入:

import * as posenet from ‘@tensorflow-models/posenet’; const net =
await posenet.load();

1
2
import * as posenet from ‘@tensorflow-models/posenet’;
const net = await posenet.load();

或通过页面的bundle:

<html> <body> <!– Load TensorFlow.js –> <script
src=”; <!– Load
Posenet –> <script
src=”; </script>
<script type=”text/javascript”> posenet.load().then(function(net)
{ // posenet model loaded }); </script> </body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
  <body>
    <!– Load TensorFlow.js –>
    <script src="https://unpkg.com/@tensorflow/tfjs"></script>
    <!– Load Posenet –>
    <script src="https://unpkg.com/@tensorflow-models/posenet">
    </script>
    <script type="text/javascript">
      posenet.load().then(function(net) {
        // posenet model loaded
      });
    </script>
  </body>
</html>

可以在Activity的init进行如下设置,WebView类包含一个公共静态方法,可应用于项目中的所有WebView,同时不受Manifest文件中的debuggable属性影响。

一个数值保存复选框的值


第2a步:单人姿态估计

图片 5

应用于图像的单人姿势估计算法示例。图片来源:“Microsoft
Coco:上下文数据集中的通用对象”,。

如前面所说的,单姿态估计算法更简单、速度更快。它的理想场景是只有一个人在输入图像或视频的中间。缺点是,如果图像中有多个人,那么来自两个人的关键点可能会被估计为是同一个单一姿势的一部分

例如,#1的左臂和#2的右膝由该算法确定为属于相同姿势而可能被合并。如果输入图像可能包含多人,则应该使用多姿态估计算法。

我们来看看单姿态估计算法的输入:

  • 输入图像元素 –
    包含要预测图像的html元素,例如video或img标签。重要的是,图像或视频元素应该是方形的。
  • 图像比例因子 –
    0.2和1之间的数字。默认为0.50。在输入到网络之前的缩放图像比例。将此数字设置得较低可以缩小图像,以牺牲精度为代价加快速度。
  • 水平翻转 –
    默认为false。如果姿势应该水平翻转/镜像。对于默认水平翻转(比如网络摄像头)的视频,这应该设置为true,这样返回的姿势方向才正确。
  • 输出步幅 –
    必须为32、16或8。默认值为16。在内部,此参数会影响神经网络中图层的高度和宽度。在上层看来,它会影响姿态估计的精度速度。输出步幅值越低精度越高但速度越慢,数值越高速度越快,但精度越低。查看输出步幅对输出质量的影响的最好方法是尝试使用这个单姿态估计的示例: 。

现在让我们看一下单姿态估计算法的输出

  • 包含姿势置信度得分和17个关键点数组的姿势。
  • 每个关键点都包含关键点位置和关键点置信度分数。同样,所有关键点位置在输入图像空间中都有x和y坐标,并且可以直接映射到图像上。

一下这个简短的代码块展示了如何使用单姿态估计算法:

const imageScaleFactor = 0.50; const flipHorizontal = false; const
outputStride = 16; const imageElement = document.getElementById(‘cat’);
// load the posenet model const net = await posenet.load(); const pose =
await net.estimateSinglePose(imageElement, scaleFactor, flipHorizontal,
outputStride);

1
2
3
4
5
6
7
const imageScaleFactor = 0.50;
const flipHorizontal = false;
const outputStride = 16;
const imageElement = document.getElementById(‘cat’);
// load the posenet model
const net = await posenet.load();
const pose = await net.estimateSinglePose(imageElement, scaleFactor, flipHorizontal, outputStride);

一个输出姿势的例子如下所示:

{ “score”: 0.32371445304906, “keypoints”: [ { // nose “position”: {
“x”: 301.42237830162, “y”: 177.69162777066 }, “score”: 0.99799561500549
}, { // left eye “position”: { “x”: 326.05302262306, “y”: 122.9596464932
}, “score”: 0.99766051769257 }, { // right eye “position”: { “x”:
258.72196650505, “y”: 127.51624706388 }, “score”: 0.99926537275314 },
… ] }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
  "score": 0.32371445304906,
  "keypoints": [
    { // nose
      "position": {
        "x": 301.42237830162,
        "y": 177.69162777066
      },
      "score": 0.99799561500549
    },
    { // left eye
      "position": {
        "x": 326.05302262306,
        "y": 122.9596464932
      },
      "score": 0.99766051769257
    },
    { // right eye
      "position": {
        "x": 258.72196650505,
        "y": 127.51624706388
      },
      "score": 0.99926537275314
    },
    …
  ]
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    WebView.setWebContentsDebuggingEnabled(true);
}

前言

在开发过程中,对于网页中的多选,我们有很多种存储方式,常见的如逗号分隔。下文介绍一种通用设计方式:用一个整数来存储复选框的值。


发表评论

电子邮件地址不会被公开。 必填项已用*标注