protected override int Recognise(FeatureData data) { switch (_motionState) { case MotionState.Initial: float footHeight = data.CalculateDifferY(JointType.AnkleLeft, JointType.AnkleRight); // 判断是否抬高脚data.CompareThresholdY(JointType.AnkleLeft, JointType.AnkleRight, 15) == 1 if (footHeight > MinFootHeight && footHeight < MaxFootHeight) // 用Y判断脚抬高度,脚离地阈值为15 { _motionState = MotionState.Invalid; // 标记为无效,等待放下脚恢复初始状态 if (data.CompareThresholdZ(JointType.AnkleLeft, JointType.HipLeft, 30) == 0 && // 用Z排除非前踢腿 data.CompareThresholdX(JointType.AnkleLeft, JointType.HipLeft, 15) == 0) // 用X排除非左右侧踢腿 { return(1); } } break; default: // 放下脚恢复初始状态 if (data.CompareThresholdY(JointType.AnkleLeft, JointType.AnkleRight, 5) == 0) { _motionState = MotionState.Initial; } break; } return(0); }
protected override int Recognise(FeatureData data) { // 计算两脚高度差 float ankleDifferY = Math.Abs(data.CalculateDifferY(JointType.AnkleRight, JointType.AnkleLeft)); // 计算两脚的绝对坐标 float absoluteAnkleRightY = data.RelativeJoints[(int)JointType.AnkleRight].y + data.AbsoluteOrigin.y; float absoluteAnkleLeftY = data.RelativeJoints[(int)JointType.AnkleLeft].y + data.AbsoluteOrigin.y; //bool tracked = data.IsJointTracked(KinectWrapper.NuiSkeletonPositionIndex.AnkleRight); Waterstrong // 两脚绝对坐标Y的较小值 float minAbsoluteAnkleY = Math.Min(absoluteAnkleLeftY, absoluteAnkleRightY); // 当一只脚超过另一脚时 if (ankleDifferY > MaxHeightThreshold) { // 当想站上某个高处时即开始准备重设地面,获取较大值 _groundLevel = Math.Max(absoluteAnkleLeftY, absoluteAnkleRightY); } switch (_motionState) { case MotionState.Initial: // 当两脚高度差不超过阈值时 if (ankleDifferY < MinHeightThreshold) { // 获取左右脚以及地面中最小的值来重设地面 _groundLevel = Math.Min(minAbsoluteAnkleY, _groundLevel); // 直接判断 if (minAbsoluteAnkleY - _groundLevel > JumpHeightThreshold /*&& tracked Waterstrong*/) { // 重置地面,用于判断是否开始落下,否则跳太高会二次识别 _groundLevel = minAbsoluteAnkleY; _counter = 0; _motionState = MotionState.Invalid; return(1); } } break; default: if (minAbsoluteAnkleY < _groundLevel) // 当开始落下时才生效 { _motionState = MotionState.Initial; } else if (++_counter >= CounterThreshold) // 可能跳到了一个较高的地方,需要一段时间来重置 { _counter = 0; _groundLevel = minAbsoluteAnkleY; _motionState = MotionState.Initial; } break; } 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); }