使用 MediaPipe 和 Three.js 的网络摄像头创建 3D 场景中的手势控制器

职场   2024-10-25 16:26   北京  

了解如何使用@mediapipe/hands 和 Three.js 创建具有深度的完整 3D 手控制器。

今天将展示如何仅使用双手、网络摄像头和网络浏览器来控制 3D 场景中的元素。这里的关键重点是将 2D 屏幕转换为 3D 空间,并实现完全深度控制。

为了实现这个结果,我们将使用MediapipeThree.js

介绍之前可以先体验一下使用这个技术的游戏:

https://caiobassetti.com/experiments/spaceship-control/

  1. 安装:

    需要创建@mediapipe/hands实例来检测手部特征点。


建了一个包含此实现的class调用MediaPipeHands,因此我们可以轻松地将其添加到代码中并在任何地方重复使用它。

onMediaPipeHandsResults是库的一个回调,它返回了提到的坐标,它来自hands.onResults。

让我们用 Three.js 创建我们的 WebGL 场景,只包含一些我们可以交互的元素。

导入它并初始化它即可拥有一个场景:

创建控件

让我们开始使用坐标,它是@mediapipe/hands我之前提到的笛卡尔坐标。

这是参考资料,这样您就知道我在说什么,并了解我们将使用的值。


为了在 x/y 轴上移动元素,我将仅选择一个点,即9。MIDDLE_FINGER_MCP,我的选择仅基于此坐标的位置,它位于一切的中心并且有意义。
我们在这次探索中只使用一只手,因此坐标的前 21 个索引很重要。
如果您想使用两只手,请使用相同的数组并从索引 21 开始读取值。

if (landmarks.multiHandLandmarks.length === 1) {    for (let l = 0; l < 21; l++) {       this.handsObj.children[l].position.x = -landmarks.multiHandLandmarks[0][l].x + 0.5;       this.handsObj.children[l].position.y = -landmarks.multiHandLandmarks[0][l].y + 0.5;       this.handsObj.children[l].position.z = -landmarks.multiHandLandmarks[0][l].z;    }}

效果如下:

正如你所注意到的,坐标点即使在 3D 空间中也具有相同的比例,这是因为 @mediapipe/hands 没有合适的 z 轴,它是 2D。

Z 深度:2D 到 3D 的转换
我的想法是获取 2 个地标点,计算它们在 2D 空间中的距离,然后将其应用为深度。
正如您在上面的视频中看到的,光标(大球体)已经朝着与地标相反的正确方向移动。为了实现这一点,我从地标中选择了点0. WRIST和10. MIDDLE_FINGER_PIP。

我将这个值限制在 -2 到 4 之间以使其友好,但这不是必要的,这完全取决于您作为用户的感受。
因此,为了朝正确的方向移动,我们需要将这个距离反转为负值,这样当手靠近相机时,光标就远离相机。像这样:


手势

使用相同的逻辑来计算closed_fist手势。由于这是一个独特的手势,我们需要抓取一个对象,因此我们不需要导入另一个依赖项,例如GestureRecognizer。这将节省加载时间和内存使用量。
所以我得到了9. MIDDLE_FINGER_MCP和12. MIDDLE_FINGER_TIP并应用了相同的方法,基于我的手是否闭合的距离!

碰撞测试

让我们计算光标和物体之间的碰撞并开始抓住它们。

写了一个简单的 AABB 测试,因为在我的测试中,它比使用射线投射器更准确、性能更好。但请记住,每种情况都是一个案例,所以也许使用另一种算法甚至使用 Rasycater 会更好!

效果如下:


思考:
用这个交互,就可以通过摄像头来移动数字人了吧。

源码地址:
https://github.com/Cai3ra/webcam-3D-handcontrols
预览地址:
https://codepen.io/caiera/project/full/ZnJpBK
https://tympanus.net/Tutorials/webcam-3D-handcontrols/


有相同兴趣爱好的可通过加星球的方式添加作者微信。加入后查看置顶评论可加微信交流。
关于作者

做一只爬的最久的乌龟,保持学习保持好奇,即使慢一点,遇到一点困难,只要最后能到达终点,又有什么关系呢。
毕竟人生没有白走的路,每一步都算数。



前端程序设计
专注前端最前沿技术,数据可视化,web3d。偶尔插播生活和艺术。
 最新文章