Handsfree.js — 一个通过计算机视觉集成手势,面部表情和各种姿势识别的前端库

当电视上出现上图这种科技大片的时候,有没有幻想过有一天可以实现上图的这种交互,当我打开Handsfree这个库的介绍页时,看到前端页面竟然能够识别人的手势,面部以及各种肢体动作,简直刷新了我对前端能力的认知。确信这种交互有一天成为可能。

计算机视觉加上AI这几年早已经不是什么新鲜的名词,随着GPU算力的不断提升,使得越来越多(小)的设备上实现人工智能成为可能。

国外的一个开发者制作了一个实现Handsfree各种效果的demo页面(https://handsfree.js.org/),并且制定了开发计划,详细的进度将在作者的twitter上实时公布。看下这个计划:

  1. 创建一个易于使用的通过面部,手,眼睛,姿势跟踪,声音和思想控制程序的库。

  2. 然后使用该库去创建自定义插件或者组件。

  3. 使用以上实现的这样一个仓库去帮助更多的人通过“用户脚本管理器”去实现浏览器插件。

  4. 然后培养实现一个围绕Handsfree的使用者和开发者的社区。

  5. 最后建立一个关于Handsfree的基金会促进实现更多优秀的创意。

下面看下Handsfree能够实现哪些有趣的功能:

触发交互事件

最近不久作者发布了名为Pincher的插件,可以实现24种以上的捏????的动作,包括三种状态,开始,保持,释放——分别用你的小拇指,无名指,中指,和食指去做捏的动作。它根据鼠标事件为模型模拟动作,然后通过类似于document.addEventListener() 去监听。

在浏览器上滚动网页

这是根据作者实现的一个浏览器插件去帮助实现的滚动网页,它使用名为MediaPipe Hands模型去跟踪手势,下面的Gif展示的就是使用pinchScroll插件实现的效果,只需要加入很少的代码实现这样一个自定义的功能

创建多种辅助技术

下面是作者最喜欢的一个功能,使用了名为“Face Pointer”的插件,可以通过面部移动屏幕上的点去实现点击和滚动网页。

控制桌面游戏

使用人的面部和手去模拟鼠标去玩“Into the Breach”这款游戏。所有的这些都是通过“Face Pointer”和“Hand Pointer”插件,集成到Robot.js中触发原生的鼠标事件来轻松实现的。

创建自己的游戏

不仅仅可以使用它玩游戏,还可以创建自定义交互的游戏

控制无人机和机器人

当然它不仅能控制浏览器端和桌面端的软件,通过web socket接口可以和任何与你的电脑建立连接的设备,就像和这个很普通的机器人进行模拟动作。

音乐和艺术创作

这里除了一些作者即将发布的想法奇特的应用可以帮助制作一些迷幻的音乐,还有更多的创意想法等着更多的开发者去实现。另外作者正在开发的WebXR DevTools Chrome 插件以帮助在没有XR设备的情况下去开发WebXR应用。

开发指南

以上已经介绍了一些Handsfree能实现的功能,接下来介绍如何去使用它。不要担心一开始会有所迷惑,它就是大概的介绍。稍后会有更多的简短聚焦的教程放出。你可以从作者的代码仓库中/boilerplate/cdn.html找到样例。

Handsfree开发上手

可以使用它的CDN资源快速开始,不需要任何的服务器,拷贝如下代码到html文件中执行:

<head><!-- Import helper classes and styles --><linkrel="stylesheet"href="https://unpkg.com/handsfree@8.1.1/build/lib/assets/handsfree.css" />
</head>
<body><!-- Import Handsfree.js in body (as it adds body classes) --><script src="https://unpkg.com/handsfree@8.1.1/build/lib/handsfree.js"></script><script>// Use the hand with defaults (and show the webcam with wireframes)handsfree = new Handsfree({showDebug: true,hands: true})// Start webcam and tracking (personally, I always like to ask first)handsfree.start()
</script>
</body>

也可以使用npm方式。其实默认情况下它仍然加载的是远程CDN资源,因为它的包体积太大了(超过10M),但是你也可以下载模型文件到自己的本地assets目录。

npm i handsfree
handsfree = new Handsfree({showDebug: true,// Use the hand model with custom confighands: {// Always make sure to enable themenabled: true,// Let's track up to 4 hands. It's best to be kind and ask permission first tho!maxNumHands: 4,}
})// Start webcam and tracking (personally, I always like to ask first)
handsfree.start()

更多的配置参数列表详情请参见:

https://handsfree.js.org/ref/prop/config.html#the-full-list

数据处理

当然这个库不仅仅展示手的三维线框图这么简单,但是它实际上还不能做任何事情。除非通过两种方式配合Handsfree一起,作者常用的一种是使用handsfree.use(newPluginName, callback)生成插件,之所以叫它插件,因为当你运行handsfree.start()的时候它会挂载到主摄像头的循环队列里。它的回调在摄像头的每一帧里都将执行,并且收到计算机视觉模型里传出的所有的数据。以下是个简单的插件,仅仅通过console打印日志数据,姑且叫它logger。

// Let's use our hands again
handsfree = new Handsfree({showDebug: true, hands: true})
handsfree.start()// Let's create a plugin called "logger" to console.log the data
handsfree.use('logger', (data) => {// I like to always bail if there's no data,// which might happen if you swap out hands for the face later onif (!data.hands) return// Log the data  console.log(data.hands)// Do something if we are pinching with left [0] pinky [3]if (data.hands.pinchState[0][3] === 'held') {console.log('pinching with left pinky')}
})

一旦你创建好了一个插件,它将在任何地方通过hansfree.plugin.pluginName调用到,而且拥有一些属性和方法。

handsfree.plugin.logger.enable()
handsfree.plugin.logger.disable()// This is what the callback gets mapped to,
// and is what gets called on every frame that this plugin is enabled
handsfree.plugin.logger.onFrame

如果你需要更多高级的功能,那么你可以传入特定的hooks的对象,它将插件的不同的阶段执行,例如:

handsfree.use('advancedLogger', {// True by defaultenabled: true,// A list of strings for tagging this plugin.// Later you can bulk disable/enable these with: handsfree.enablePlugins(['tag1', 'tag2'])tags: [],// This special property can be adjusted later (or even before!) in various waysconfig: {},// Called immediately after the plugin is added, even if disabled// The `this` context is the plugin itself: handsfree.plugin.advancedLogger// If you need to create DOM elements or other setup, this is the method to do it inonUse () {},// Called when you .enable() this pluginonEnabled () {},// Called when you .disable() this pluginonEnabled () {}
})

使用数据代替插件

有的时候你可能想用一个框架,一张图片,一个画布,或者一段视频来取代摄像头去跟踪里面的数据,或者在一个app内你很难调用到handsfree里面的东西。诸如此类的情况,你可以使用document的监听事件。

你可以在这些事件中通过ev.detail.data获取到相关的数据

// This will get called on every frame
document.addEventListener('handsfree-data', ev => console.log(ev.detail.data))// Listen to when the thumb and index (0) are pinched on any hand
document.addEventListener('handsfree-finger-pinched-0')// Listen to when the right (1) thumb and pinky (3) are pinched
document.addEventListener('handsfree-finger-pinched-1-3')

同时,你也可以通过handsfree实例直接访问data属性里面的数据

console.log(handsfree.data.hands)

更新模型和插件

Handsfree其实最强大之处在于可以随时更换模型和插件,当你的app中不同的路由呈现不同的handsfree使用场景的时候就显得很重要。它是通过handsfree.update(config)来达到目的的。作者在一个网页上在不重启摄像头的情况下呈现不同的demo,就是依靠这个实现的。

handsfree.use带有与实例化Hansfree时相同的config对象,但是它还做了另外几件事:

  1. 它不会合并更改,所以当你打开双手的情况下仅传递   handsfree.update({facemesh:true})参数,最终会导致两者都失败。

  2. 它会在任何需要的模型和依赖的地方自动加载loading。

  3. 赋予配置插件,关闭插件的能力

案例如下:

// Start with hands
const handsfree = new Handsfree({hands: true})
handsfree.start()// Add facemesh
handsfree.update({facemesh: true})// Replace both with pose
handsfree.update({hands: false,facemesh: false,pose: true
})// Use Weboji and enable the Face Pointer plugins
handsfree.update({hands: false, facemesh: false, pose: false,weboji: true,plugin: {// Enable some pluginsfaceClick: truefaceScroll: true,// Update the special .config properties of the plugins (this is so magical!)facePointer: {speed: {x: 2,y: 2}},}
})

你也可以批量禁用插件和打开插件,甚至使用标签作为参数

// Disable and enable them all
handsfree.disablePlugins()
handsfree.enablePlugins()// Disable all the "core" tagged plugins
handsfree.disablePlugins('core')// Enable handsfree "browser" tagged plugins
handsfree.enablePlugins('browser')

这些插件下的配置参数都可以即时修改,通过config下面的属性名称进行访问:

// Change the Face Pointer speed
handsfree.plugin.facePointer.config.speed.x = 2
handsfree.plugin.facePointer.config.speed.y = 2// Set the threshold for how much you have to smile to click (0 - 1)
handsfree.plugin.faceClick.config.morphs[0] = .25

元素类名

当页面状态发生变化的时候,body标签会自动加上class类名

body.handsfree-started
body.handsfree-loadingbody.handsfree-model-weboji
body.handsfree-model-hands
  • Generic classes:

     https://handsfree.js.org/ref/util/classes.html

  • Pinching states:

     https://handsfree.js.org/ref/plugin/pinchers.html#classes

以上就是大概的介绍,为了防止你听的有点迷糊,作者新年的计划是每周至少一次针对每一个主题来出一份教程,作者将全职all in这个项目创造出更多的创意使用场景。支持作者可以加入https://github.com/sponsors/midiblocks。

该项目的核心AI技术用到了google的TensorFlow,还是很值得期待将来有更多的使用场景的。

译自:

https://dev.to/midiblocks/introducing-handsfree-js-integrate-hand-face-and-pose-gestures-to-your-frontend-4g3p

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354674.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ejb jsf jpa_完整的WebApplication JSF EJB JPA JAAS –第1部分

ejb jsf jpa这篇文章将是迄今为止我博客中最大的一篇文章&#xff01; 我们将看到完整的Web应用程序。 最新的技术&#xff08;直到今天&#xff09;都将完成&#xff0c;但是我将给出一些提示以显示如何使本文章适应较旧的技术。 在本文的结尾&#xff0c;您将找到要下载的源代…

Jzoj4782 Math

若一个数x是平方数&#xff0c;则d(x)为平方数 所以就是要考虑有多少对i*j为平方数 我们假设&#xff0c;ip*k^2&#xff0c;那么&#xff0c;jp*q^2时&#xff0c;i*j为平方数&#xff08;p不含平方因子&#xff0c;k&#xff0c;q为正整数&#xff09; 所以&#xff0c;我们对…

前端暗黑模式,你了解多少

关于使用越来越多的前端暗黑模式&#xff0c;手机的app或网站都将支持暗黑模式逐渐成为一种规范&#xff0c;这样做的目的是什么呢&#xff1f;从我最初的理解是为了在黑暗的环境下屏幕上阅读的体验考虑&#xff0c;但是看了文摘却有另一种意义。暗黑模式究竟能不能起到省电的作…

两全其美的

使用抽象文档模式的类型安全视图 您如何组织对象&#xff1f; 在本文中&#xff0c;我将介绍一种模式&#xff0c;该模式以无类型的方式在您的系统中组织所谓的名词类&#xff0c;然后使用特征公开数据的类型化视图。 这使得只需少量的牺牲就可以在Java之类的语言中获得JavaScr…

Windows内核函数

字符串处理 在驱动中一般使用的是ANSI字符串和宽字节字符串&#xff0c;在驱动中我们仍然可以使用C中提供的字符串操作函数&#xff0c;但是在DDK中不提倡这样做&#xff0c;由于C函数容易导致缓冲区溢出漏洞&#xff0c;针对字符串的操作它提供了一组函数分别用来处理ANSI字符…

前端应该关注的2021年UI设计趋势

UI设计趋势几乎每年都在发生变化&#xff0c;变化的原因是人们的审美在变导致的&#xff0c;还是设计越来越人性化。市场上是谁在主导设计趋势&#xff1f;其中原因不得而知&#xff0c;我们先看看究竟有哪些变化&#xff1a;1. 3D插图&#xff08;依然流行&#xff09;3D图像将…

如何让你在开发者工具中查看源代码有语法高亮和暗黑主题的效果

如何让你在Chrome浏览器开发者工具中查看源代码的时候&#xff0c;和在代码编辑器中有同样的代码语法高亮的效果&#xff0c;而且还是深色主题&#xff0c;如果你是深色主题的爱好者就更合你意了。国外的美女开发者为你实现了这样功能的浏览器拓展&#xff0c;她的Github主页&a…

“太空语言”JavaScript编码标准规范指南

喷气推进实验室是 美国国家航空航天局的科研机构。 该实验室JPL开发大部分的软件是用在无人深度太空和其他行星探测的领域。他们拥有著名的 好奇号火星探测器 和 旅行者号探测器 。已经离开太阳系25年&#xff0c;仍然在飞行并提供科学信息。高水平的自动化和长期的任务导致了对…

如何在JUnit 5中替换规则

最近发布的JUnit 5&#xff08;又名JUnit Lambda&#xff09; Alpha版本引起了我的兴趣&#xff0c;在浏览文档时&#xff0c;我注意到规则以及跑步者和阶级规则都消失了。 根据文档&#xff0c;这些部分竞争的概念已被单个一致的扩展模型取代。 多年来&#xff0c; Frank和我…

微页面设计开发指南

一、目标实现左侧&#xff1a;为可用的组件列表&#xff0c;可拖动任一组件到中间的预览区域中间&#xff1a;为页面预览效果页面&#xff0c;选中任一组件&#xff0c;可在右侧进行参数配置右侧&#xff1a;为组件的参数配置&#xff08;选中中间的组件时出现&#xff09;&…

商城商品购买数量增减的完美JS效果

商城商品购买数量增减的完美JS效果 近期在开发一个地方O2O租书项目&#xff0c;使用ASP.NET MVC技术&#xff0c;其中在图书详情页&#xff0c;用户可以输入借阅的数量&#xff0c;这里使用了js来控制数量的增减和校验。 数量一定是数字 点击增减按钮的时候要能自动加1或减1 …

这款插件让你在VSCode上也能答题背单词

在VSCode上也可以在线答题了&#xff0c;插件市场上线了一款答题的插件&#xff0c;免去了去其它网站或者软件的烦恼&#xff0c;代码写累了&#xff0c;随手打开答题功能&#xff0c;换换脑子&#xff0c;或者熟悉两个单词&#xff0c;程序员的别样休闲时光&#xff0c;哈哈&a…

使用Java 8在地图上流式传输

在本文中&#xff0c;我将向您展示如何在标准Java映射上有效地实现Speedment Open Source流&#xff0c;并将Stream接口扩展为MapStream&#xff01; 即使在复杂的情况下&#xff0c;此添加将使保持流的具体性和可读性变得更加容易。 希望这将允许您继续流式传输而不会过早收集…

如何使用python给PDF文件加水印

Python作为编程界最火的语言&#xff0c;能做的事几乎你能想到的它都能干&#xff0c;就连抢茅台都可以&#xff0c;还有什么不行&#xff1f;&#xff01;Python作为脚本编程语言&#xff0c;可以做很多事情。使用Python&#xff0c;你可以轻松地给pdf加上水印。 你可以使用名…

搭建一个redis高可用系统

一、单个实例 当系统中只有一台redis运行时&#xff0c;一旦该redis挂了&#xff0c;会导致整个系统无法运行。 单个实例二、备份 由于单台redis出现单点故障&#xff0c;就会导致整个系统不可用&#xff0c;所以想到的办法自然就是备份&#xff08;一般工业界认为比较安全的备…

SSH连接远程服务器,本地known_hosts文件记录了什么

今天工作时&#xff0c;使用ssh命令远程连接公司的本地服务器时&#xff0c;突然出现以下错误bash-3.2$ ssh argus192.168.200.8 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdroppin…

“全人类的知识宝藏”维基百科迎来了20岁的生日!

维基百科从一个伟大的想法开始&#xff0c;与无数的像你像我一样的阅读者&#xff0c;创作者&#xff0c;捐赠者和粉丝经历了互联网的20年&#xff0c;今天让我们一起为这个属于所有互联网人的成果庆祝一次生日。值此20周年特地为它做了一个主页&#xff1a;https://wikimediaf…

转:智能音箱市场深度报告:怎么大家都在抢这个两亿小蛋糕?

原文链接&#xff1a;http://www.sohu.com/a/199335366_115978 智能音箱是今年最热的智能硬件项目之一。目前&#xff0c;智能音箱已经有了比较成熟的技术方案和模式思路&#xff0c;但消费市场似乎依然秉持着比较谨慎的态度。智能音箱市场上的主流产品都有什么思路&#xff1f…

Tailwindcss尤大神都fork了,是未来的趋势?

最近Tailwindcss频繁出现在我的视野里&#xff0c;从单词拼写中看&#xff0c;多多少少与css有点关系。近几年是JS框架大行其道&#xff0c;CSS方面少有新的框架出现。昨天突然看到尤大神在Github上的动态&#xff0c;fork了该项目&#xff0c;看来马上要火的节奏啊&#xff01…

JUnit 5 –架构

现在我们知道如何设置JUnit 5并使用它编写一些测试 &#xff0c;下面让我们看一下。 在本文中&#xff0c;我们将讨论JUnit 5架构以及采用这种方式的原因。 总览 这篇文章是有关JUnit 5的系列文章的一部分&#xff1a; 设定 基本 建筑 条件 注射 … JUnit 4 忽略Hamcre…