コード例 #1
0
        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);
        }
コード例 #2
0
        private const double TimeMillisecondsThreshold = 750d; // 时间阈值,以毫秒计算
        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.ShoulderLeft, 0) == 1)
                {
                    _dtBegin     = DateTime.Now; // 获取开始时间
                    _motionState = MotionState.Valid;
                }
                break;

            case MotionState.Valid:
                // 如果生效了,则判断是否回到初始位置,如果是,则识别成功
                if (data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1)
                {
                    _motionState = MotionState.Initial;
                    _dtEnd       = DateTime.Now; // 获取截止时间
                    // 如果时间差小于一定的阈值则识别
                    if (_dtEnd.Subtract(_dtBegin).TotalMilliseconds < TimeMillisecondsThreshold)
                    {
                        return(1);
                    }
                }
                break;

            default:
                // 其他状态回到了初始位置,则重置状态为初始状态
                if (data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1)
                {
                    _motionState = MotionState.Initial;
                }
                break;
            }
            if (_motionState != MotionState.Invalid)
            {
                // 如果手抬起太高,则抬起失效
                if (data.CompareThresholdY(JointType.HandLeft, JointType.Head, 5) == 1)
                {
                    _motionState = MotionState.Invalid;
                }

                // 超出身体指定的范围标记为无效,此时刚好为到Y轴的距离
                if (data.HandLeft2BodyHorizontalDistance > data.Head2HipCenterHeight)
                {
                    _motionState = MotionState.Invalid;
                }
            }
            return(0);
        }
コード例 #3
0
        protected override int Recognise(FeatureData data)
        {
            // 如果另一只手不在初始位置,则不识别
            if (data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == 1)
            {
                _motionState = MotionState.Invalid;
                return(0);
            }

            switch (_motionState)
            {
            case MotionState.Initial:
                // 用肩中心到脊椎的距离大致估计手的比例,确保身高不影响,超出身体指定的范围标记为无效,此时刚好为到Y轴的距离
                // 手超过了脊椎的位置并且手在身体附近
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == 1 &&
                    data.HandRight2BodyHorizontalDistance < data.ShoulderCenter2SpineHeight)
                {
                    _motionState = MotionState.Valid;
                }
                break;

            case MotionState.Valid:
                // 上身的高度,用于近视计算手的比例
                if (data.HandRight2BodyHorizontalDistance > data.Head2HipCenterHeight)
                {
                    _motionState = MotionState.Initial;
                    return(1);
                }
                break;

            default:
                break;
            }
            // 如果手抬起太高,则抬起失效
            if (_motionState != MotionState.Invalid &&
                data.CompareThresholdY(JointType.HandRight, JointType.Head, 0) == 1)
            {
                _motionState = MotionState.Invalid;
            }
            // 当手放下时
            if (_motionState != MotionState.Initial)
            {
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1)
                {
                    _motionState = MotionState.Initial;
                }
                else if (_motionState == MotionState.Invalid && // 当因为另一只手抬起导致状态无效时
                         data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1)
                {
                    _motionState = MotionState.Initial;
                }
            }
            return(0);
        }
