教年轻 AIoT 创业者如何从 0 到 1 实现AIoT 创业项目 了解详情
写点什么

Handtrack.js 开源:3 行 JS 代码搞定手部动作跟踪

  • 2019-03-27
  • 本文字数:3556 字

    阅读完需:约 12 分钟

Handtrack.js 开源:3行JS代码搞定手部动作跟踪

近日,GitHub 上开源了一个名为 Handtrack.js 的项目,有了它,你只需要 3 行代码就能用来检测图片中手的动作。



演示地址:https://victordibia.github.io/handtrack.js/#/


运行时:22 FPS,Macbook Pro 2018(2.5 Ghz),Chrome 浏览器。13FPS,Macbook Pro 2014(2.2GHz)。


不久之前,一个使用 TensorFlow 对象检测 API 跟踪图片中手部动作的实验结果把我震惊到了。我把训练模型和源代码开放了出来。


从那时起,它就被用来开发一些非常有趣的东西,比如:


一个可以帮助孩子进行拼写练习的工具


一个可以识别手势的插件


一个乒乓球游戏


有很多人想要尝试我提供的训练模型,但无法设置好 Tensorflow(安装问题、TF 版本问题、导出图表,等等)。幸运的是,Tensorflow.js 解决了其中的一些安装和发行问题,因为它经过优化,可以在浏览器的标准化环境中运行。为此,我创建了Handtrack.js库


它可以让开发人员使用经过训练的手部检测模型快速创建手势交互原型。


这个库的目标是隐藏与加载模型文件相关的步骤,为用户提供有用的函数,并允许用户在没有任何 ML 经验的情况下检测图像中的手,你不需要自己训练模型。


你也无需导出任何图或已保存的模型。你可以直接在 Web 应用程序中包含 handtrack.js(详情如下),然后调用这个库提供的方法。

如何在 Web 应用程序中使用它?

你可以直接在 script 标签中包含这个库的 URL 地址,或者使用构建工具从 npm 中导入它。

使用 script 标签

Handtrack.js 的最小化 js 文件目前托管在 jsdelivr 上,jsdelivr 是一个免费的开源 CDN,让你可以在 Web 应用程序中包含任何的 npm 包。


<script src="https://cdn.jsdelivr.net/npm/handtrackjs/dist/handtrack.min.js"> </script>
复制代码


在将上面的 script 标签添加到 html 页面后,就可以使用 handTrack 变量引用 handtrack.js,如下所示。


