Exemplo n.º 1
0
        private const float LegRadianThreshold = 0.57f; //30, 0.64f; //弧度阈值;40度约为0.64左右,45度约为0.707

        #endregion Fields

        #region Methods

        protected override bool Recognise(FeatureData data)
        {
            switch (_motionState)
            {
                case MotionState.Initial:
                    // 判断是否抬高脚
                    if (data.CompareThresholdY(JointType.AnkleRight, JointType.AnkleLeft, 10) == 1) // 用Y判断脚抬高度,脚离地阈值为10
                    {
                        _motionState = MotionState.Valid;
                    }
                    break;
                case MotionState.Valid:
                    // 区别抬脚动作
                    if (data.CompareThresholdZ(JointType.AnkleRight, JointType.HipRight, 30) == 0 &&
                        data.CompareThresholdX(JointType.AnkleRight, JointType.HipRight, 15) == 0)
                    {
                        _motionState = MotionState.Invalid;
                        return false;
                    }
                    // 大概的腿长,从踝开始计算
                    float legLength = data.CalculateDifferY(JointType.HipLeft, JointType.AnkleLeft);
                    if (legLength <= 0) // 腿长不适合理论数据
                    {
                        return false;
                    }
                    // 在x和z轴上的映射投影距离差值
                    float ankleDifferX = Math.Abs(data.CalculateDifferX(JointType.AnkleRight, JointType.AnkleLeft));
                    float ankleDifferZ = Math.Abs(data.CalculateDifferZ(JointType.AnkleRight, JointType.AnkleLeft));

                    if (ankleDifferX >= ankleDifferZ) // 排除向前或后踢的情况
                    {
                        // 计算腿抬起后裸相差的水平距离
                        float ankleHorizontalDistance = (float)Math.Sqrt(ankleDifferX * ankleDifferX + ankleDifferZ * ankleDifferZ);

                        // 计算腿抬起的弧度
                        float legRadian = ankleHorizontalDistance / legLength;

                        // 当抬起角度超过弧度阈值后生效
                        if (legRadian > LegRadianThreshold)
                        {
                            _motionState = MotionState.Invalid;
                            return true;
                        }
                    }
                    else
                    {
                        _motionState = MotionState.Invalid;
                    }
                    break;
                default:
                    // 放下脚恢复初始状态
                    if (data.CompareThresholdY(JointType.AnkleRight, JointType.AnkleLeft, 5) == 0)
                    {
                        _motionState = MotionState.Initial;
                    }
                    break;
            }
            return false;
        }
Exemplo n.º 2
0
        protected override bool Recognise(FeatureData data)
        {
            // 如果另一只手不在初始位置,则不识别
            if (data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == 1)
            {
                _motionState = MotionState.Invalid;
                return false;
            }

            switch(_motionState)
            {
                case MotionState.Initial:
                    // 手超过一定位置
                    if (data.CompareThresholdY(JointType.HandRight, JointType.ShoulderLeft, 0) == 1)
                    {
                        // 用肩中心到脊椎的距离大致估计手的比例,确保身高不影响,超出身体指定的范围标记为无效,此时刚好为到Y轴的距离
                        // 并且手在身体附近
                        if (data.CalculateDifferX(JointType.HandRight, JointType.ShoulderCenter) < 5 ||
                            (data.HandRight2BodyHorizontalDistance < data.ShoulderCenter2SpineHeight &&
                            data.CalculateSpaceDistance(JointType.HandRight, JointType.ShoulderLeft) < data.ShoulderCenter2SpineHeight))
                        {
                            _motionState = MotionState.Valid;
                        }
                        else
                        {
                            _motionState = MotionState.Invalid;
                        }
                    }
                    break;
                case MotionState.Valid: // 达到第一个有效点后
                    // 判断是否超过了头
                    if (data.CompareThresholdY(JointType.HandRight, JointType.Head, 0) == 1)
                    {
                        _motionState = MotionState.Valid2;
                    }
                    break;
                case MotionState.Valid2: // 第二个有效点
                    if (data.CompareThresholdY(JointType.HandRight, JointType.ShoulderRight, 15) == 0) // 经过了肩的位置,表明正放下
                    {
                        _motionState = MotionState.Invalid; // 无论结果如何都无效

                        // 手是否伸直的,上身的高度,用于近视计算手的比例
                        if (data.HandRight2BodyHorizontalDistance > data.Head2HipCenterHeight*0.8)
                        {
                            return true;
                        }
                    }
                    break;
                default:
                    break;
            }
            // 当手放下时
            if (_motionState != MotionState.Initial &&
                data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1)
            {
                _motionState = MotionState.Initial;
            }
            return false;
        }
Exemplo n.º 3
0
        protected override bool Recognise(FeatureData data)
        {
            // 当另一只手也举起则无效
            if (data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderLeft, 0) == 1)
            {
                _motionState = MotionState.Invalid;
                return false;
            }

            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, 8) == 1)
                    {
                        _motionState = MotionState.Invalid;
                        return true;
                    }
                    //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 false;
        }