コード例 #4
0
        protected override int Recognise(FeatureData data)
        {
            switch (_motionState)
            {
            case MotionState.Initial:
                // 手超过了脊椎的位置
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == 1 &&
                    data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == 1)
                {
                    // 用肩中心到脊椎的距离替代肩宽,理论上比肩宽大一些
                    // 并且两手距离近
                    if (data.Hand2HandHorizontalDistance < data.ShoulderCenter2SpineHeight)
                    {
                        _motionState = MotionState.Valid;
                    }
                    //else
                    //{
                    //    _motionState = MotionState.Invalid; // W.S.
                    //}
                }
                break;

            case MotionState.Valid:
                // 上身的高度,用于近视计算手的比例 WS (此处不知双手平推和双手展开的区别,先区别一个双手交叉吧)
                // 当两手距离超过阈值后识别成功
                if (data.Hand2HandHorizontalDistance > 2 * data.ShoulderCenter2HipCenterHeight)
                {
                    //_motionState = MotionState.Invalid; // 无论是否成功识别者标记为无效状态 W.S.
                    _motionState = MotionState.Initial;     // 为了多次识别
                    // 区别于双手向下的动作,只有在肩的上方
                    if (data.CompareThresholdY(JointType.HandRight, JointType.ShoulderRight, 5) >= 0 &&
                        data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderLeft, 5) >= 0)
                    {
                        return(1);
                    }
                }
                break;

            default:
                break;
            }
            // 如果手抬起太高,则抬起失效
            if (_motionState != MotionState.Invalid &&
                (data.CompareThresholdY(JointType.HandRight, JointType.ShoulderCenter, 15) == 1 ||
                 data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderCenter, 15) == 1))
            {
                _motionState = MotionState.Invalid;
            }
            // 当手放下时恢复初始
            if (_motionState != MotionState.Initial)
            {
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1 ||
                    data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1)
                {
                    _motionState = MotionState.Initial;
                }
            }
            return(0);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
ファイル: HandsUp.cs プロジェクト: 791771289/VirtualAssembly
        protected override int Recognise(FeatureData data)
        {
            // 用肩中心到脊椎的距离替代肩宽,理论上比肩宽大一些
            float minHorizontalDistanceThreshold = data.ShoulderCenter2SpineHeight;

            switch (_motionState)
            {
            case MotionState.Initial:
                // 手是否在经过肩附近
                if (data.CompareThresholdY(JointType.HandRight, JointType.ShoulderRight, 15) == 0 &&
                    data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderRight, 15) == 0 &&
                    data.Hand2HandHorizontalDistance < minHorizontalDistanceThreshold)     // 并且两手距离很近
                {
                    _motionState = MotionState.Valid;
                }
                break;

            case MotionState.Valid:
                // 上身的高度,用于近视计算手的比例
                // 当两手距离超过阈值后识别成功
                if (data.Hand2HandHorizontalDistance > /*2 * */ data.ShoulderCenter2HipCenterHeight)
                {
                    // 判断是否高于头部
                    if (data.CompareThresholdY(JointType.HandRight, JointType.Head, 0) == 1 &&
                        data.CompareThresholdY(JointType.HandLeft, JointType.Head, 0) == 1)
                    {
                        _motionState = MotionState.Initial;     // 识别后标记为初始状态
                        return(1);
                    }
                    else if (data.Hand2HandHorizontalDistance > 2 * data.ShoulderCenter2HipCenterHeight)    // &&
                    //data.CompareThresholdY(JointType.HandRight, JointType.ShoulderRight, 15) == 0 &&
                    //data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderRight, 15) == 0)
                    {
                        _motionState = MotionState.Initial;     // 排除从两边抬起手臂,还可排除手低的情况
                    }
                }
                break;

            default:
                break;
            }
            // 当手放下时恢复初始状态
            if (_motionState != MotionState.Initial &&
                (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1 ||
                 data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1))
            {
                _motionState = MotionState.Initial;
            }
            // 当两手合在一起后超过头设置
            //if (_motionState != MotionState.Initial &&
            //    data.Hand2HandHorizontalDistance < minHorizontalDistanceThreshold &&
            //    (data.CompareThresholdY(JointType.HandRight, JointType.Head, 0) == 1 ||
            //    data.CompareThresholdY(JointType.HandLeft, JointType.Head, 0) == 1))
            //{
            //    _motionState = MotionState.Initial;
            //}
            return(0);
        }
