예제 #1
0
        /// <summary>
        /// Compares a skeleton against the angle criterion
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        public override bool MatchesCriterion(SkeletonStamp skeletonStamp)
        {
            Joint vertexJoint; Joint[] adjacentJoints;
            int   convertedDotAngle = FindAngle(skeletonStamp, out vertexJoint, out adjacentJoints);

            return(convertedDotAngle > MinimumAngle && convertedDotAngle < MaximumAngle);
        }
예제 #2
0
        public override bool MatchesCriterion(SkeletonStamp skeletonStamp)
        {
            double alignmentValue = 0.0;

            Joint[] trackedJoints = new Joint[Joints.Length];
            Joint   centerJoint;
            int     i = 0;

            // get the joints to be aligned
            foreach (XmlJointType type in Joints)
            {
                trackedJoints[i++] = skeletonStamp.GetTrackedSkeleton().Joints[type.GetJointType()];
            }
            switch (Alignment)
            {
            case Alignment.Point:
                centerJoint    = skeletonStamp.GetTrackedSkeleton().Joints[CenterJoint.GetJointType()];
                alignmentValue = JointAnalyzer.AreJointsAligned(centerJoint, trackedJoints);
                break;

            case Alignment.Horizontal:
                alignmentValue = JointAnalyzer.AlignedHorizontally(trackedJoints[0], trackedJoints[1]);
                break;

            case Alignment.Vertical:
                alignmentValue = JointAnalyzer.AlignedVertically(trackedJoints[0], trackedJoints[1]);
                break;
            }
            return(alignmentValue > MaximumAcceptedRange);
        }
예제 #3
0
        /// <summary>
        /// Check form will validate all the tracked joints based on the criteria provided by trackedJoints
        /// Joints which are not compared are considered perfectly accurate (0)
        /// </summary>
        /// <returns></returns>
        public double[] CheckForm(SkeletonStamp skeletonStamp)
        {
            double[] jointAccuracy = new double[20];
            /* Keeps track of how many times the joint has been updated */
            double[] timesJointUpdated = new double[20];
            /** loop through each Criterion and determine if it is bad or not */
            /** aggregate all the results */
            foreach (Criterion criterion in TrackingCriteria)
            {
                double[] result = criterion.CheckForm(skeletonStamp);

                for (int i = 0; i < jointAccuracy.Length; i++)
                {
                    if (result[i] != -999)
                    {
                        jointAccuracy[i] += result[i];
                        timesJointUpdated[i]++;
                    }
                }
            }
            /* Take the average result based on the amount of times a joint was updated */
            for (int i = 0; i < jointAccuracy.Length; i++)
            {
                jointAccuracy[i] = jointAccuracy[i] / timesJointUpdated[i];
            }
            /** Joints which are not compared are considered perfectly accurate (0) */
            return(jointAccuracy);
        }
예제 #4
0
        public override double[] CheckForm(SkeletonStamp skeletonStamp)
        {
            Joint vertexJoint; Joint[] adjacentJoints;
            int   convertedDotAngle = FindAngle(skeletonStamp, out vertexJoint, out adjacentJoints);

            double normalizedAccuracy = 0;

            switch (Operation)
            {
            case Operation.GreaterThan:
                if (convertedDotAngle < MinimumAngle)
                {
                    normalizedAccuracy = (Angle - convertedDotAngle) / 180;
                }
                break;

            case Operation.LessThan:
                if (convertedDotAngle > MaximumAngle)
                {
                    normalizedAccuracy = (Angle - convertedDotAngle) / 180;
                }
                break;

            case Operation.Equals:
                normalizedAccuracy = (Angle - convertedDotAngle) / 180;
                break;
            }
            double[] results = new double[20];
            results[(int)vertexJoint.JointType]       = normalizedAccuracy;
            results[(int)adjacentJoints[0].JointType] = normalizedAccuracy;
            results[(int)adjacentJoints[1].JointType] = normalizedAccuracy;
            return(results);
        }
예제 #5
0
        public void Initialize()
        {
            this.universe = new SkeletonStamp[maxInstances];
            this.free     = new Queue <SkeletonStamp>(maxInstances);

            for (int i = 0; i < maxInstances; ++i)
            {
                universe[i] = new SkeletonStamp(new Skeleton[0], long.MaxValue);
                free.Enqueue(universe[i]);
            }
        }
예제 #6
0
        public SkeletonStamp[] ReadProcessedData(string fileId)
        {
            SkeletonStamp[] stamps = new SkeletonStamp[0];

            using (FileStream fs = new FileStream(FilesUsed[fileId] + "_data", FileMode.Open, FileAccess.Read))
            {
                PostProcessedRead ppr = new PostProcessedRead(fs);
                stamps = ppr.Data;
            }

            return(stamps);
        }
예제 #7
0
        private void CreateFromReader(BinaryReader reader)
        {
            SkeletonStamp frame = new SkeletonStamp(new Skeleton[0], 0);

            frame.PercentBad = new double[_jointLength];
            frame.TimeStamp  = reader.ReadInt64();
            for (int i = 0; i < _jointLength; ++i)
            {
                frame.PercentBad[i] = reader.ReadDouble();
            }

            _frames.Add(frame);
        }