const img = document.getElementById('img');  handTrack.load().then(model => {     model.detect(img).then(predictions => {      console.log('Predictions: ', predictions) // bbox predictions    });});
复制代码


上面的代码段将打印出通过 img 标签传入的图像的预测边框,如果换了视频或通过摄像头提交图像帧,那么就可以“跟踪”在每一帧中出现的手。



使用 handtrack.js 跟踪图像中的手,你可以调用 renderPredictions()方法在 canvas 对象中绘制检测到的边框和源图像。

使用 NPM

你可以使用以下命令将 handtrack.js 作为 npm 包来安装:


npm install --save handtrackjs
复制代码


下面给出了如何在 React 应用程序中导入和使用它的示例。


import * as handTrack from 'handtrackjs';const img = document.getElementById('img');// Load the model.handTrack.load().then(model => {  // detect objects in the image.  console.log("model loaded")  model.detect(img).then(predictions => {    console.log('Predictions: ', predictions);   });});
复制代码


Handtrack.js 的 API

Handtrack.js 提供了几种方法。两个主要的方法是 load()和 detect(),分别用于加载手部检测模型和获取预测结果。


load()方法接受可选的模型参数,允许你控制模型的性能。这个方法以 webmodel 格式(也托管在 jsdelivr 上)加载预训练的手部检测模型。


detect()方法接受输入源参数(img、video 或 canvas 对象)并返回图像中手部位置的边框预测结果。


const modelParams = {  flipHorizontal: true,   // flip e.g for video   imageScaleFactor: 0.7,  // reduce input image size .  maxNumBoxes: 20,        // maximum number of boxes to detect  iouThreshold: 0.5,      // ioU threshold for non-max suppression  scoreThreshold: 0.79,    // confidence threshold for predictions.}const img = document.getElementById('img');handTrack.load(modelParams).then(model => {    model.detect(img).then(predictions => {    console.log('Predictions: ', predictions);   });});
复制代码


预测结果格式如下:


[{  bbox: [x, y, width, height],  class: "hand",  score: 0.8380282521247864}, {  bbox: [x, y, width, height],  class: "hand",  score: 0.74644153267145157}]
复制代码


Handtrack.js 还提供了其他辅助方法:


  • model.getFPS():获取 FPS,即每秒检测次数;

  • model.renderPredictions(predictions, canvas, context, mediasource):在指定的画布上绘制边框(和源图像);

  • model.getModelParameters():返回模型参数;

  • model.setModelParameters(modelParams):更新模型参数;

  • dispose():删除模型实例;

  • startVideo(video):在给定的视频元素上启动摄像头视频流。返回一个 promise,可用于验证用户是否提供了视频权限;

  • stopVideo(video):停止视频流。

库大小和模型大小

库大小为 810 KB,主要是因为它与 tensorflow.js 库捆绑在一起(最新版本存在一些未解决的问题)。


模型大小为 18.5 MB,在初始加载页面时需要等待一会儿。TF.js 模型通常分为多个文件(在本例中为四个 4.2 MB 的文件和一个 1.7 MB 的文件)。

工作原理

Handtrack.js 使用了 Tensorflow.js 库,一个灵活而直观的 API,用于在浏览器中从头开始构建和训练模型。它提供了一个低级的 JavaScript 线性代数库和一个高级的层 API。

创建 Handtrack.js 库


创建基于 Tensorflow.js 的 JavaScript 库的步骤

数据汇编

这个项目中使用的数据主要来自Egohands数据集。其中包括 4800 张人手的图像,带有边框,使用谷歌眼镜捕获。

模型训练

使用 Tensorflow 对象检测 API 训练模型。对于这个项目,我们使用了Single Shot MultiBox DetectorMobileNetV2架构。然后将训练好的模型导出为 savedmodel。

模型转换

Tensorflow.js 提供了一个模型转换工具,可以用它将 savedmodel 转换为可以在浏览器中加载的 webmodel 格式。最后,在转换过程中删除了对象检测模型图的后处理部分。这个优化可以让检测和预测操作的速度加倍。

库的包装和托管

这个库由一个主类组成,这个类提供了一些用于加载模型、检测图像的方法以及一组其他有用的函数,例如 startVideo、stopVideo、getFPS()、renderPredictions()、getModelParameters()、setModelParameters(),等等。方法的完整描述可以在Github上找到.


然后使用 rollup.js 捆绑源文件,并在 npm 上发布(包括 webmodel 文件)。目前 Handtrack.js 与 Tensorflow.js(v0.13.5)捆绑在一起,主要是因为在编写这个库的时候,Tensorflow.js(v0.15)在加载图像/视频标签为张量时会发生类型错误。如果新版本修复了这个问题,我也将更新到最新版本。

什么时候应该使用 Handtrack.js?

如果你对基于手势的交互式体验感兴趣,Handtrack.js 可能会很有用。用户不需要使用任何额外的传感器或硬件就可以立即获得基于手势的交互体验。



下面列出了一些(并非所有)相关的场景:


  • 将鼠标移动映射到手部移动,达到控制的目的。

  • 当手和其他物体重叠时可以表示某些有意义的交互信号(例如触碰物体或选择物体)。

  • 人手运动可以作为某些动作识别的代理(例如,自动跟踪视频或图像中下棋或打高尔夫球的动作),或者知识简单地计算图像或视频中出现了多少人。

  • 互动艺术装置,一组有趣的交互式艺术装置控件。

  • 教授他人 ML/AI 知识。Handtrack.js 库提供了一个很有意思的界面,用于演示模型参数的变化(置信度阈值、IoU 阈值、图像大小等)如何影响检测结果。

  • 创建演示,任何人都可以轻松运行或体验这些东西。


局限性

浏览器是单线程的:所以必须确保预测操作不会阻塞 UI 线程。每个预测可能需要 50 到 150 毫秒,所以用户会注意到这个延迟。在将 Handtrack.js 集成到每秒需要多次渲染整个屏幕的应用程序中时(例如游戏),我发现有必要减少每秒的预测数量。


逐帧跟踪手部动作:如果想要跨帧识别手势,需要编写额外的代码来推断手在进入、移动和离开连续帧时的 ID。


不正确的预测:偶尔会出现不正确的预测(有时候会将脸检测为手)。我发现,不同的摄像头和光线条件都需要不同的模型参数设置(尤其是置信度阈值)才能获得良好的检测效果。更重要的是,这个可以通过额外的数据进行改进。

下一步

Handtrack.js 代表了新形式 AI 人机交互的早期阶段。在浏览器方面已经有一些很好的想法,例如用于人体姿势检测的posenet


以及用于在浏览器中检测面部表情的handsfree.js


与此同时,我将在以下这些方面花更多的时间:


创建更好的模型:创建一个强大的基准来评估底层的手部模型。收集更多可提高准确性和稳定性的数据。


额外的词汇表:在构建样本时,我发现这种交互方法的词汇表很有限。最起码还需要支持更多的状态,比如拳头和摊开的手掌。这意味着需要重新标记数据集(或使用一些半监督方法)。


额外的模型量化:现在,我们使用的是 MobilenetV2。是否还有更快的解决方案?


英文原文:https://hackernoon.com/handtrackjs-677c29c1d585


更多内容,请关注前端之巅。



活动推荐:

2023年9月3-5日,「QCon全球软件开发大会·北京站」 将在北京•富力万丽酒店举办。此次大会以「启航·AIGC软件工程变革」为主题,策划了大前端融合提效、大模型应用落地、面向 AI 的存储、AIGC 浪潮下的研发效能提升、LLMOps、异构算力、微服务架构治理、业务安全技术、构建未来软件的编程语言、FinOps 等近30个精彩专题。咨询购票可联系票务经理 18514549229(微信同手机号)。

2019-03-27 08:105283
用户头像

发布了 321 篇内容, 共 128.8 次阅读, 收获喜欢 139 次。

关注

评论

发布
暂无评论
发现更多内容

最近的一些人生感悟

小智

人生 哲学

漫谈哲学与编程

keelii

编程 哲学

如何阅读源码?

武培轩

Java 源码 面试 进阶 后端

回"疫"录(3):让人怀念的普通一天

小天同学

疫情 回忆录 现实纪录 纪实

世界知识产权日碎碎念

Yin

成长 随笔 知识产权

从【炉石传说】到矩阵运算

IT蜗壳-Tango

Python 学习 矩阵 数学

程序员5分钟:你了解32位带符号的整型吗?

顾仲贤

程序员

微信朋友圈为什么没有阅读数?

彭宏豪95

微信 产品 产品设计

随手记备忘录的好习惯

changyou

Java并发编程系列——线程

孙苏勇

Java 并发编程 线程

「超级右键」

非著名程序员

macos 程序员 效率工具 软件 Mac

程序员陪娃漫画系列——修龙头

孙苏勇

程序员 生活 陪伴 漫画

除了负载均衡的算法,你还应该知道这些

松花皮蛋me

Java 负载均衡 分布式

别总说CMS、G1,该聊聊ZGC了

猿人谷

CMS G1 ZGC JVM

决定我们认知深度的究竟是什么?

石君

深度思考 方法论 连接

敏捷开发 | 张三与需求管理

Worktile

敏捷开发 需求管理

前端如何搞监控总结篇

大前端洞见

大前端 监控 全链路监控

爱他,就让他走?

Selina

团队管理 领导力 团队协作

加班能解决交付的期望么?

拖地先生

项目管理 领导力 管理 时间管理

很不幸,自动化测试永远只能是必要非充分条件

刘华Kenneth

DevOps 敏捷 自动化 测试 金字塔

知乎开发了一个搜索引擎

红泥

搜索引擎 百度 知乎

程序员5分钟:你的程序占用了多少内存?

顾仲贤

程序员

程序员陪娃漫画系列——看医生

孙苏勇

程序员 生活 陪伴 漫画

聊聊苹果公司技术部门的宫斗和冷战

赵钰莹

程序员 外包 apple

我为什么选择infoq写作平台

三爻

小论互联网项目管理

南方

项目管理 互联网 个人成长 碧海潮生曲

克制文章长度

changyou

基于Kubernetes的多云和混合云

倪朋飞

云计算 架构 Kubernetes 微服务 Service Mesh

在谈判中,你有哪些属于自己的独特的方法和技巧?

Yolanda

Java并发编程系列插曲——对象的内存结构

孙苏勇

Java 内存模型 面向对象 ClassLayout

程序员都应该了解的运维知识经验

松花皮蛋me

DevOps 分布式 运维

  • 扫码添加小助手
    领取最新资料包
Handtrack.js 开源:3行JS代码搞定手部动作跟踪_大前端_Victor Dibia_InfoQ精选文章