/** * 原地踏步走运动 * 1.要求侧位视图。 * 2.左、右任一次摆臂和提脚视计数1。 * * @alphaair * 20230329 created. **/ const utils = require("../../utils/utils"); const AiSport = requirePlugin("aiSport"); const SportBase = AiSport.sports.SportBase; const Calculator = AiSport.calc.Calculator; const CalcBase = AiSport.calc.CalcBase; /** * 原地踏步运动分析器 */ class SportWalkInPlace extends SportBase { /** * 本运动检测规则 */ rules = null stateTran = -1 /** * 初始化分析器 * * @param {int?} pointThreshold 计算器取点评分阈值 */ constructor(pointThreshold) { super(pointThreshold); this.tickMode = true; //计次模式 this._calcBase = new CalcBase(); this._calculator = new Calculator(); this._calculator.pointThreshold = this.pointThreshold; this.rules = {}; this.buildRules(); } /** * 构建检测规则 */ buildRules() { this.rules.basePose = { name: '站立状态', calc: 'stand', offset: 80 }; this.rules.armPose = { name: '摆臂状态', calc: '$and', rules: [{ name: '左手伸值', calc: 'match-angle', angleKey: 'left_elbow', secondKey: 'left_shoulder', thirdKey: 'left_wrist', angle: 155, offset: 25 }, { name: '左手摆臂', calc: 'match-angle', angleKey: 'left_shoulder', secondKey: 'left_hip', thirdKey: 'left_wrist', angle: 68, offset: 43 }, { name: '右手伸值', calc: 'match-angle', angleKey: 'right_elbow', secondKey: 'right_shoulder', thirdKey: 'right_wrist', angle: 155, offset: 25 }, { name: '右手摆臂', calc: 'match-angle', angleKey: 'right_shoulder', secondKey: 'right_hip', thirdKey: 'right_wrist', angle: 68, offset: 43 }] }; this.rules.leftLeg = { name: '左脚抬起', calc: 'match-angle', angleKey: 'left_knee', secondKey: 'left_hip', thirdKey: 'left_ankle', angle: 125, offset: 35 }; this.rules.rightLeg = { name: '右脚抬起', calc: 'match-angle', angleKey: 'right_knee', secondKey: 'right_hip', thirdKey: 'right_ankle', angle: 125, offset: 35 }; } /** * 启动分析 */ start() { super.start(); this.stateTran = -1; } /** * 接受帧识别结果,进行分析 * * @param {BodyDetectionResult} body 人体检测结果 */ pushing(body) { if (utils.isNone(body)) return; //基本姿态 if (!this._calculator.calculating(body, this.rules.basePose) || !this._calculator.calculating(body, this.rules.armPose)) { console.debug('基本姿态未通过'); return; } let leg = -1; //1-左边 2-右边 if (this.stateTran === -1 || this.stateTran === 2) { if (this._calculator.calculating(body, this.rules.leftLeg)) leg = 1; else console.error('左侧未通过'); } if (leg === -1 || this.stateTran === 1) { if (this._calculator.calculating(body, this.rules.rightLeg)) leg = 2; else console.error('右侧未通过'); } const leftAngle = this._calcBase.angle(body.keypoints[13], body.keypoints[11], body.keypoints[15]); const rightAngle = this._calcBase.angle(body.keypoints[14], body.keypoints[13], body.keypoints[16]); console.debug(this.stateTran, leg, leftAngle, rightAngle); if (this.stateTran === leg || leg === -1) return; //互斥才计数,防止中间动作被计数 this.stateTran = leg; this.countTimes(); this.emitTick(); } } SportWalkInPlace.KEY = "Walk-In-Place"; SportWalkInPlace.NAME = "自定义-原地踏步"; module.exports = SportWalkInPlace;