YD_WeChatApplet/module-sport/sports/sport-walk-in-place.js
2025-06-06 15:17:30 +08:00

173 lines
4.5 KiB
JavaScript

/**
* 原地踏步走运动
* 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;