예제 #8
0
        /// <summary>
        /// This method retrieves a new skeleton frame if necessary.
        /// </summary>
        /// <param name="gameTime">The elapsed game time.</param>
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            // If the sensor is not found, not running, or not connected, stop now
            if (null == this.Chooser.Sensor ||
                false == this.Chooser.Sensor.IsRunning ||
                KinectStatus.Connected != this.Chooser.Sensor.Status)
            {
                return;
            }

            if (this.RecordingManager.Status == RecordingManagerStatus.Replaying)
            {
                return;
            }

            // If we have already drawn this skeleton, then we should retrieve a new frame
            // This prevents us from calling the next frame more than once per update
            if (skeletonDrawn)
            {
                using (var skeletonFrame = this.Chooser.Sensor.SkeletonStream.OpenNextFrame(0))
                {
                    // Sometimes we get a null frame back if no data is ready
                    if (null == skeletonFrame)
                    {
                        return;
                    }

                    if (RecordingManager.Status == RecordingManagerStatus.Recording)
                    {
                        SkeletonStamp stamp = SkeletonPool.GetOldestProcessedSkeleton();
                        RecordingManager.Record(stamp.PercentBad, stamp.TimeStamp);
                        ++_counter;
                        RecordingManager.Record(skeletonFrame);
                    }

                    // Reallocate if necessary
                    if (null == skeletonData || skeletonData.Length != skeletonFrame.SkeletonArrayLength)
                    {
                        skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];
                    }

                    skeletonFrame.CopySkeletonDataTo(skeletonData);
                    SkeletonPool.Add(skeletonData, skeletonFrame.Timestamp);

                    skeletonDrawn = false;
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Determines whether the supplied skeleton matches the criteria
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        internal bool MatchesCriteria(SkeletonStamp skeletonStamp, Criterion[] criterion)
        {
            bool matches = true;

            // go through each joint's criteria and verify it is true
            foreach (Criterion c in criterion)
            {
                if (!c.MatchesCriterion(skeletonStamp))
                {
                    // no need to keep checking.
                    return(false);
                }
            }
            return(matches);
        }
예제 #10
0
        /// <summary>
        /// Finds the angle between the provided joints.
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <param name="vertexJoint"></param>
        /// <param name="adjacentJoints"></param>
        /// <returns></returns>
        private int FindAngle(SkeletonStamp skeletonStamp, out Joint vertexJoint, out Joint[] adjacentJoints)
        {
            // Test bone orientations
            Skeleton        skeleton = skeletonStamp.GetTrackedSkeleton();
            BoneOrientation bo       = skeleton.BoneOrientations[Vertex.GetJointType()];

            // get the vertex and other joints off the skeleton stamp
            vertexJoint = skeletonStamp.GetTrackedSkeleton().Joints[Vertex.GetJointType()];

            adjacentJoints    = new Joint[2];
            adjacentJoints[0] = skeletonStamp.GetTrackedSkeleton().Joints[OtherJoints[0].GetJointType()];
            adjacentJoints[1] = skeletonStamp.GetTrackedSkeleton().Joints[OtherJoints[1].GetJointType()];
            int convertedDotAngle = JointAnalyzer.FindAngle(vertexJoint, adjacentJoints);

            return(convertedDotAngle);
        }
예제 #11
0
        /// <summary>
        /// Future Enchancement. Creates a skeleton based on the current patients skeleton and the
        /// starting criteria for that skeleton.
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        public Skeleton CreateStartingSkeleton(SkeletonStamp skeletonStamp)
        {
            Skeleton skeleton = skeletonStamp.GetTrackedSkeleton();
            /* Determine the joint types to calculate */
            ISet <JointType> jointTypes = new SortedSet <JointType>();

            foreach (Criterion criterion in StartingCriteria)
            {
                foreach (Joint jointType in criterion.MatchSkeletonToCriterion())
                {
                    jointTypes.Add(jointType.JointType);
                }
            }
            /* find path to take from parent to child */
            foreach (JointType jointType in jointTypes)
            {
            }
            return(null);
        }
예제 #12
0
        /// <summary>
        /// Determines whether the rep has been completed by the patient
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        public bool isRepComplete(SkeletonStamp skeletonStamp)
        {
            bool matches = false;

            matches = _exercise.MatchesCriteria(skeletonStamp, _exercise.Checkpoints[_checkpoint].Criteria);
            if (matches)
            {
                // increment the checkpoint
                Checkpoint++;

                if (Checkpoint >= _exercise.Checkpoints.Length)
                {
                    // we have now completed a repetition reset our counter
                    Checkpoint = 0;
                    return(true);
                }
            }

            return(false);
        }
예제 #13
0
        /// <summary>
        /// Checks the alignment of the joints. returns a value for each joint measured
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        private double[] FindAlignment(SkeletonStamp skeletonStamp)
        {
            // initialize the values of the array to -2 since the value we're returning is between -1 and +1
            double[] alignmentValue = Enumerable.Repeat(-999.0, 20).ToArray();
            Joint[]  trackedJoints  = new Joint[Joints.Length];
            Joint    centerJoint;
            int      i = 0;

            // get the joints to be aligned
            foreach (XmlJointType type in Joints)
            {
                trackedJoints[i++] = skeletonStamp.GetTrackedSkeleton().Joints[type.GetJointType()];
            }
            double tempValue;

            switch (Alignment)
            {
            case Alignment.Point:
                centerJoint = skeletonStamp.GetTrackedSkeleton().Joints[CenterJoint.GetJointType()];
                tempValue   = 1 - JointAnalyzer.AreJointsAligned(centerJoint, trackedJoints);
                alignmentValue[(int)CenterJoint.GetJointType()] = tempValue;
                alignmentValue[(int)trackedJoints[0].JointType] = tempValue;
                alignmentValue[(int)trackedJoints[1].JointType] = tempValue;
                break;

            case Alignment.Horizontal:
                tempValue = 1 - JointAnalyzer.AlignedHorizontally(trackedJoints[0], trackedJoints[1]);
                alignmentValue[(int)trackedJoints[0].JointType] = tempValue;
                alignmentValue[(int)trackedJoints[1].JointType] = tempValue;
                break;

            case Alignment.Vertical:
                tempValue = 1 - JointAnalyzer.AlignedVertically(trackedJoints[0], trackedJoints[1]);
                alignmentValue[(int)trackedJoints[0].JointType] = tempValue;
                alignmentValue[(int)trackedJoints[1].JointType] = tempValue;
                break;
            }

            return(alignmentValue);
        }
예제 #14
0
        /// <summary>
        /// Dequeues from the queue if available and accepting
        /// </summary>
        /// <param name="skeleton">Skeletal array data from the SkeletonFrame</param>
        public void Add(Skeleton[] skeleton, long timeStamp)
        {
            // Is there any space left?
            if (free.Count == 0)
            {
                for (int i = 0; i < maxInstances; ++i)
                {
                    //   enqueue again so long as no one else is using this
                    if (!this.universe[i].InUse)
                    {
                        free.Enqueue(this.universe[i]);
                    }
                }
            }

            if (free.Count > 0)
            {
                SkeletonStamp s = free.Dequeue();
                s.TimeStamp    = timeStamp;
                s.SkeletonData = skeleton;
                s.InUse        = false;
                s.IsActive     = true;
            }
        }
예제 #15
0
        public void TestCreateStartingSkeleton()
        {
            #region Setup Skeleton
            Skeleton[] skeletonData = new Skeleton[1];
            Skeleton skeleton = new Skeleton();
            skeleton.TrackingState = SkeletonTrackingState.Tracked;
            /* this needs to be done because you can't set properties directly on the skelton's Joint object:
             * you must create a new joint,
             * set the properties,
             * then set the new joint on the skeleton */
            SkeletonPoint sp = new SkeletonPoint();
            sp.X = 1.0F;
            sp.Y = 1.0F;
            sp.Z = 1.0F;
            Joint shoulder = skeleton.Joints[JointType.ShoulderLeft];
            shoulder.Position = sp;
            skeleton.Joints[JointType.ShoulderLeft] = shoulder;
            Joint elbow = skeleton.Joints[JointType.ElbowLeft];
            elbow.Position = sp;
            skeleton.Joints[JointType.ElbowLeft] = elbow;
            Joint wrist = skeleton.Joints[JointType.WristLeft];
            wrist.Position = sp;
            skeleton.Joints[JointType.WristLeft] = wrist;
            skeletonData[0] = skeleton;

            System.Console.WriteLine("Shoulder Position X: " + shoulder.Position.X);
            System.Console.WriteLine("Skel Shoulder Position X: " + skeleton.Joints[JointType.ShoulderLeft].Position.X);
            SkeletonStamp skeletonStamp = new SkeletonStamp(skeletonData, 1);

            Skeleton startingSkeleton = Exercise.createStartingSkeleton(skeletonStamp);
            Skeleton[] startingSkeletonData = new Skeleton[1];
            SkeletonStamp startingSkeletonStamp = new SkeletonStamp(startingSkeletonData, 999);
            Assert.IsTrue(Exercise.matchesCriteria(startingSkeletonStamp, Exercise.StartingCriteria), "Created skeleton does not match starting criteria");

            #endregion
        }
        /// <summary>
        /// Checks the alignment of the joints. returns a value for each joint measured
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        private double[] FindAlignment(SkeletonStamp skeletonStamp)
        {
            // initialize the values of the array to -2 since the value we're returning is between -1 and +1
            double[] alignmentValue = Enumerable.Repeat(-999.0, 20).ToArray();
            Joint[] trackedJoints = new Joint[Joints.Length];
            Joint centerJoint;
            int i = 0;
            // get the joints to be aligned
            foreach (XmlJointType type in Joints)
            {
                trackedJoints[i++] = skeletonStamp.GetTrackedSkeleton().Joints[type.GetJointType()];
            }
            double tempValue;
            switch (Alignment)
            {
                case Alignment.Point:
                    centerJoint = skeletonStamp.GetTrackedSkeleton().Joints[CenterJoint.GetJointType()];
                    tempValue = 1 - JointAnalyzer.areJointsAligned(centerJoint, trackedJoints);
                    alignmentValue[(int)CenterJoint.GetJointType()] = tempValue;
                    alignmentValue[(int)trackedJoints[0].JointType] = tempValue;
                    alignmentValue[(int)trackedJoints[1].JointType] = tempValue;
                    break;
                case Alignment.Horizontal:
                    tempValue = 1 - JointAnalyzer.alignedHorizontally(trackedJoints[0], trackedJoints[1]);
                    alignmentValue[(int)trackedJoints[0].JointType] = tempValue;
                    alignmentValue[(int)trackedJoints[1].JointType] = tempValue;
                    break;
                case Alignment.Vertical:
                    tempValue = 1 - JointAnalyzer.alignedVertically(trackedJoints[0], trackedJoints[1]);
                    alignmentValue[(int)trackedJoints[0].JointType] = tempValue;
                    alignmentValue[(int)trackedJoints[1].JointType] = tempValue;
                    break;
            }

            Console.WriteLine("Align:" + Alignment + " Joint:" + trackedJoints[0].JointType.ToString() + " val:" + alignmentValue[(int)trackedJoints[0].JointType] + " Min:" + MinimumAcceptedRange + " Max:" + MaximumAcceptedRange);
            return alignmentValue;
        }
 /// <summary>
 /// Determines if the repetition has been started
 /// </summary>
 /// <param name="skeletonStamp"></param>
 /// <returns></returns>
 public bool isRepStarted(SkeletonStamp skeletonStamp)
 {
     bool matches = Exercise.matchesCriteria(skeletonStamp, Exercise.StartingCriteria);
     if (matches)
     {
         startTime = DateTime.Now;
         /// add 2 seconds (hopefully they have moved within that time)
         TimeSpan time = new TimeSpan(0, 0, 0, 2);
         endTime = startTime.Add(time);
     }
     return matches;
 }
 public double[] checkForm(SkeletonStamp skeletonStamp)
 {
     return Exercise.CheckForm(skeletonStamp);
 }
예제 #19
0
 /// <summary>
 /// Check the form of the patient while they perform the repetition
 /// </summary>
 /// <param name="skeletonStamp"></param>
 /// <returns></returns>
 public double[] checkForm(SkeletonStamp skeletonStamp)
 {
     return(_exercise.CheckForm(skeletonStamp));
 }
예제 #20
0
 /// <summary>
 /// Compares a skeleton against the angle criterion
 /// </summary>
 /// <param name="skeletonStamp"></param>
 /// <returns></returns>
 public override bool matchesCriterion(SkeletonStamp skeletonStamp)
 {
     Joint vertexJoint; Joint[] adjacentJoints;
     int convertedDotAngle = FindAngle(skeletonStamp, out vertexJoint, out adjacentJoints);
     return convertedDotAngle > MinimumAngle && convertedDotAngle < MaximumAngle;
 }
예제 #21
0
 public abstract double[] CheckForm(SkeletonStamp skeletonStamp);
예제 #22
0
 public override bool matchesCriterion(SkeletonStamp skeletonStamp)
 {
     throw new NotSupportedException();
 }
예제 #23
0
 public override List<Joint> MatchSkeletonToCriterion(SkeletonStamp skeletonStamp)
 {
     throw new NotImplementedException();
 }
예제 #24
0
 public override double[] CheckForm(SkeletonStamp skeletonStamp)
 {
     throw new NotImplementedException();
 }
 public override bool matchesCriterion(SkeletonStamp skeletonStamp)
 {
     double alignmentValue = 0.0;
     Joint[] trackedJoints = new Joint[Joints.Length];
     Joint centerJoint;
     int i = 0;
     // get the joints to be aligned
     foreach (XmlJointType type in Joints)
     {
         trackedJoints[i++] = skeletonStamp.GetTrackedSkeleton().Joints[type.GetJointType()];
     }
     switch (Alignment)
     {
         case Alignment.Point:
             centerJoint = skeletonStamp.GetTrackedSkeleton().Joints[CenterJoint.GetJointType()];
             alignmentValue = JointAnalyzer.areJointsAligned(centerJoint, trackedJoints);
             break;
         case Alignment.Horizontal:
             alignmentValue = JointAnalyzer.alignedHorizontally(trackedJoints[0], trackedJoints[1]);
             break;
         case Alignment.Vertical:
             alignmentValue = JointAnalyzer.alignedVertically(trackedJoints[0], trackedJoints[1]);
             break;
     }
     Console.WriteLine("Align:" + Alignment + " Joint:" + trackedJoints[0].JointType.ToString() + " val:" + alignmentValue + " Min:" + MinimumAcceptedRange + " Max:" + MaximumAcceptedRange);
     return alignmentValue > MaximumAcceptedRange;
 }
 public override double[] CheckForm(SkeletonStamp skeletonStamp)
 {
     return FindAlignment(skeletonStamp);
 }
예제 #27
0
        public void TestAlignmentCheckForm()
        {
            #region Setup Skeleton
            Skeleton[] skeletonData = new Skeleton[1];
            Skeleton skeleton = new Skeleton();
            skeleton.TrackingState = SkeletonTrackingState.Tracked;
            /* this needs to be done because you can't set properties directly on the skelton's Joint object:
             * you must create a new joint,
             * set the properties,
             * then set the new joint on the skeleton */
            SkeletonPoint sp = new SkeletonPoint();
            sp.X = 1.0F;
            sp.Y = 1.0F;
            sp.Z = 1.0F;
            Joint hip = skeleton.Joints[JointType.HipRight];
            hip.Position = sp;
            skeleton.Joints[JointType.HipRight] = hip;
            Joint knee = skeleton.Joints[JointType.KneeRight];
            knee.Position = sp;
            skeleton.Joints[JointType.KneeRight] = knee;
            Joint ankle = skeleton.Joints[JointType.AnkleRight];
            ankle.Position = sp;
            skeleton.Joints[JointType.AnkleRight] = ankle;
            skeletonData[0] = skeleton;

            System.Console.WriteLine("Hip Position X: " + hip.Position.X);
            System.Console.WriteLine("Skel Hip Position X: " + skeleton.Joints[JointType.HipRight].Position.X);
            SkeletonStamp skeletonStamp = new SkeletonStamp(skeletonData,1);
            #endregion

            Exercise alignmentExercise = new Exercise();

            #region Check Vertical Alignment
            alignmentExercise.TrackingCriteria = new Criterion[] { VerticalAlignmentCriterion };
            double[] percentBad = alignmentExercise.CheckForm(skeletonStamp);

            /* check the hip and ankle percent bad */
            Assert.AreEqual(0, percentBad[(int)JointType.HipRight]);
            Assert.IsNaN(percentBad[(int)JointType.KneeRight]); /* this is not part of the criteria and should not be set */;
            Assert.AreEqual(0, percentBad[(int)JointType.AnkleRight]);
            #endregion

            #region Check Horizontal Alignment
            alignmentExercise.TrackingCriteria = new Criterion[] { HorizontalAlignmentCriterion };
            percentBad = alignmentExercise.CheckForm(skeletonStamp);

            /* check the hip and ankle percent bad */
            Assert.AreEqual(0, percentBad[(int)JointType.HipRight]);
            Assert.IsNaN(percentBad[(int)JointType.KneeRight]); /* this is not part of the criteria and should not be set */;
            Assert.AreEqual(0, percentBad[(int)JointType.AnkleRight]);
            #endregion

            #region Check Three Joint Alignment
            alignmentExercise.TrackingCriteria = new Criterion[] { ThreeJointAlignmentCriterion };
            percentBad = alignmentExercise.CheckForm(skeletonStamp);

            /* check the hip and ankle percent bad */
            Assert.AreEqual(0, percentBad[(int)JointType.HipRight]);
            Assert.AreEqual(0,percentBad[(int)JointType.KneeRight]); /* this is NOW part of the criteria and should be set */;
            Assert.AreEqual(0, percentBad[(int)JointType.AnkleRight]);
            #endregion
        }
예제 #28
0
 public abstract List<Joint> MatchSkeletonToCriterion(SkeletonStamp skeletonStamp);
예제 #29
0
 public abstract bool MatchesCriterion(SkeletonStamp skeletonStamp);
예제 #30
0
 public abstract bool matchesCriterion(SkeletonStamp skeletonStamp);
예제 #31
0
 public abstract double[] CheckForm(SkeletonStamp skeletonStamp);
예제 #32
0
 public override double[] CheckForm(SkeletonStamp skeletonStamp)
 {
     return(FindAlignment(skeletonStamp));
 }
예제 #33
0
        /// <summary>
        /// This method draws the skeleton frame data.
        /// </summary>
        /// <param name="gameTime">The elapsed game time.</param>
        public override void Draw(GameTime gameTime)
        {
            skeletonDrawn = true;
            // If the joint texture isn't loaded, load it now
            if (null == this.jointTexture)
            {
                this.LoadContent();
            }
            SkeletonStamp skeletonData = SkeletonPool.GetOldestProcessedSkeleton();

            // If we don't have data, lets leave
            if (null == skeletonData || null == this.mapMethod)
            {
                return;
            }
            Skeleton skeleton = skeletonData.GetTrackedSkeleton();

            if (null == skeleton)
            {
                return;
            }
            if (false == this.initialized)
            {
                this.Initialize();
            }

            this.SharedSpriteBatch.Begin();

            // Draw Bones
            this.DrawBone(skeleton.Joints, JointType.Head, JointType.ShoulderCenter);
            this.DrawBone(skeleton.Joints, JointType.ShoulderCenter, JointType.ShoulderLeft);
            this.DrawBone(skeleton.Joints, JointType.ShoulderCenter, JointType.ShoulderRight);
            this.DrawBone(skeleton.Joints, JointType.ShoulderCenter, JointType.Spine);
            this.DrawBone(skeleton.Joints, JointType.Spine, JointType.HipCenter);
            this.DrawBone(skeleton.Joints, JointType.HipCenter, JointType.HipLeft);
            this.DrawBone(skeleton.Joints, JointType.HipCenter, JointType.HipRight);

            this.DrawBone(skeleton.Joints, JointType.ShoulderLeft, JointType.ElbowLeft);
            this.DrawBone(skeleton.Joints, JointType.ElbowLeft, JointType.WristLeft);
            this.DrawBone(skeleton.Joints, JointType.WristLeft, JointType.HandLeft);

            this.DrawBone(skeleton.Joints, JointType.ShoulderRight, JointType.ElbowRight);
            this.DrawBone(skeleton.Joints, JointType.ElbowRight, JointType.WristRight);
            this.DrawBone(skeleton.Joints, JointType.WristRight, JointType.HandRight);

            this.DrawBone(skeleton.Joints, JointType.HipLeft, JointType.KneeLeft);
            this.DrawBone(skeleton.Joints, JointType.KneeLeft, JointType.AnkleLeft);
            this.DrawBone(skeleton.Joints, JointType.AnkleLeft, JointType.FootLeft);

            this.DrawBone(skeleton.Joints, JointType.HipRight, JointType.KneeRight);
            this.DrawBone(skeleton.Joints, JointType.KneeRight, JointType.AnkleRight);
            this.DrawBone(skeleton.Joints, JointType.AnkleRight, JointType.FootRight);

            // Now draw the joints
            Game.GraphicsDevice.BlendState        = BlendState.Opaque;
            Game.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            Game.GraphicsDevice.SamplerStates[0]  = SamplerState.LinearWrap;
            foreach (Joint j in skeleton.Joints)
            {
                /* its good unless proven bad.*/
                Color jointColor = Color.Green;

                /*  How do we know its bad?
                 * Check the deviation field */
                double deviation = skeletonData.PercentBad[(int)j.JointType];
                if (!Double.IsNaN(deviation))
                {
                    if (deviation > .01 || deviation < -.01)
                    {
                        jointColor = Color.Red;
                    }

                    this.SharedSpriteBatch.Draw(
                        this.jointTexture,
                        this.mapMethod(j.Position),
                        null,
                        jointColor,
                        0.0f,
                        this.jointOrigin,
                        1.0f,
                        SpriteEffects.None,
                        0.0f);
                }
            }

            this.SharedSpriteBatch.End();
            // we are now done with this skeleton data remove all previous from the pool
            SkeletonPool.Remove(skeletonData.TimeStamp);
            base.Draw(gameTime);
        }
예제 #34
0
        public void TestAlignmentMatchesCriteria()
        {
            #region Setup Skeleton
            Skeleton[] skeletonData = new Skeleton[1];
            Skeleton skeleton = new Skeleton();
            skeleton.TrackingState = SkeletonTrackingState.Tracked;
            /* this needs to be done because you can't set properties directly on the skelton's Joint object:
             * you must create a new joint,
             * set the properties,
             * then set the new joint on the skeleton */
            SkeletonPoint sp = new SkeletonPoint();
            sp.X = 1.0F;
            sp.Y = 1.0F;
            sp.Z = 1.0F;
            Joint hip = skeleton.Joints[JointType.HipRight];
            hip.Position = sp;
            skeleton.Joints[JointType.HipRight] = hip;
            Joint knee = skeleton.Joints[JointType.KneeRight];
            knee.Position = sp;
            skeleton.Joints[JointType.KneeRight] = knee;
            Joint ankle = skeleton.Joints[JointType.AnkleRight];
            ankle.Position = sp;
            skeleton.Joints[JointType.AnkleRight] = ankle;
            skeletonData[0] = skeleton;

            System.Console.WriteLine("Hip Position X: " + hip.Position.X);
            System.Console.WriteLine("Skel Hip Position X: " + skeleton.Joints[JointType.HipRight].Position.X);
            SkeletonStamp skeletonStamp = new SkeletonStamp(skeletonData, 1);
            #endregion

            Exercise alignmentExercise = new Exercise();
            #region Matches Alignment
            alignmentExercise.StartingCriteria = new Criterion[] { VerticalAlignmentCriterion };
            Assert.IsTrue(alignmentExercise.matchesCriteria(skeletonStamp,alignmentExercise.StartingCriteria));
            #endregion

            #region Does Not Match Alignment
            SkeletonPoint misalignedPoint = new SkeletonPoint();
            misalignedPoint.X = 100.0F;
            misalignedPoint.Y = 1.0F;
            misalignedPoint.Z = 1.0F;
            hip = skeleton.Joints[JointType.HipRight];
            hip.Position = misalignedPoint;
            skeleton.Joints[JointType.HipRight] = hip;

            System.Console.WriteLine("Hip Position X: " + hip.Position.X);
            System.Console.WriteLine("Skel Hip Position X: " + skeleton.Joints[JointType.HipRight].Position.X);
            System.Console.WriteLine("Skel Knee Position X: " + skeleton.Joints[JointType.KneeRight].Position.X);
            Assert.IsFalse(alignmentExercise.matchesCriteria(skeletonStamp,alignmentExercise.StartingCriteria));
            #endregion
        }
예제 #35
0
        /// <summary>
        /// Determines if the patient is in the starting position
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        public bool isRepStarted(SkeletonStamp skeletonStamp)
        {
            bool matches = _exercise.MatchesCriteria(skeletonStamp, _exercise.StartingCriteria);

            return(matches);
        }
예제 #36
0
        public void TestAngleCheckForm()
        {
            #region Setup Skeleton
            Skeleton[] skeletonData = new Skeleton[1];
            Skeleton skeleton = new Skeleton();
            skeleton.TrackingState = SkeletonTrackingState.Tracked;
            /* this needs to be done because you can't set properties directly on the skelton's Joint object:
             * you must create a new joint,
             * set the properties,
             * then set the new joint on the skeleton */
            SkeletonPoint hipPoint = new SkeletonPoint();
            hipPoint.X = 1.0F;
            hipPoint.Y = 1.0F;
            hipPoint.Z = 1.0F;
            Joint hip = skeleton.Joints[JointType.HipRight];
            hip.Position = hipPoint;
            skeleton.Joints[JointType.HipRight] = hip;

            SkeletonPoint kneePoint = new SkeletonPoint();
            kneePoint.X = 2.0F;
            kneePoint.Y = 1.0F;
            kneePoint.Z = 1.0F;
            Joint knee = skeleton.Joints[JointType.KneeRight];
            knee.Position = kneePoint;

            SkeletonPoint anklePoint = new SkeletonPoint();
            anklePoint.X = 2.0F;
            anklePoint.Y = 0.0F;
            anklePoint.Z = 1.0F;
            skeleton.Joints[JointType.KneeRight] = knee;
            Joint ankle = skeleton.Joints[JointType.AnkleRight];
            ankle.Position = anklePoint;
            skeleton.Joints[JointType.AnkleRight] = ankle;
            skeletonData[0] = skeleton;
            SkeletonStamp skeletonStamp = new SkeletonStamp(skeletonData, 1);
            #endregion
            Exercise angleExercise = new Exercise();

            #region Angle In Range
            angleExercise.TrackingCriteria = new Criterion[1] { AngleCriterion };
            double[] jointImperfection = angleExercise.CheckForm(skeletonStamp);
            // should be exactly 90 degrees
            Assert.AreEqual(0, jointImperfection[(int)JointType.KneeRight]);
            Assert.AreEqual(0, jointImperfection[(int)JointType.HipRight]);
            Assert.AreEqual(0, jointImperfection[(int)JointType.AnkleRight]);
            #endregion

            #region Angle Out Of Range
            // change the skeleton to be out of range
            SkeletonPoint misalignedPoint = new SkeletonPoint();
            misalignedPoint.X = 2.0F;
            misalignedPoint.Y = 0.0F;
            misalignedPoint.Z = 1.0F;
            hip = skeleton.Joints[JointType.HipRight];
            hip.Position = misalignedPoint;
            skeleton.Joints[JointType.HipRight] = hip;
            jointImperfection = angleExercise.CheckForm(skeletonStamp);
            Assert.AreNotEqual(0, jointImperfection[(int)JointType.KneeRight]);
            Assert.AreNotEqual(0, jointImperfection[(int)JointType.HipRight]);
            Assert.AreNotEqual(0, jointImperfection[(int)JointType.AnkleRight]);
            #endregion
        }
        /// <summary>
        /// Determines whether the rep has been completed. 
        /// </summary>
        /// <param name="skeletonStamp"></param>
        /// <returns></returns>
        public bool isRepComplete(SkeletonStamp skeletonStamp)
        {
            bool matches = false;

            matches = Exercise.matchesCriteria(skeletonStamp, Exercise.Checkpoints[_checkpoint].Criteria);
            if (matches)
            {
                // increment the checkpoint
                Checkpoint++;

                if (Checkpoint >= Exercise.Checkpoints.Length)
                {
                    // we have now completed a repetition reset our counter
                    Checkpoint = 0;
                    return true;
                }
            }

            return false;
        }
예제 #38
0
        public void TestAngleMatchesCriteria()
        {
            #region Setup Skeleton
            Skeleton[] skeletonData = new Skeleton[1];
            Skeleton skeleton = new Skeleton();
            skeleton.TrackingState = SkeletonTrackingState.Tracked;
            /* this needs to be done because you can't set properties directly on the skelton's Joint object:
             * you must create a new joint,
             * set the properties,
             * then set the new joint on the skeleton */
            SkeletonPoint hipPoint = new SkeletonPoint();
            hipPoint.X = 1.0F;
            hipPoint.Y = 1.0F;
            hipPoint.Z = 1.0F;
            Joint hip = skeleton.Joints[JointType.HipRight];
            hip.Position = hipPoint;
            skeleton.Joints[JointType.HipRight] = hip;

            SkeletonPoint kneePoint = new SkeletonPoint();
            kneePoint.X = 2.0F;
            kneePoint.Y = 1.0F;
            kneePoint.Z = 1.0F;
            Joint knee = skeleton.Joints[JointType.KneeRight];
            knee.Position = kneePoint;

            // slightly off 90 but should still match
            SkeletonPoint anklePoint = new SkeletonPoint();
            anklePoint.X = 2.0F;
            anklePoint.Y = 0.01F;
            anklePoint.Z = 1.0F;
            skeleton.Joints[JointType.KneeRight] = knee;
            Joint ankle = skeleton.Joints[JointType.AnkleRight];
            ankle.Position = anklePoint;
            skeleton.Joints[JointType.AnkleRight] = ankle;
            skeletonData[0] = skeleton;
            SkeletonStamp skeletonStamp = new SkeletonStamp(skeletonData, 1);
            #endregion
            Exercise angleExercise = new Exercise();

            #region Angle Matches
            angleExercise.StartingCriteria = new Criterion[1] { AngleCriterion };
            Assert.IsTrue(angleExercise.matchesCriteria(skeletonStamp,angleExercise.StartingCriteria));
            #endregion

            #region Angle Does Not Match
            SkeletonPoint misalignedPoint = new SkeletonPoint();
            misalignedPoint.X = 2.0F;
            misalignedPoint.Y = 0.0F;
            misalignedPoint.Z = 1.0F;
            hip = skeleton.Joints[JointType.HipRight];
            hip.Position = misalignedPoint;
            skeleton.Joints[JointType.HipRight] = hip;
            Assert.IsFalse(angleExercise.matchesCriteria(skeletonStamp, angleExercise.StartingCriteria));
            #endregion
        }
예제 #39
0
        public void Initialize()
        {
            this.universe = new SkeletonStamp[maxInstances];
            this.free = new Queue<SkeletonStamp>(maxInstances);

            for (int i = 0; i < maxInstances; ++i)
            {
                universe[i] = new SkeletonStamp(new Skeleton[0], long.MaxValue);
                free.Enqueue(universe[i]);
            }
        }
 public override List<Joint> MatchSkeletonToCriterion(SkeletonStamp skeletonStamp)
 {
     Joint[] trackedJoints = new Joint[Joints.Length];
     Joint centerJoint;
     int i = 0;
     // get the joints to be aligned
     foreach (XmlJointType type in Joints)
     {
         trackedJoints[i++] = skeletonStamp.GetTrackedSkeleton().Joints[type.GetJointType()];
     }
     double tempValue;
     switch (Alignment)
     {
         case Alignment.Point:
             centerJoint = skeletonStamp.GetTrackedSkeleton().Joints[CenterJoint.GetJointType()];
             tempValue = 1 - JointAnalyzer.areJointsAligned(centerJoint, trackedJoints);
             break;
         case Alignment.Horizontal:
             trackedJoints[(int)trackedJoints[1].JointType] = JointAnalyzer.alignJointHorizontally(trackedJoints[0], trackedJoints[1]);
             break;
         case Alignment.Vertical:
             tempValue = 1 - JointAnalyzer.alignedVertically(trackedJoints[0], trackedJoints[1]);
             break;
     }
     return new List<Joint>(trackedJoints);
 }
예제 #41
0
        public override List<Joint> MatchSkeletonToCriterion(SkeletonStamp skeletonStamp)
        {
            List<JointType> jointTypes = new List<JointType>();

            jointTypes.Add(Vertex.GetJointType());
            foreach (XmlJointType xmlJointType in OtherJoints)
            {
                jointTypes.Add(xmlJointType.GetJointType());
            }
            return null;
        }
예제 #42
0
 public Skeleton createStartingSkeleton(SkeletonStamp skeletonStamp)
 {
     Skeleton skeleton = skeletonStamp.GetTrackedSkeleton();
     /* Determine the joint types to calculate */
     ISet<JointType> jointTypes = new SortedSet<JointType>();
     foreach (Criterion criterion in StartingCriteria)
     {
         foreach (Joint jointType in criterion.MatchSkeletonToCriterion(skeletonStamp))
         {
             jointTypes.Add(jointType.JointType);
         }
     }
     /* find path to take from parent to child */
     foreach (JointType jointType in jointTypes)
     {
     }
     return null;
 }
예제 #43
0
        /// <summary>
        /// Check form will validate all the tracked joints based on the criteria provided by trackedJoints
        /// Joints which are not compared are considered perfectly accurate (0) 
        /// </summary>
        /// <returns></returns>
        public double[] CheckForm(SkeletonStamp skeletonStamp)
        {
            double[] jointAccuracy = new double[20];
            /* Keeps track of how many times the joint has been updated */
            double[] timesJointUpdated = new double[20];
            /** loop through each Criterion and determine if it is bad or not */
            /** aggregate all the results */
            foreach (Criterion criterion in TrackingCriteria)
            {
                double[] result = criterion.CheckForm(skeletonStamp);

                for (int i = 0; i < jointAccuracy.Length; i++)
                {
                    if (result[i] != -999)
                    {
                        jointAccuracy[i] += result[i];
                        timesJointUpdated[i]++;
                    }

                }
            }
            /* Take the average result based on the amount of times a joint was updated */
            for (int i = 0; i < jointAccuracy.Length; i++)
            {
                jointAccuracy[i] = jointAccuracy[i] / timesJointUpdated[i];
            }
            /** Joints which are not compared are considered perfectly accurate (0) */
            return jointAccuracy;
        }
예제 #44
0
        private int FindAngle(SkeletonStamp skeletonStamp, out Joint vertexJoint, out Joint[] adjacentJoints)
        {
            // Test bone orientations
            Skeleton skeleton = skeletonStamp.GetTrackedSkeleton();
            BoneOrientation bo = skeleton.BoneOrientations[Vertex.GetJointType()];
            Debug.WriteLine("Bone Orientation: abs: " + bo.AbsoluteRotation.ToString() + " end: " + bo.EndJoint.ToString() + " start: " + bo.StartJoint.ToString() + " hier: " + bo.HierarchicalRotation.ToString());

            // get the vertex and other joints off the skeleton stamp
            vertexJoint = skeletonStamp.GetTrackedSkeleton().Joints[Vertex.GetJointType()];

            adjacentJoints = new Joint[2];
            adjacentJoints[0] = skeletonStamp.GetTrackedSkeleton().Joints[OtherJoints[0].GetJointType()];
            adjacentJoints[1] = skeletonStamp.GetTrackedSkeleton().Joints[OtherJoints[1].GetJointType()];
            int convertedDotAngle = JointAnalyzer.findAngle(vertexJoint, adjacentJoints);
            Debug.WriteLine("Vertex: " + vertexJoint.JointType.ToString() + " Angle: " + convertedDotAngle + " Min: " + MinimumAngle + " Max: " + MaximumAngle);
            return convertedDotAngle;
        }
예제 #45
0
 /// <summary>
 /// Determines whether the supplied skeleton matches the criteria
 /// </summary>
 /// <param name="skeletonStamp"></param>
 /// <returns></returns>
 internal bool matchesCriteria(SkeletonStamp skeletonStamp, Criterion[] criterion)
 {
     bool matches = true;
     // go through each joint's criteria and verify it is true
     foreach (Criterion c in criterion)
     {
         if (!c.matchesCriterion(skeletonStamp))
         {
             // no need to keep checking.
             return false;
         }
     }
     return matches;
 }
예제 #46
0
        public override double[] CheckForm(SkeletonStamp skeletonStamp)
        {
            Joint vertexJoint; Joint[] adjacentJoints;
            int convertedDotAngle = FindAngle(skeletonStamp, out vertexJoint, out adjacentJoints);

            double normalizedAccuracy = 0;
            switch (Operation)
            {
                case Operation.GreaterThan:
                    if (convertedDotAngle < MinimumAngle)
                    {
                        normalizedAccuracy = (Angle - convertedDotAngle) / 180;
                    }
                    break;
                case Operation.LessThan:
                    if (convertedDotAngle > MaximumAngle)
                    {
                        normalizedAccuracy = (Angle - convertedDotAngle) / 180;
                    }
                    break;
                case Operation.Equals:
                    normalizedAccuracy = (Angle - convertedDotAngle) / 180;
                    break;
            }
            normalizedAccuracy = Math.Abs(normalizedAccuracy);
            double[] results = new double[20];
            results[(int)vertexJoint.JointType] = normalizedAccuracy;
            results[(int)adjacentJoints[0].JointType] = normalizedAccuracy;
            results[(int)adjacentJoints[1].JointType] = normalizedAccuracy;
            return results;
        }