コード例 #7
0
        protected override int Recognise(FeatureData data)
        {
            switch (_motionState)
            {
            case MotionState.Initial:
                // 手超过了脊椎的位置
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == 1 &&
                    data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == 1)
                {
                    // 并且两手距离很远(上半身的高度,用于近视计算手的比例)
                    if (data.Hand2HandHorizontalDistance > 2 * data.ShoulderCenter2HipCenterHeight)
                    {
                        _motionState = MotionState.Valid;
                    }
                    else
                    {
                        _motionState = MotionState.Invalid;
                    }
                }
                break;

            case MotionState.Valid:
                // 用肩中心到脊椎的距离替代肩宽,理论上比肩宽大一些
                if (data.Hand2HandHorizontalDistance < data.ShoulderCenter2SpineHeight)
                {
                    _motionState = MotionState.Invalid;     // 识别后标记为无效状态
                    return(1);
                }
                break;

            default:
                break;
            }
            // 如果手抬起太高,则抬起失效
            if (_motionState != MotionState.Invalid &&
                (data.CompareThresholdY(JointType.HandRight, JointType.Head, 0) == 1 ||
                 data.CompareThresholdY(JointType.HandLeft, JointType.Head, 0) == 1))
            {
                _motionState = MotionState.Invalid;
            }
            // 当手放下时恢复初始状态
            if (_motionState != MotionState.Initial)
            {
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1 ||
                    data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1)
                {
                    _motionState = MotionState.Initial;
                }
            }
            return(0);
        }
コード例 #8
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);
        }
コード例 #9
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);
        }
コード例 #10
0
        private const double TimeMillisecondsThreshold = 800d; // 时间阈值,以毫秒计算
        protected override int Recognise(FeatureData data)
        {
            // 上身的高度,用于近视计算手的比例
            float maxHorizontalDistanceThreshold = 2 * data.ShoulderCenter2HipCenterHeight;

            switch (_motionState)
            {
            case MotionState.Initial:
                // 手超过了脊椎的位置
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == 1 &&
                    data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == 1)
                {
                    // 并且两手距离不远,用max因为向下的手势比较难识别,所以范围大
                    if (data.Hand2HandHorizontalDistance < maxHorizontalDistanceThreshold)
                    {
                        _dtBegin     = DateTime.Now; // 获取开始时间
                        _motionState = MotionState.Valid;
                    }
                    else     // 区别于双手收缩
                    {
                        _motionState = MotionState.Invalid;
                    }
                }
                break;

            case MotionState.Valid:
                // 判断是否低于一定的位置
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1 &&
                    data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1)
                {
                    _dtEnd = DateTime.Now;
                    // 如果时间差小于一定的阈值则识别
                    if (_dtEnd.Subtract(_dtBegin).TotalMilliseconds < TimeMillisecondsThreshold)
                    {
                        // 当两手距离超过阈值后识别成功
                        if (data.Hand2HandHorizontalDistance > maxHorizontalDistanceThreshold)
                        {
                            _motionState = MotionState.Initial;     // 识别后标记为初始状态
                            return(1);
                        }
                    }
                    else
                    {
                        _motionState = MotionState.Invalid;     //时间到了后无效
                    }
                }
                else if (data.Hand2HandHorizontalDistance > maxHorizontalDistanceThreshold &&
                         data.CompareThresholdY(JointType.HandRight, JointType.ShoulderRight, 5) >= 0 &&
                         data.CompareThresholdY(JointType.HandLeft, JointType.ShoulderLeft, 5) >= 0)
                {
                    _motionState = MotionState.Invalid;
                }
                //else if (data.CompareThresholdY(JointType.HandRight, JointType.HipRight, 14) == -1 || // 加入时间戳后需要重置
                //    data.CompareThresholdY(JointType.HandLeft, JointType.HipLeft, 14) == -1)
                //{
                //    _motionState = MotionState.Invalid;
                //}
                break;

            default:
                // 当手放下时恢复初始
                if (data.CompareThresholdY(JointType.HandRight, JointType.Spine, 0) == -1 ||
                    data.CompareThresholdY(JointType.HandLeft, JointType.Spine, 0) == -1)
                {
                    _motionState = MotionState.Initial;
                }
                break;
            }
            // 如果手抬起太高,则抬起失效
            if (_motionState != MotionState.Invalid &&
                (data.CompareThresholdY(JointType.HandRight, JointType.Head, 0) == 1 ||
                 data.CompareThresholdY(JointType.HandLeft, JointType.Head, 0) == 1))
            {
                _motionState = MotionState.Invalid;
            }
            return(0);
        }