找回密码
 立即注册
首页 业界区 安全 【一步步开发AI运动APP】十二、自定义扩展新运动项目2 ...

【一步步开发AI运动APP】十二、自定义扩展新运动项目2

毁抨句 昨天 09:15
之前我们为您分享了【一步步开发AI运动小程序】开发系列博文,通过该系列博文,很多开发者开发出了很多精美的AI健身、线上运动赛事、AI学生体测、美体、康复锻炼等应用场景的AI运动小程序;为了帮助开发者继续深耕AI运动领域市场,今天开始我们将为您分享新系列【一步步开发AI运动APP】的博文,带您开发性能更强、体验更好的AI运动APP。
上一篇为您介绍了uni-app版运动识别插件的自定义扩展运动的基本架构、与小程序版运动识别插件的运动扩展差异,本篇我们就以双手并举为例带你来实现一个扩展运动。
一、动作姿态拆解

1.jpeg

如上图所示,这个运动主要为手部摆动动,包含2个分动作姿态,起始动作姿态1为双手垂放于左右两侧站立,结束动作姿态2双手举过头顶撑直为结束动作,完成动作2时计数加一,如此反复运动。
二、定义运动检测规则

接下来我们为这两个拆解姿态分别构建检测规则,检测规则及自定义姿态的检测可以参考本系列博文的前面章节及插件的pose-calc指南文档。

  • 先构建动作姿态1手垂于两侧并站立的动作的检测规则:
  1. {
  2.          name: '双手下垂',
  3.          calc: '$and',
  4.                  rules: [{
  5.                          name: '站立姿态',
  6.                          calc: 'stand',
  7.                          offset: 25
  8.                  }, {
  9.                          name: '左腋夹角',
  10.                          calc: 'match-angle',
  11.                          angleKey: 'left_shoulder',
  12.                          secondKey: 'left_hip',
  13.                          thirdKey: 'left_wrist',
  14.                          angle: 30,
  15.                          offset: 30
  16.                  }, {
  17.                          name: '左手下垂',
  18.                          calc: 'vertical',
  19.                          upperKey: 'left_shoulder',
  20.                          centerKey: 'left_elbow',
  21.                          lowerKey: 'left_wrist',
  22.                          offset: 25
  23.                  }, {
  24.                          name: '右腋夹角',
  25.                          calc: 'match-angle',
  26.                          angleKey: 'right_shoulder',
  27.                          secondKey: 'right_hip',
  28.                          thirdKey: 'right_wrist',
  29.                          angle: 30,
  30.                          offset: 30
  31.                  }, {
  32.                          name: '右手下垂',
  33.                          calc: 'vertical',
  34.                          upperKey: 'right_shoulder',
  35.                          centerKey: 'right_elbow',
  36.                          lowerKey: 'right_wrist',
  37.                          offset: 25
  38.                  }]
  39. }
复制代码

  • 再构建动作姿态2双手举过头顶伸直站立的检测规则:
  1. {
  2.         name: '双手上举',
  3.         calc: '$and',
  4.         rules: [{
  5.                 name: '左手上举',
  6.                 calc: 'position',
  7.                 referenceKey: 'left_eye',
  8.                 positionKey: 'left_wrist',
  9.                 position: 'top',
  10.                 relaxed: true
  11.         }, {
  12.                 name: '右手上举',
  13.                 calc: 'position',
  14.                 referenceKey: 'right_eye',
  15.                 positionKey: 'right_wrist',
  16.                 position: 'top',
  17.                 relaxed: true
  18.         }]
  19. }
复制代码
三、实现运动分析器

