前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Processing手部追踪

Processing手部追踪

作者头像
ChildhoodAndy
发布2021-10-26 13:31:27
2.8K0
发布2021-10-26 13:31:27
举报
文章被收录于专栏:小菜与老鸟

有天小菜在看视频号,很大声牛兄的一个视频系统给我推送了过来

类似还有最近的这个

比较好奇,手部的跟踪识别是怎么做到的。

起初我以为牛兄是用 Processing Java 做的,我记得没有好用的手部识别库,而一个 OpenCV 识别脸部的还各种报错。是用 Kinect 做的吗?经过和牛兄的沟通,原来是使用 p5js 实现的,使用的是一个叫做Handtrack.js的一个 js 库。

于是小菜花了点时间研究了下,总结一下,做个备忘和信息分享。

借助Handtrack.js库,可以不需要再依赖额外的传感器或者其他硬件,只需要浏览器和摄像头就能实现手部动作的检测和追踪,确实方便不少。

初识HandTrack

  • HandTrack github 地址[1]
  • 官方网站[2]

Handtrack 的背后依赖的是 TensorFlow,借助机器学习,能够对手部姿势和脸部进行检测和跟踪。在使用的时候,浏览器其实会下载一个识别模型,这个模型就是机器学习的产物,输入数据,就能按照学习的结果,输出结果。输出结果的准确度,取决于机器学习的算法以及训练程度。

目前支持的7种姿势:

  • open-手部打开姿势
  • closed-手部关闭姿势,如拳头等形态
  • pinch-手指捏合姿势
  • point-手指指向☝🏻姿势
  • face-脸部
  • pointtip
  • pinchtip

后面两种 tip 类型小菜在测试的时候暂时没有测试出来。

Handtrack如何在p5js中使用?

1) 引入 handtrack.js

我们在 html 中除下引入 p5.js、p5.sound.min.js(如果用到声音处理)等 p5 核心 js 文件后,引入

<script src="https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js"></script>。成熟好用的 js 库一般都会在cdn.jsdelivr.net cdn 上有存储地址。这里我们不考虑npm install的情况,如果读者有这方面的诉求,可以查看 github 上的 readme 获得更详细的说明。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
 <meta charset="utf-8" />
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.sound.min.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/handtrackjs@latest/dist/handtrack.min.js"></script>
 <script src="sketch.js"></script>
 <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>   
</body>
</html>

2)声明模型的配置

代码语言:javascript
复制
// 参考官方的例子配置
const modelSettings = {
 flipHorizontal: true, // 水平是否镜像反转,如摄像头数据
 maxNumBoxes: 10, // 最大检测的矩形盒子数量
 iouThreshold: 0.5,  // iou阈值
 scoreThreshold: 0.6 // 评分阈值
}

3)下载模型开启检测

开启摄像头,成功后,handTrack 按照模型设置进行下载相应的模型,下载成功后,开始检测runDetection()

代码语言:javascript
复制
let canvas; // 画布
let model; // 模型
let capture; // 摄像头视频
function setup() {
 canvas = createCanvas(640, 480);

 capture = createCapture(VIDEO, function() {
  handTrack.load(modelSettings).then(lmodel => {
   model = lmodel;
   runDetection();
  });
 }); 
}

开启检测内部具体做了什么事情呢?

代码语言:javascript
复制
let predictionArr;

function runDetection() {
  // 模型开始对摄像头的 elt(dom 对象)中的数据进行检测
  // then 是 js 的 promise 的一种语法,这里简单理解一次检测结束后,获得了预测结果 predictions
 model.detect(capture.elt).then(predictions => {
  predictionArr = predictions;
  // model.renderPredictions(predictions, canvas, context, capture.elt); // 渲染检测值
  if (capture) {
      // 每一帧需要对摄像头数据进行检测
   requestAnimationFrame(runDetection);
  }
 });
}

这个检测会输入摄像头捕获的数据,然后给出预测结果。

4)玩转预测结果

我们在第三步拿到了预测结果predictionArr,便可以愉快的玩耍了。

那么这里面究竟存放了什么数据?

数组中的单个元素的数据结构如下:

代码语言:javascript
复制
{
    "bbox": [
        125.76276779174805,
        43.020243644714355,
        215.00505447387695,
        307.0961809158325
    ],
    "class": 5,
    "label": "face",
    "score": "0.76"
}
  • label:识别预测的类型,包含上面列举的7种类型,face、open、closed、pinch、point 等
  • score:打的分数,表示预测结果的好坏,分数越高,表明预测的准确度越高
  • class:和 label 标签类型对应,可以忽略
  • bbox:识别出的 label 它的像素位置和长宽范围,如识别出来的 label 为 face,bbox则为脸部的矩形范围,bbox[0]指的是矩形左上角 x 坐标,bbox[1]指的是矩形左上角 y 坐标,bbox[2]指的是矩形宽度,bbox[3]指的是矩形高度。
代码语言:javascript
复制
function drawPredictions() {
  predictionArr.forEach((item, i) => {
    // console.log(item);
    let w = item.bbox[2];
    let h = item.bbox[3];
    let x = item.bbox[0];
    let y = item.bbox[1];
    let centerX = x + w / 2;
    let centerY = y + h / 2;
    let score = item.score;
    let label = item.label;

    stroke(0);
    strokeWeight(2);
    fill(0, 100);
    rect(x, y, w, h, 10, 10, 10, 10); // 我就画个半透明矩形
    noStroke();
    fill(255);
    text(score, x + 10, y + 10); // 我就画个分数
    fill(255, 255, 0);
    text(label, x + 10, y + 40); // 我就画个标签

    // 你想干啥就在这里干吧
    if (item.label == "face") {
    } else if (item.label == "open") {
    } else if (item.label == "closed") {
    } else if (item.label == "point") {
    } else if (item.label == "pinch") {
    }
  });
}

这个最后的效果如上面视频号展示。

有了这些数据,我想,创意就交给亲爱的读者们了!

一些应用例子

其实手势的应用很广泛,放在 processing 中,我们常常可以这么做:

1)将原来鼠标移动的控制改为手部移动的控制

2)当手和其他物体重叠时,可以表示有意义的交互信号,如物体碰撞,选择物体等

3)两只手的协调处理,比如两只手一起转动,连线的角度就会发生变化,可以用来控制物体的旋转角度等

还有更多的想法控制,读者朋友们可以多多留言呀。

Skyfall

Wiki 上的一个例子,来自codepen[3],代码也是开源的,只不过不是用 p5js 的方式写的。

源码

代码小菜已经放到 https://github.com/xiaocai-laoniao/Processing100DaysSketch的 Day_032 练习中了,感兴趣的读者可以查看代码。或者直接查看 https://openprocessing.org/sketch/1322756。


小菜与老鸟后期会不定期更新一些 Processing 绘制的代码思路分析,欢迎关注不迷路。

如果有收获,能一键三连么?

参考资料

[1]

HandTrack github 地址: https://github.com/victordibia/handtrack.js/

[2]

官方网站: https://victordibia.com/handtrack.js/

[3]

codepen: https://codepen.io/victordibia/full/aGpRZV

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小菜与老鸟 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初识HandTrack
  • Handtrack如何在p5js中使用?
    • 1) 引入 handtrack.js
      • 2)声明模型的配置
        • 3)下载模型开启检测
          • 4)玩转预测结果
          • 一些应用例子
            • Skyfall
            • 源码
              • 参考资料
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档