protected override int Recognise(FeatureData data) { // 当另一只手也举起则无效 if (data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderLeft, 0) == 1) { _motionState = MotionState.Invalid; return(0); } switch (_motionState) { case MotionState.Initial: // 当超过肩开始生效 if (data.CompareThresholdY(JointType.HandRight, JointType.ShoulderLeft, 0) == 1) { // 太近了则无效,区别于划圆 if (data.CalculateDifferX(JointType.HandRight, JointType.ShoulderCenter) < 5 || (data.HandRight2BodyHorizontalDistance < data.ShoulderCenter2SpineHeight && data.CalculateSpaceDistance(JointType.HandRight, JointType.ShoulderLeft) < data.ShoulderCenter2SpineHeight)) { _motionState = MotionState.Invalid; } else { _motionState = MotionState.Valid; } } break; case MotionState.Valid: // 手举起后肘关节与头的相对位置 //if (data.CompareThresholdY(JointType.ElbowRight, JointType.Head, 13) == 0 && // data.CompareThresholdX(JointType.ElbowRight, JointType.Head, 33) == 0) if (data.CompareThresholdY(JointType.HandRight, JointType.Head, 5) == 1) { _motionState = MotionState.Invalid; return(1); } //else if (data.HandRight2BodyHorizontalDistance > 1.1 * data.Head2HipCenterHeight) // 在有效状态下,超出身体指定的范围标记为无效,可能是从侧面举起手的 //{ // // 水平距离的阈值,大致估计手的比例,确保身高不影响(可用1.8 * data.ShoulderCenter2SpineHeight) // _motionState = MotionState.Invalid; //} break; default: break; } // 手放下来后恢复初始状态 if (_motionState != MotionState.Initial && data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1) { _motionState = MotionState.Initial; } return(0); }
private const float LegRadianThreshold = 0.64f; //弧度阈值;40度约为0.64左右,45度约为0.707 protected override int Recognise(FeatureData data) { switch (_motionState) { case MotionState.Initial: // 判断是否抬高脚 if (data.CompareThresholdY(JointType.AnkleLeft, JointType.AnkleRight, 10) == 1) // 用Y判断脚抬高度,脚离地阈值为10 { _motionState = MotionState.Valid; } break; case MotionState.Valid: // 区别抬脚动作 if (data.CompareThresholdZ(JointType.AnkleLeft, JointType.HipLeft, 30) == 0 && data.CompareThresholdX(JointType.AnkleLeft, JointType.HipLeft, 15) == 0) { _motionState = MotionState.Invalid; return(0); } // 大概的腿长,从踝开始计算 float legLength = data.CalculateDifferY(JointType.HipRight, JointType.AnkleRight); if (legLength <= 0) // 腿长不适合理论数据 { return(0); } // 在x和z轴上的映射投影距离差值 float ankleDifferX = Math.Abs(data.CalculateDifferX(JointType.AnkleLeft, JointType.AnkleRight)); float ankleDifferZ = Math.Abs(data.CalculateDifferZ(JointType.AnkleLeft, JointType.AnkleRight)); if (ankleDifferX >= ankleDifferZ) // 排除向前或后踢的情况 { // 计算腿抬起后裸相差的水平距离 float ankleHorizontalDistance = (float)Math.Sqrt(ankleDifferX * ankleDifferX + ankleDifferZ * ankleDifferZ); // 计算腿抬起的弧度 float legRadian = ankleHorizontalDistance / legLength; // 当抬起角度超过弧度阈值后生效 if (legRadian > LegRadianThreshold) { _motionState = MotionState.Invalid; return(1); } } else { _motionState = MotionState.Invalid; } break; default: // 放下脚恢复初始状态 if (data.CompareThresholdY(JointType.AnkleLeft, JointType.AnkleRight, 5) == 0) { _motionState = MotionState.Initial; } break; } return(0); }
protected override int Recognise(FeatureData data) { // 如果另一只手不在初始位置,则不识别 if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == 1) { _motionState = MotionState.Invalid; return(0); } switch (_motionState) { case MotionState.Initial: // 手超过一定位置 if (data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderRight, 0) == 1) { // 用肩中心到脊椎的距离大致估计手的比例,确保身高不影响,超出身体指定的范围标记为无效,此时刚好为到Y轴的距离 // 并且手在身体附近 if (data.CalculateDifferX(JointType.ShoulderCenter, JointType.HandLeft) < 5 || (data.HandLeft2BodyHorizontalDistance < data.ShoulderCenter2SpineHeight && data.CalculateSpaceDistance(JointType.HandLeft, JointType.ShoulderRight) < data.ShoulderCenter2SpineHeight)) { _motionState = MotionState.Valid; } else { _motionState = MotionState.Invalid; } } break; case MotionState.Valid: // 达到第一个有效点后 // 判断是否超过了头 if (data.CompareThresholdY(JointType.HandLeft, JointType.Head, 0) == 1) { _motionState = MotionState.Valid2; } break; case MotionState.Valid2: // 第二个有效点 if (data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderLeft, 15) == 0) // 经过了肩的位置,表明正放下 { _motionState = MotionState.Invalid; // 无论结果如何都无效 // 手是否伸直的,上身的高度,用于近视计算手的比例 if (data.HandLeft2BodyHorizontalDistance > data.Head2HipCenterHeight * 0.8) { return(1); } } break; default: break; } // 当手放下时 if (_motionState != MotionState.Initial && data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1) { _motionState = MotionState.Initial; } return(0); }