定义好动作姿态检测规则后,我们便可以实现此扩展运动的运动分析器了,完整代码如下:
  1. /**
  2. * 双手并举运动分析器
  3. */
  4. export class BothHandsUpSport {
  5.         context = null;
  6.         calculator = null; //ICalculator
  7.         stateTran = -1;
  8.         /**
  9.          * 初始化运动分析器
  10.          */
  11.         constructor() {
  12.                 this.calculator = createCalculator();
  13.                 this.buildRules();
  14.                 const that = this;
  15.                 this.context = createExtendSportContext({
  16.                         key: 'both-hands-up',
  17.                         name: '自定义-双手并举',
  18.                         tickMode: true,
  19.                         view: 'front_back',
  20.                         start: () => that.start(),
  21.                         // reset: this.reset,
  22.                         // stop: this.stop,
  23.                         pushing: human => that.pushing(human)
  24.                 });
  25.         }
  26.         buildRules() {
  27.                 this.rules = {};
  28.                 this.rules.ups = {
  29.                         name: '双手上举',
  30.                         calc: '$and',
  31.                         rules: [{
  32.                                 name: '左手上举',
  33.                                 calc: 'position',
  34.                                 referenceKey: 'left_eye',
  35.                                 positionKey: 'left_wrist',
  36.                                 position: 'top',
  37.                                 relaxed: true
  38.                         }, {
  39.                                 name: '右手上举',
  40.                                 calc: 'position',
  41.                                 referenceKey: 'right_eye',
  42.                                 positionKey: 'right_wrist',
  43.                                 position: 'top',
  44.                                 relaxed: true
  45.                         }]
  46.                 };
  47.                 this.rules.downs = {
  48.                         name: '双手下垂',
  49.                         calc: '$and',
  50.                         rules: [{
  51.                                 name: '站立姿态',
  52.                                 calc: 'stand',
  53.                                 offset: 25
  54.                         }, {
  55.                                 name: '左腋夹角',
  56.                                 calc: 'match-angle',
  57.                                 angleKey: 'left_shoulder',
  58.                                 secondKey: 'left_hip',
  59.                                 thirdKey: 'left_wrist',
  60.                                 angle: 30,
  61.                                 offset: 30
  62.                         }, {
  63.                                 name: '左手下垂',
  64.                                 calc: 'vertical',
  65.                                 upperKey: 'left_shoulder',
  66.                                 centerKey: 'left_elbow',
  67.                                 lowerKey: 'left_wrist',
  68.                                 offset: 25
  69.                         }, {
  70.                                 name: '右腋夹角',
  71.                                 calc: 'match-angle',
  72.                                 angleKey: 'right_shoulder',
  73.                                 secondKey: 'right_hip',
  74.                                 thirdKey: 'right_wrist',
  75.                                 angle: 30,
  76.                                 offset: 30
  77.                         }, {
  78.                                 name: '右手下垂',
  79.                                 calc: 'vertical',
  80.                                 upperKey: 'right_shoulder',
  81.                                 centerKey: 'right_elbow',
  82.                                 lowerKey: 'right_wrist',
  83.                                 offset: 25
  84.                         }]
  85.                 };
  86.         }
  87.         start() {
  88.                 this.stateTran = -1;
  89.                 console.log('运动启动', this);
  90.         }
  91.         pushing(fragment) {
  92.                 if (fragment.isNobody) {
  93.                         console.log('未识别到人体');
  94.                         return;
  95.                 }
  96.                 const human = fragment.human;
  97.                 if (this.stateTran != 1 && this.calculator.calculating(human, this.rules.downs)) {
  98.                         this.stateTran = 1;
  99.                         return;
  100.                 }
  101.                 if (this.stateTran == 1 && this.calculator.calculating(human, this.rules.ups)) {
  102.                         this.stateTran = 2;
  103.                         this.context.countTimes();
  104.                         this.context.emitTick(1);
  105.                 }
  106.         }
  107.         /**
  108.          * 获取当前扩展运动的原生分析器实例
  109.          * @returns 原生运动分析器实例
  110.          */
  111.         getSportInstance() {
  112.                 return this.context.getSport();
  113.         }
  114.         /**
  115.          * 获取当前扩展运动描述
  116.          *
  117.          * @returns  运动描述条目实例
  118.          */
  119.         static getDescriptor() {
  120.                 let item = {
  121.                         key: 'both-hands-up',
  122.                         name: '自定义-双手并举'
  123.                 };
  124.                 return item;
  125.         }
  126. }
复制代码
好了,本节就为您介绍到这,下一节我们将为您介绍将实现的自定义扩展运动列表的维护,敬请期待...
2.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册