基于xr-frame实现微信小程序的手部、手势识别3D模型叠加和石头剪刀布游戏功能

前言

xr-frame是一套小程序官方提供的XR/3D应用解决方案,基于混合方案实现,性能逼近原生、效果好、易用、强扩展、渐进式、遵循小程序开发标准。xr-frame在基础库v2.32.0开始基本稳定,发布为正式版,但仍有一些功能还在开发,目前(2024.11)有一些限制如下:

1最低要求客户端iOS8.0.29、安卓8.0.30及以上,推荐稳定版在iOS8.0.36、安卓8.0.35及以上。

2基础库最低2.27.1及以上,推荐2.32.0及以上。 3开发工具需要最新版本,建议Nightly版本。

4小程序全局同一时刻只能存在一个xr-frame组件,否则可能会发生异常。

5同一个xr-frame组件只能存在一个xr-scene,并且必须为顶层。 6目前不支持和小程序传统标签比如混写。

7目前不支持wxml自动补全,真机调试需要特别注意,见真机调试文档。

后续的展望:

1 XR-FRAME内置特色的UI组件,让开发者可以在XR-FRAME组件中写UI,来实现一套酷炫的UI系统。 2

AR/VR能力持续增强,支持眼睛设备。 3 交互手段进一步强化,物理碰撞、触发等功能(已完成,待发布)。 4

工具能力强化,包括标签属性自动补全等。

在这一文章中,我将会利用以该解决方案的官方demo为参考开发微信小程序的人手识别案例并叠加模型动作的功能,具体使用的是Hand识别模式,去识别出摄像头画面中的会通过图像算法识别出人手部的特征点,然后变换到3D空间,继而进行追踪。用它构建一个XR小程序,实现一个人手识别叠加3D动作模型,实现手势识别的石头剪刀布的小游戏逻辑。

效果

指尖追踪叠加模型:

石头剪刀布效果:

实现过程

Hand模式,从基础库2.28.1开始支持。

其中就需要将模式修改为 手部模式(modes:Hand):

xml 复制代码
<xr-scene ar-system="modes:Hand" bind:ready="handleReady" bind:tick="handleTick">
</xr-scene>

手部识别模式,会通过图像算法识别出人手部的特征点,然后变换到3D空间,可用于一些手势等场景。与Face模式用法一致,但多出了两个参数:

javascript 复制代码
// 获取手势姿态
const gesture = tracker.gesture;
// 获取总体置信度
const score = tracker.score;

人手特征追踪

人手的识别后,会形成手部对应人手的特征点,特征点的设定如下图:

比如要在大拇指的指尖上叠加一个模型,就使用AR追踪器(xr-ar-tracker)来实现追踪,模式修改为Hand,参照上图的手部特征点数值大拇指为4,同步特征点属性设置为auto-sync="4",完整AR追踪器实现如下:

xml 复制代码
  <xr-ar-tracker id="tracker" mode="Hand" auto-sync="4">
    <xr-gltf model="hudie" rotation="0 90 -90" anim-autoplay scale="0.5 0.5 0.5"/>
  </xr-ar-tracker>

这个就是在大拇指的指尖上叠加了蝴蝶模型,同时自动播放模型动作。

手势识别

图像算法识别出人手部的特征点后,变换到3D空间,进一步会识别出手部的手势,手势的数值通过tracker.gesture获取, tracker.score是手势的置信度,其中手势姿态(0~18,-1为无效/未知手势)如下图:

因为是石头剪刀布的游戏,只用关心这三个状态:布1 ; 剪刀2;石头3;

手势获取通过bind:tick事件(bind:tick="handleTick")绑定到handleTick函数,每帧检测手势信息:

javascript 复制代码
handleTick: function () {
      if (!this.tracker || this.result) return;
      const {gesture, score} = this.tracker;
      //console.log(" gesture:"+gesture+"  score:"+score);
      if (gesture === -1 || score < 0.3 ) 
      {
        return;
      }
      this.triggerEvent('info', {gesture, score});
}

这里的handleTick的处理是将追踪器中的手势信息和置信度信息解析出来,有效手势和置信度大于0.3的再触发事件info,将数据传送到页面。

而页面这边,在wxml中组件中将info事件绑定到handleInfo中处理:

javascript 复制代码
bind:info="handleInfo"

handleInfo函数就将数据记录到data中,而且同时处理石头剪刀布的手势逻辑,和他们的克制关系,让识别出来的手势永远被xr-frame所压制:

javascript 复制代码
handleInfo: function({detail}) {
    console.log("handleInfo gesture:"+detail.gesture+"  score:"+detail.score);
    this.setData({gesture: detail.gesture, score: detail.score.toFixed(2)});
    if(this.data.result)
      return;
      if(this.data.gesture === 1){
         this.setData({gesRltImg: 'bu',gesRltName:'布',arRltImg:'jiandao',arRltName:'剪刀'});
      }else if(this.data.gesture === 2){
        this.setData({gesRltImg: 'jiandao',gesRltName:'剪刀',arRltImg:'shitou',arRltName:'石头'});
      }else if(this.data.gesture === 3){
        this.setData({gesRltImg: 'shitou',gesRltName:'石头',arRltImg:'bu',arRltName:'布'});
      }else{
        this.setData({gesRltImg: 'unknow',gesRltName:'未知',arRltImg:'unknow',arRltName:'未知'});
      }
  },

问题

目前在安卓机实机测试中,感觉变换后手势识别的有些延后,实录如下:

以上的问题,造成了这个石头剪刀布小游戏的体验也不如意,按理识别速度快,可以快速的换手势,系统也能在肉眼不可见的反应时间内,识别出变化,再出一个克制的手势,而现在测试还是无法做到的,要么提前出拳,要么变换后识别不出结果。

相关推荐
尘浮生1 小时前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
/**书香门第*/2 小时前
Cocos creator 3.8 支持的动画 7
学习·游戏·游戏引擎·游戏程序·cocos2d
HerayChen3 小时前
微信小程序混合 h5 wx.miniProgram是 undefined
微信小程序·小程序·h5
九州ip动态4 小时前
做网络推广及游戏注册为什么要换IP
网络·tcp/ip·游戏
中云DDoS CC防护蔡蔡10 小时前
微信小程序被攻击怎么选择高防产品
服务器·网络安全·微信小程序·小程序·ddos
井眼13 小时前
微信小程序-prettier 格式化
微信小程序·小程序
向宇it15 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
qq_174482857516 小时前
springboot基于微信小程序的旧衣回收系统的设计与实现
spring boot·后端·微信小程序
wqq_99225027716 小时前
springboot基于微信小程序的食堂预约点餐系统
数据库·微信小程序·小程序
licy__1 天前
微信小程序登录注册页面设计(小程序项目)
微信小程序·小程序