基于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:'未知'});
      }
  },

问题

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

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

相关推荐
白乐天_n7 小时前
腾讯游戏安全移动赛题Tencent2016A
安全·游戏
这是我587 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
tealcwu8 小时前
【游戏设计原理】21 - 解谜游戏的设计
游戏·游戏策划
清梦20208 小时前
经典问题---跳跃游戏II(贪心算法)
算法·游戏·贪心算法
tealcwu10 小时前
【游戏设计原理】22 - 石头剪刀布
游戏·游戏策划
.生产的驴10 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
l1384942745112 小时前
Java每日一题(2)
java·开发语言·游戏
汤姆yu15 小时前
基于微信小程序的乡村旅游系统
微信小程序·旅游·乡村旅游
曲辒净16 小时前
微信小程序实现二维码海报保存分享功能
微信小程序·小程序
孤留光乩1 天前
从零搭建纯前端飞机大战游戏(附源码)
前端·javascript·游戏·html·css3