예제 #1
0
 public static DepthPoint operator *(DepthPoint firstPoint, double constant)
 {
     DepthPoint multPoint = new DepthPoint((int)(firstPoint.x * constant),
                                           (int)(firstPoint.y * constant),
                                           (long)(firstPoint.depth * constant));
     return multPoint;
 }
예제 #2
0
        /// <summary>
        /// 
        /// </summary>
        public ReferenceFrame()
        {
            if (armLengths == null)
            {
                armLengths = new double[MINDATAPOINTSREQ];
            }
            if (torsoPositions == null)
            {
                torsoPositions = new DepthPoint[MINDATAPOINTSREQ];
                for (int i = 0; i < MINDATAPOINTSREQ; i++)
                {
                    torsoPositions[i] = new DepthPoint();

                }
            }

            this.torsoPosition = new DepthPoint();
            leftWristPoints = new Queue<DepthPoint>();
            rightWristPoints = new Queue<DepthPoint>();
            leftShoulderPoints = new Queue<DepthPoint>();
            rightShoulderPoints = new Queue<DepthPoint>();
            totalArmPoints = 0;
            totalTorsoPoints = 0;

            shoulderCenterPoints = new Queue<DepthPoint>();
            spinePoints = new Queue<DepthPoint>();
            hipCenterPoints = new Queue<DepthPoint>();

            shoulderCenterPointsSupplemental = new Queue<DepthPoint>();
            spinePointsSupplemental = new Queue<DepthPoint>();
            hipCenterPointsSupplemental = new Queue<DepthPoint>();
        }
예제 #3
0
        private const double TORSO_LEARNING_ALPHA = 0.1; // torso learning alpha for after we have MAX_POINTS_IN_READING


        /// <summary>
        ///
        /// </summary>
        public ReferenceFrame()
        {
            if (armLengths == null)
            {
                armLengths = new double[MINDATAPOINTSREQ];
            }
            if (torsoPositions == null)
            {
                torsoPositions = new DepthPoint[MINDATAPOINTSREQ];
                for (int i = 0; i < MINDATAPOINTSREQ; i++)
                {
                    torsoPositions[i] = new DepthPoint();
                }
            }

            this.torsoPosition  = new DepthPoint();
            leftWristPoints     = new Queue <DepthPoint>();
            rightWristPoints    = new Queue <DepthPoint>();
            leftShoulderPoints  = new Queue <DepthPoint>();
            rightShoulderPoints = new Queue <DepthPoint>();
            totalArmPoints      = 0;
            totalTorsoPoints    = 0;

            shoulderCenterPoints = new Queue <DepthPoint>();
            spinePoints          = new Queue <DepthPoint>();
            hipCenterPoints      = new Queue <DepthPoint>();

            shoulderCenterPointsSupplemental = new Queue <DepthPoint>();
            spinePointsSupplemental          = new Queue <DepthPoint>();
            hipCenterPointsSupplemental      = new Queue <DepthPoint>();
        }
예제 #4
0
        public static DepthPoint operator *(DepthPoint firstPoint, double constant)
        {
            DepthPoint multPoint = new DepthPoint((int)(firstPoint.x * constant),
                                                  (int)(firstPoint.y * constant),
                                                  (long)(firstPoint.depth * constant));

            return(multPoint);
        }
예제 #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="leftWristJoint"></param>
        /// <param name="leftShoulderJoint"></param>
        /// <param name="rightWristJoint"></param>
        /// <param name="rightShoulderJoint"></param>
        public void computeArmLengthPixels(DepthPoint leftWristPoint, DepthPoint leftShoulderPoint, DepthPoint rightWristPoint, DepthPoint rightShoulderPoint)
        {
            totalArmPoints++;
            if (totalArmPoints > MIN_POINTS_BEFORE_READING && leftWristPoints.Count < MAX_POINTS_IN_READING)
            {
                leftWristPoints.Enqueue(leftWristPoint);
                leftShoulderPoints.Enqueue(leftShoulderPoint);
                rightWristPoints.Enqueue(rightWristPoint);
                rightShoulderPoints.Enqueue(rightShoulderPoint);
            }


            int leftArmX = leftWristPoint.x - leftShoulderPoint.x;
            int leftArmY = leftWristPoint.y - leftShoulderPoint.y;
            //int leftArmZ = leftWristPoint.Position.Z - leftShoulderPoint.Position.Z;
            int rightArmX = rightWristPoint.x - rightShoulderPoint.x;
            int rightArmY = rightWristPoint.y - rightShoulderPoint.y;
            //int rightArmZ = rightWristPoint.Position.Z - rightShoulderPoint.Position.Z;
            double leftArm  = Math.Sqrt(leftArmX * leftArmX + leftArmY * leftArmY /*+ leftArmZ * leftArmZ*/);
            double rightArm = Math.Sqrt(rightArmX * rightArmX + rightArmY * rightArmY /*+ rightArmZ * rightArmZ*/);

            this.armLengthPixels = (int)((leftArm + rightArm) / 2.0);

            /*
             * The length of both arms changes depending on the location of the person due to noise in data
             * and also inaccuracy of depth cammera at too far and too close postions.
             * so we collect at least 50 data points of the four joint we need and calculate the avregae
             *
             */
            /*
             * if (armCounter < MINDATAPOINTSREQ)
             * {
             *  armLengths[armCounter] = (leftArm + rightArm) / 2;
             *  armCounter++;
             * }
             * else
             * {
             *  for (int i = 0; i < armCounter; i++)
             *  {
             *      this.armLength += armLengths[i];
             *  }
             *  //this.armLength /= (armCounter);
             *  this.armLength = (leftArm + rightArm) / 2;
             * }*/
        }
예제 #6
0
        public DepthPoint getNearestPoint(DepthPoint other)
        {
            DepthPoint nearestPoint = null;

            foreach (DepthPoint pt in points)
            {
                if (nearestPoint == null)
                {
                    nearestPoint = pt;
                }
                else
                {
                    if (distance(pt, other) < distance(nearestPoint, other))
                    {
                        nearestPoint = pt;
                    }
                }
            }
            return(nearestPoint);
        }
예제 #7
0
 public static double EuclideanDistance2d(DepthPoint p1, DepthPoint p2)
 {
     return(Math.Sqrt((p1.x - p2.x) * (p1.x - p2.x) +
                      (p1.y - p2.y) * (p1.y - p2.y)));
 }
예제 #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="shoulderCenter"></param>
        /// <param name="spine"></param>
        /// <param name="hipCenter"></param>
        internal void computerTorsoDepth(DepthPoint shoulderCenter, DepthPoint spine, DepthPoint hipCenter)
        {
            totalTorsoPoints++;

            /*
             * if (shoulderCenterPoints.Count == MAX_POINTS_IN_READING)
             * {
             *  shoulderCenterPointsSupplemental.Enqueue(shoulderCenter);
             *  hipCenterPointsSupplemental.Enqueue(hipCenter);
             *  spinePointsSupplemental.Enqueue(spine);
             * }
             */

            while (shoulderCenterPoints.Count > MAX_POINTS_IN_READING)
            {
                shoulderCenterPoints.Dequeue();
                hipCenterPoints.Dequeue();
                spinePoints.Dequeue();
            }

            while (shoulderCenterPointsSupplemental.Count > MAX_POINTS_IN_READING)
            {
                shoulderCenterPointsSupplemental.Dequeue();
                hipCenterPointsSupplemental.Dequeue();
                spinePointsSupplemental.Dequeue();
            }


            if (totalTorsoPoints > MIN_POINTS_BEFORE_READING && shoulderCenterPoints.Count < MAX_POINTS_IN_READING)
            {
                shoulderCenterPoints.Enqueue(shoulderCenter);
                hipCenterPoints.Enqueue(hipCenter);
                spinePoints.Enqueue(spine);
            }
            else
            {
                shoulderCenterPointsSupplemental.Enqueue(shoulderCenter);
                hipCenterPointsSupplemental.Enqueue(hipCenter);
                spinePointsSupplemental.Enqueue(spine);
            }

            // Alpha average between the supplemental points and our stored average torso pos

            if (shoulderCenterPointsSupplemental.Count > 30 && _avgTorsoPosition != null)
            {
                List <double> shoulderCenterX = new List <double>();
                List <double> shoulderCenterY = new List <double>();
                List <double> shoulderCenterZ = new List <double>();

                List <double> hipCenterX = new List <double>();
                List <double> hipCenterY = new List <double>();
                List <double> hipCenterZ = new List <double>();

                List <double> spineX = new List <double>();
                List <double> spineY = new List <double>();
                List <double> spineZ = new List <double>();

                for (int i = 0; i < shoulderCenterPoints.Count; i++)
                {
                    shoulderCenterX.Add(shoulderCenterPoints.ElementAt(i).x);
                    shoulderCenterY.Add(shoulderCenterPoints.ElementAt(i).y);
                    shoulderCenterZ.Add(shoulderCenterPoints.ElementAt(i).depth);

                    hipCenterX.Add(hipCenterPoints.ElementAt(i).x);
                    hipCenterY.Add(hipCenterPoints.ElementAt(i).y);
                    hipCenterZ.Add(hipCenterPoints.ElementAt(i).depth);

                    spineX.Add(spinePoints.ElementAt(i).x);
                    spineY.Add(spinePoints.ElementAt(i).y);
                    spineZ.Add(spinePoints.ElementAt(i).depth);
                }
                shoulderCenterX.Sort();
                shoulderCenterY.Sort();
                shoulderCenterZ.Sort();

                hipCenterX.Sort();
                hipCenterY.Sort();
                hipCenterZ.Sort();

                spineX.Sort();
                spineY.Sort();
                spineZ.Sort();

                int numToRemove = shoulderCenterPoints.Count / 4;
                for (int i = 0; i < numToRemove; i++)
                {
                    shoulderCenterX.RemoveAt(0);
                    shoulderCenterY.RemoveAt(0);
                    shoulderCenterZ.RemoveAt(0);

                    hipCenterX.RemoveAt(0);
                    hipCenterY.RemoveAt(0);
                    hipCenterZ.RemoveAt(0);

                    spineX.RemoveAt(0);
                    spineY.RemoveAt(0);
                    spineZ.RemoveAt(0);


                    shoulderCenterX.RemoveAt(shoulderCenterX.Count - 1);
                    shoulderCenterY.RemoveAt(shoulderCenterY.Count - 1);
                    shoulderCenterZ.RemoveAt(shoulderCenterZ.Count - 1);

                    hipCenterX.RemoveAt(hipCenterX.Count - 1);
                    hipCenterY.RemoveAt(hipCenterZ.Count - 1);
                    hipCenterZ.RemoveAt(hipCenterZ.Count - 1);

                    spineX.RemoveAt(spineX.Count - 1);
                    spineY.RemoveAt(spineY.Count - 1);
                    spineZ.RemoveAt(spineZ.Count - 1);
                }

                double shoulderCenterSumX = shoulderCenterX.Sum();
                double shoulderCenterSumY = shoulderCenterY.Sum();
                double shoulderCenterSumZ = shoulderCenterZ.Sum();

                double hipCenterSumX = hipCenterX.Sum();
                double hipCenterSumY = hipCenterY.Sum();
                double hipCenterSumZ = hipCenterZ.Sum();

                double spineSumX = spineX.Sum();
                double spineSumY = spineX.Sum();
                double spineSumZ = spineX.Sum();

                double avgShoulderX = shoulderCenterSumX / (double)shoulderCenterX.Count;
                double avgShoulderY = shoulderCenterSumY / (double)shoulderCenterX.Count;
                double avgShoulderZ = shoulderCenterSumZ / (double)shoulderCenterX.Count;

                double avgSpineX = shoulderCenterSumX / (double)shoulderCenterX.Count;
                double avgSpineY = shoulderCenterSumY / (double)shoulderCenterX.Count;
                double avgSpineZ = shoulderCenterSumZ / (double)shoulderCenterX.Count;

                double avgHipX = shoulderCenterSumX / (double)shoulderCenterX.Count;
                double avgHipY = shoulderCenterSumY / (double)shoulderCenterX.Count;
                double avgHipZ = shoulderCenterSumZ / (double)shoulderCenterX.Count;

                double avgTorsoX = (avgShoulderX + avgSpineX + avgHipX) / 3.0;
                double avgTorsoY = (avgShoulderY + avgSpineY + avgHipY) / 3.0;
                double avgTorsoZ = (avgShoulderZ + avgSpineZ + avgHipZ) / 3.0;

                _avgTorsoPosition = new DepthPoint((int)(_avgTorsoPosition.x * (1 - TORSO_LEARNING_ALPHA) + avgTorsoX * TORSO_LEARNING_ALPHA),
                                                   (int)(_avgTorsoPosition.y * (1 - TORSO_LEARNING_ALPHA) + avgTorsoY * TORSO_LEARNING_ALPHA),
                                                   (long)(_avgTorsoPosition.depth * (1 - TORSO_LEARNING_ALPHA) + avgTorsoZ * TORSO_LEARNING_ALPHA));
            }


            if (shoulderCenterPointsSupplemental.Count == MAX_POINTS_IN_READING)
            {
                // Determine if we should switch to the supplemental queue because the user has moved
                double torsoSumX = 0.0;
                double torsoSumY = 0.0;
                double torsoSumZ = 0.0;

                double torsoSDX = 0.0;
                double torsoSDY = 0.0;
                double torsoSDZ = 0.0;

                for (int i = 0; i < shoulderCenterPointsSupplemental.Count; i++)
                {
                    torsoSumX += (shoulderCenterPointsSupplemental.ElementAt(i).x +
                                  hipCenterPointsSupplemental.ElementAt(i).x +
                                  spinePointsSupplemental.ElementAt(i).x) / 3.0;
                    torsoSumY += (shoulderCenterPointsSupplemental.ElementAt(i).y +
                                  hipCenterPointsSupplemental.ElementAt(i).y +
                                  spinePointsSupplemental.ElementAt(i).y) / 3.0;
                    torsoSumZ += (shoulderCenterPointsSupplemental.ElementAt(i).depth +
                                  hipCenterPointsSupplemental.ElementAt(i).depth +
                                  spinePointsSupplemental.ElementAt(i).depth) / 3.0;
                }
                double avgTorsoX = torsoSumX / shoulderCenterPointsSupplemental.Count;
                double avgTorsoY = torsoSumY / shoulderCenterPointsSupplemental.Count;
                double avgTorsoZ = torsoSumZ / shoulderCenterPointsSupplemental.Count;
                for (int i = 0; i < shoulderCenterPointsSupplemental.Count; i++)
                {
                    torsoSDX += Math.Pow(((shoulderCenterPointsSupplemental.ElementAt(i).x +
                                           hipCenterPointsSupplemental.ElementAt(i).x +
                                           spinePointsSupplemental.ElementAt(i).x) / 3.0) - avgTorsoX, 2);
                    torsoSDY += Math.Pow(((shoulderCenterPointsSupplemental.ElementAt(i).y +
                                           hipCenterPointsSupplemental.ElementAt(i).y +
                                           spinePointsSupplemental.ElementAt(i).y) / 3.0) - avgTorsoY, 2);
                    torsoSDZ += Math.Pow(((shoulderCenterPointsSupplemental.ElementAt(i).depth +
                                           hipCenterPointsSupplemental.ElementAt(i).depth +
                                           spinePointsSupplemental.ElementAt(i).depth) / 3.0) - avgTorsoZ, 2);
                }
                torsoSDX /= (shoulderCenterPointsSupplemental.Count - 1);
                torsoSDY /= (shoulderCenterPointsSupplemental.Count - 1);
                torsoSDZ /= (shoulderCenterPointsSupplemental.Count - 1);
                DepthPoint current = AvgTorsoPosition;
                double     xZScore = Math.Abs((current.x - avgTorsoX) / torsoSDX);
                double     yZScore = Math.Abs((current.y - avgTorsoY) / torsoSDY);
                double     zZScore = Math.Abs((current.depth - avgTorsoZ) / torsoSDZ);
                if (xZScore + yZScore + zZScore > Z_SCORE_SUM_BOUND)
                {
                    //Console.WriteLine("Adjusting torso center, z score: " + (xZScore + yZScore + zZScore));

                    shoulderCenterPoints = shoulderCenterPointsSupplemental;
                    spinePoints          = spinePointsSupplemental;
                    hipCenterPoints      = hipCenterPointsSupplemental;

                    shoulderCenterPointsSupplemental.Clear();
                    spinePointsSupplemental.Clear();
                    hipCenterPointsSupplemental.Clear();
                }
                else
                {
                    while (shoulderCenterPointsSupplemental.Count > MAX_POINTS_IN_READING)
                    {
                        shoulderCenterPointsSupplemental.Dequeue();
                        spinePointsSupplemental.Dequeue();
                        hipCenterPointsSupplemental.Dequeue();
                    }
                }
            }

            //long shoulderCenterZ = shoulderCenter.depth;
            //long spineZ = spine.depth;
            //long hipCenterZ = hipCenter.depth;

            this.torsoPosition = new DepthPoint((shoulderCenter.x + spine.x + hipCenter.x) / 3,
                                                (shoulderCenter.y + spine.y + hipCenter.y) / 3,
                                                (long)((shoulderCenter.depth + spine.depth + hipCenter.depth) / 3));

            /*
             * this.torsoPosition.x = (shoulderCenter.x + spine.x + hipCenter.x) / 3;
             * this.torsoPosition.y = (shoulderCenter.y + spine.y + hipCenter.y) / 3;
             * this.torsoPosition.depth = (shoulderCenter.depth + spine.Position.Z + hipCenter.Position.Z) / 3;
             * */

            /*
             * //System.Console.WriteLine("shoulder z is: " + shoulderCenterZ + " spine z is: " + spineZ + " hipCenter z is: " + hipCenterZ);
             * if (torsoCounter < MINDATAPOINTSREQ)
             * {
             *  torsoPositions[torsoCounter].X = (shoulderCenter.Position.X + spine.Position.X + hipCenter.Position.X) / 3;
             *  torsoPositions[torsoCounter].Y = (shoulderCenter.Position.Y + spine.Position.Y + hipCenter.Position.Y) / 3;
             *  torsoPositions[torsoCounter].Z = (shoulderCenter.Position.Z + spine.Position.Z + hipCenter.Position.Z) / 3;
             *  torsoCounter++;
             * }
             * else
             * {
             *  this.torsoPosition = new Point3d();
             *  for (int i = 0; i < torsoCounter; i++)
             *  {
             *      this.torsoPosition =
             *          this.torsoPosition + torsoPositions[i];
             *  }
             *  this.torsoPosition.X /= (torsoCounter);
             *  this.torsoPosition.Y /= (torsoCounter);
             *  this.torsoPosition.Z /= (torsoCounter);
             *  //System.Console.WriteLine("The depth of torso is: " + this.torsoPosition);
             * }
             */
        }
예제 #9
0
 public bool crossesPlane(DepthPoint point)
 {
     // Ignore Y axis data
     // Return whether the length of the projected vector into xz-space is greater than the cutoff
     return Math.Sqrt(Math.Pow(point.x - center.x, 2) + Math.Pow(point.depth - center.depth, 2)) > depth;
 }
예제 #10
0
 public bool crossesPlane(DepthPoint point)
 {
     //Console.WriteLine("Difference: " + (point.depth - (center.depth - depth)));
     return point.depth < (center.depth - depth);
 }
예제 #11
0
 public void addPoint(DepthPoint point)
 {
     points.Add(point);
 }
예제 #12
0
 public bool crossesPlane(DepthPoint point)
 {
     // Return whether the length of the vector is greater than the cutoff
     return Math.Sqrt(Math.Pow(point.x - center.x, 2) + Math.Pow(point.depth - center.depth, 2)) > depth;
 }
예제 #13
0
 public Vec2d(DepthPoint p1, DepthPoint p2)
 {
     this.p1 = new Point2d(p1.x, p1.y);
     this.p2 = new Point2d(p2.x, p2.y);
 }
예제 #14
0
 // Simple euclidean distance
 private double distance(DepthPoint x, DepthPoint y)
 {
     return Math.Sqrt(Math.Pow((x.x - y.x), 2) +
                      Math.Pow((x.y - y.y), 2) +
                      Math.Pow((x.depth - y.depth), 2));
 }
예제 #15
0
 public bool crossesPlane(DepthPoint point)
 {
     // Return whether the length of the vector is greater than the cutoff
     return(Math.Sqrt(Math.Pow(point.x - center.x, 2) + Math.Pow(point.depth - center.depth, 2)) > depth);
 }
예제 #16
0
 public Vec2d(DepthPoint p1, DepthPoint p2)
 {
     this.p1 = new Point2d(p1.x, p1.y);
     this.p2 = new Point2d(p2.x, p2.y);
 }
예제 #17
0
 public SphericalPlane(DepthPoint center, double depth)
 {
     this.depth  = depth;
     this.center = center;
 }
예제 #18
0
 public bool crossesPlane(DepthPoint point)
 {
     // Ignore Y axis data
     // Return whether the length of the projected vector into xz-space is greater than the cutoff
     return(Math.Sqrt(Math.Pow(point.x - center.x, 2) + Math.Pow(point.depth - center.depth, 2)) > depth);
 }
예제 #19
0
 public bool crossesPlane(DepthPoint point)
 {
     //Console.WriteLine("Difference: " + (point.depth - (center.depth - depth)));
     return(point.depth < (center.depth - depth));
 }
예제 #20
0
 public void setCenter(DepthPoint center)
 {
     this.center = center;
 }
예제 #21
0
 private int manhattanDistance2d(DepthPoint x, DepthPoint y)
 {
     return(Math.Abs(x.x - y.x) + Math.Abs(x.y - y.y));
 }
예제 #22
0
 public void removePoint(DepthPoint point)
 {
     points.Remove(point);
 }
예제 #23
0
        // Simple euclidean distance

        private double distance(DepthPoint x, DepthPoint y)
        {
            return(Math.Sqrt(Math.Pow((x.x - y.x), 2) +
                             Math.Pow((x.y - y.y), 2) +
                             Math.Pow((x.depth - y.depth), 2)));
        }
예제 #24
0
 private int manhattanDistance2d(DepthPoint x, DepthPoint y)
 {
     return Math.Abs(x.x - y.x) + Math.Abs(x.y - y.y);
 }
예제 #25
0
 public void addPoint(DepthPoint point)
 {
     points.Add(point);
 }
예제 #26
0
 public DepthPoint getNearestPoint(DepthPoint other)
 {
     DepthPoint nearestPoint = null;
     foreach (DepthPoint pt in points)
     {
         if (nearestPoint == null)
         {
             nearestPoint = pt;
         }
         else
         {
             if (distance(pt, other) < distance(nearestPoint, other))
             {
                 nearestPoint = pt;
             }
         }
     }
     return nearestPoint;
 }
예제 #27
0
 public void removePoint(DepthPoint point)
 {
     points.Remove(point);
 }
예제 #28
0
        private double depth; // distance to torso

        #endregion Fields

        #region Constructors

        public CylindricalPlane(DepthPoint center, double depth)
        {
            this.depth = depth;
            this.center = center;
        }
예제 #29
0
 public static double EuclideanDistance2d(DepthPoint p1, DepthPoint p2)
 {
     return Math.Sqrt((p1.x - p2.x) * (p1.x - p2.x) +
                         (p1.y - p2.y) * (p1.y - p2.y));
 }
예제 #30
0
        private double depth; // distance to torso

        #endregion Fields

        #region Constructors

        public FlatPlane(DepthPoint center, double depth)
        {
            this.depth = depth * 1000; // Assuming we get depth in meters from the skeleton tracker
            this.center = center;
        }
예제 #31
0
        private void drawHands(DrawingContext drawingContext, ThreeDAuth.DepthPoint hand, bool drawHand, DepthImageFrame depthFrame)
        {
            //showDepthView(depthFrame, drawingContext);
            //return;
            if (Util.EuclideanDistance2d(hand, lastPoint) < 3.0)
            {
                hand = lastPoint;
            }
            else
            {
                lastPoint = hand;
            }
            

            //Start Siavash

            double resetButtonTimePercentage = 0.0;
            double doneButtonTimePercentage = 0.0;
            if (userImage != null)
            {
                drawingContext.DrawImage(userImage, new Rect(0.0, 0.0, RenderWidth, RenderHeight));

                // Draw the reset button regardless
                //Pen buttonPen = new Pen(Brushes.Black, 0.1);
                //Brush resetButtonBrush = new SolidColorBrush(Color.FromRgb());
                //drawingContext
                if (resetButtonTimer.IsRunning)
                {
                    resetButtonTimePercentage = (double) resetButtonTimer.ElapsedMilliseconds / (double) BUTTON_HOLD_CUTOFF;
                }
                if (resetButtonTimePercentage > 1.0)
                {
                    drawingContext.DrawEllipse(Brushes.Green, null, new System.Windows.Point(0, 0), 50, 50);
                    resetButtonTimePercentage = 1.0;
                }
                else
                {
                    drawingContext.DrawEllipse(Brushes.White, null, new System.Windows.Point(0, 0), 50, 50);
                }
                
                DrawWedge(drawingContext, 0, 0, SweepDirection.Counterclockwise, resetButtonTimePercentage); 
                drawingContext.DrawText(
                    new FormattedText("Reset", 
                                      System.Globalization.CultureInfo.CurrentCulture, 
                                      FlowDirection.LeftToRight, 
                                      new Typeface("Arial"), 
                                      14.0, 
                                      Brushes.Black), 
                    new System.Windows.Point(3, 12.5));

                // Draw the done button if we're learning
                if (gLearner.isRecording)
                {
                    if (doneButtonTimer.IsRunning)
                    {
                        doneButtonTimePercentage = (double)doneButtonTimer.ElapsedMilliseconds / (double)BUTTON_HOLD_CUTOFF;
                    }
                    if (doneButtonTimePercentage > 1.0) doneButtonTimePercentage = 1.0;
                    drawingContext.DrawEllipse(Brushes.White, null, new System.Windows.Point(depthFrame.Width, 0), 50, 50);
                    DrawWedge(drawingContext, depthFrame.Width, 0, SweepDirection.Clockwise, doneButtonTimePercentage);
                    drawingContext.DrawText(
                        new FormattedText("Done",
                                          System.Globalization.CultureInfo.CurrentCulture,
                                          FlowDirection.LeftToRight,
                                          new Typeface("Arial"),
                                          14.0,
                                          Brushes.Black),
                        new System.Windows.Point(depthFrame.Width - 35.0, 12.5));
                }
            }

            //End Siavash
            drawHand = true;
            if (drawHand)
            {
                if (myFrame.AvgTorsoPosition != null)
                //if (myFrame.torsoPosition != null)
                {
                    // Anton's code
                    // when a new frame is available, we check if the wrists are crossing the plane and we draw an appropriately colored
                    // rectangle over them to give the user feedback
                    double planeDepth = myFrame.armLength * .8;
                    int planeDepthPixels = (int)((planeDepth / myFrame.armLength) * myFrame.AvgArmLengthPixels);
                    //ThreeDAuth.FlatPlane myPlane = new ThreeDAuth.FlatPlane(myFrame.torsoPosition, planeDepth);
                    ThreeDAuth.FlatPlane myPlane = new ThreeDAuth.FlatPlane(myFrame.AvgTorsoPosition, planeDepth);
                    //Console.WriteLine("Torso depth: " + torsoSkeletonPoint.Z);
                    //ThreeDAuth.Point3d wristRight = new ThreeDAuth.Point3d(rightWrist.Position.X, rightWrist.Position.Y, rightWrist.Position.Z);

                    //ThreeDAuth.DepthPoint right = this.SkeletonPointToScreen(rightWrist.Position);

                    //ThreeDAuth.PlanePoint arrived = new ThreeDAuth.PlanePoint(right.x, right.y, myPlane.crossesPlane(right));

                    //pDistributor.GivePoint(arrived);
                    //Console.WriteLine("Depth: " + hand.depth);

                    short planeDepthmm = (short)(planeDepth * 1000); // convert m to mm
                    Tuple<int, int> handTuple = new Tuple<int, int>(hand.x, hand.y);
                    if (HandTrackingOptionSet.ProjectingPoints)
                    {
                        handTuple = ProjectPoint(handTuple,
                                                 myFrame.AvgTorsoPosition,
                                                 myFrame.AvgArmLengthPixels,
                                                 planeDepthPixels,
                                                 depthFrame.Width,
                                                 depthFrame.Height);
                    }
                    if (handTuple == null)
                    {
                        // encountered a problem and won't be able to project this point, so drop this frame
                        return;
                    }

                    ThreeDAuth.PlanePoint planePoint = new ThreeDAuth.PlanePoint(handTuple.Item1, handTuple.Item2, myPlane.crossesPlane(hand));
                    //ThreeDAuth.PlanePoint planePoint = new ThreeDAuth.PlanePoint(hand.x, hand.y, myPlane.crossesPlane(hand));
                    pDistributor.GivePoint(planePoint);

                    //drawingContext.DrawRoundedRectangle(Brushes.Green, null, new Rect(hand.x, hand.y, 30, 30), null, 14, null, 14, null);

                    // Check if the point is in the buttons

                    // reset button
                    bool inButton = false;
                    if (Math.Sqrt((planePoint.x * planePoint.x) + (planePoint.y * planePoint.y)) < 50.0)
                    {
                        // in reset button
                        inButton = true;
                        if (!resetButtonTimer.IsRunning)
                        {
                            resetButtonTimer.Start();
                           
                        }
                    }
                    else
                    {
                        if (resetButtonTimer.IsRunning)
                        {

                            resetButtonTimer.Reset();
                           
                        }
                    }

                    // done button
                    if (gLearner.isRecording)
                    {
                        if (Math.Sqrt(((planePoint.x - depthFrame.Width) * (planePoint.x - depthFrame.Width)) + 
                                      (planePoint.y * planePoint.y)) < 50.0)
                        {
                            // in done button
                            inButton = true;
                            if (!doneButtonTimer.IsRunning)
                            {
                                doneButtonTimer.Start();
                            }
                        }
                        else
                        {
                            if (doneButtonTimer.IsRunning)
                            {
                                doneButtonTimer.Reset();
                            }
                        }
                    }


                    if (HandTrackingOptionSet.ShowUnprojectedHand)
                    {
                        drawingContext.DrawRoundedRectangle(Brushes.Yellow, null, new Rect(hand.x, hand.y, 30, 30), null, 14, null, 14, null);
                    }

                    //if (arrived.inPlane)
                    if (planePoint.inPlane)
                    {
                        //drawingContext.DrawRoundedRectangle(Brushes.Blue, null, new Rect(right.x, right.y, 30, 30), null, 14, null, 14, null);
                        //drawingContext.DrawRoundedRectangle(Brushes.Blue, null, new Rect(hand.x, hand.y, 30, 30), null, 14, null, 14, null);
                        drawingContext.DrawRoundedRectangle(Brushes.Blue, null, new Rect(planePoint.x, planePoint.y, 30, 30), null, 14, null, 14, null);
                    }
                    else
                    {
                        //drawingContext.DrawRoundedRectangle(Brushes.Red, null, new Rect(right.x, right.y, 30, 30), null, 14, null, 14, null);
                        //drawingContext.DrawRoundedRectangle(Brushes.Red, null, new Rect(hand.x, hand.y, 30, 30), null, 14, null, 14, null);
                        drawingContext.DrawRoundedRectangle(Brushes.Red, null, new Rect(planePoint.x, planePoint.y, 30, 30), null, 14, null, 14, null);
                    }


                    ThreeDAuth.Point3d wristLeft = new ThreeDAuth.Point3d(leftWrist.Position.X, leftWrist.Position.Y, leftWrist.Position.Z);

                    ThreeDAuth.DepthPoint left = this.SkeletonPointToScreen(leftWrist.Position);

                    if (myPlane.crossesPlane(left))
                    {
                        //drawingContext.DrawRoundedRectangle(Brushes.Blue, null, new Rect(left.X, left.Y, 30, 30), null, 14, null, 14, null);
                    }
                    else
                    {
                        //drawingContext.DrawRoundedRectangle(Brushes.Red, null, new Rect(left.X, left.Y, 30, 30), null, 14, null, 14, null);
                    }



                    // Mason's code
                    // If we're learning a gesture, draw the learned points
                    if (gLearner != null && gLearner.isRecording)
                    {
                        System.Collections.Generic.Queue<ThreeDAuth.Point2d> currentPoints = gLearner.getGesturePath();
                        foreach (ThreeDAuth.Point2d point in currentPoints)
                        {
                            drawingContext.DrawRoundedRectangle(Brushes.Green, null, new Rect(point.x, point.y, 30, 30), null, 14, null, 14, null);

                        }
                    }

                    if (gValidator != null && HandTrackingOptionSet.ShowTargetPoints)
                    {
                        Queue<ThreeDAuth.Point2d> unhitPoints = gValidator.getUnHitPoints();
                        Queue<ThreeDAuth.Point2d> hitPoints = gValidator.getHitPoints();
                        Point2d nextPoint = gValidator.getNextPoint();
                        foreach (Point2d point in unhitPoints)
                        {
                            drawingContext.DrawRoundedRectangle(Brushes.Yellow, null, new Rect(point.x, point.y, 30, 30), null, 14, null, 14, null);
                        }
                        foreach (Point2d point in hitPoints)
                        {
                            drawingContext.DrawRoundedRectangle(Brushes.Green, null, new Rect(point.x, point.y, 30, 30), null, 14, null, 14, null);
                        }

                        if (nextPoint != null)
                        {
                            drawingContext.DrawRoundedRectangle(Brushes.Purple, null, new Rect(nextPoint.x, nextPoint.y, 30, 30), null, 14, null, 14, null);
                        }
                    }

                    if (gLearner != null && gLearner.isRecording && doneButtonTimePercentage >= 1.0)
                    {
                        // Done recording
                        gLearner.stopRecording();
                        this.myImageBox.Visibility = System.Windows.Visibility.Collapsed;
                        List<ThreeDAuth.Point2d> password = new List<ThreeDAuth.Point2d>(gLearner.getGesturePath());
                        this.currentUser.password = password;
                        this.gestureMassage.Text = "Success. Your account has been created. Welcome to 3DAuth!";
                        SaveUser(currentUser);
                        StateMachine.AdvanceState();
                        SetSensorListeners();
                    }

                    if (inButton && resetButtonTimePercentage >= 1.0)
                    {
                        if (gLearner != null && gLearner.isRecording)
                        {
                            // Reset the learner
                            gLearner.restart();
                        }
                        else if (gValidator != null)
                        {
                            // Reset the validator
                            gValidator.restart();
                        }
                    }

                    /*
                    // If we're learning a gesture and we've been out of the plane for 5 seconds, stop learning
                    if (gLearner.isRecording && !planePoint.inPlane)
                    {
                        if (!outOfPlaneTimer.IsRunning)
                        {
                            outOfPlaneTimer.Start();
                        }
                        if (outOfPlaneTimer.ElapsedMilliseconds > BUTTON_HOLD_CUTOFF)
                        {
                            gLearner.stopRecording();
                            this.myImageBox.Visibility = System.Windows.Visibility.Collapsed;
                            List<ThreeDAuth.Point2d> password = new List<ThreeDAuth.Point2d>(gLearner.getGesturePath());
                            this.currentUser.password = password;
                            this.gestureMassage.Text = "Success. Your account has been created. Welcome to 3DAuth!";
                            SaveUser(currentUser);
                        }
                    }
                    else if (gLearner.isRecording)
                    {
                        outOfPlaneTimer.Reset();
                    }
                     * */
                }
            }
        }
예제 #32
0
 public void setCenter(DepthPoint center)
 {
     this.center = center;
 }
예제 #33
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="shoulderCenter"></param>
        /// <param name="spine"></param>
        /// <param name="hipCenter"></param>
        internal void computerTorsoDepth(DepthPoint shoulderCenter, DepthPoint spine, DepthPoint hipCenter)
        {
            totalTorsoPoints++;

            /*
            if (shoulderCenterPoints.Count == MAX_POINTS_IN_READING)
            {
                shoulderCenterPointsSupplemental.Enqueue(shoulderCenter);
                hipCenterPointsSupplemental.Enqueue(hipCenter);
                spinePointsSupplemental.Enqueue(spine);
            }
            */

            while (shoulderCenterPoints.Count > MAX_POINTS_IN_READING)
            {
                shoulderCenterPoints.Dequeue();
                hipCenterPoints.Dequeue();
                spinePoints.Dequeue();
            }

            while (shoulderCenterPointsSupplemental.Count > MAX_POINTS_IN_READING)
            {
                shoulderCenterPointsSupplemental.Dequeue();
                hipCenterPointsSupplemental.Dequeue();
                spinePointsSupplemental.Dequeue();
            }

            if (totalTorsoPoints > MIN_POINTS_BEFORE_READING && shoulderCenterPoints.Count < MAX_POINTS_IN_READING)
            {
                shoulderCenterPoints.Enqueue(shoulderCenter);
                hipCenterPoints.Enqueue(hipCenter);
                spinePoints.Enqueue(spine);
            }
            else
            {
                shoulderCenterPointsSupplemental.Enqueue(shoulderCenter);
                hipCenterPointsSupplemental.Enqueue(hipCenter);
                spinePointsSupplemental.Enqueue(spine);
            }

            // Alpha average between the supplemental points and our stored average torso pos

            if (shoulderCenterPointsSupplemental.Count > 30 && _avgTorsoPosition != null)
            {
                List<double> shoulderCenterX = new List<double>();
                List<double> shoulderCenterY = new List<double>();
                List<double> shoulderCenterZ = new List<double>();

                List<double> hipCenterX = new List<double>();
                List<double> hipCenterY = new List<double>();
                List<double> hipCenterZ = new List<double>();

                List<double> spineX = new List<double>();
                List<double> spineY = new List<double>();
                List<double> spineZ = new List<double>();

                for (int i = 0; i < shoulderCenterPoints.Count; i++)
                {
                    shoulderCenterX.Add(shoulderCenterPoints.ElementAt(i).x);
                    shoulderCenterY.Add(shoulderCenterPoints.ElementAt(i).y);
                    shoulderCenterZ.Add(shoulderCenterPoints.ElementAt(i).depth);

                    hipCenterX.Add(hipCenterPoints.ElementAt(i).x);
                    hipCenterY.Add(hipCenterPoints.ElementAt(i).y);
                    hipCenterZ.Add(hipCenterPoints.ElementAt(i).depth);

                    spineX.Add(spinePoints.ElementAt(i).x);
                    spineY.Add(spinePoints.ElementAt(i).y);
                    spineZ.Add(spinePoints.ElementAt(i).depth);
                }
                shoulderCenterX.Sort();
                shoulderCenterY.Sort();
                shoulderCenterZ.Sort();

                hipCenterX.Sort();
                hipCenterY.Sort();
                hipCenterZ.Sort();

                spineX.Sort();
                spineY.Sort();
                spineZ.Sort();

                int numToRemove = shoulderCenterPoints.Count / 4;
                for (int i = 0; i < numToRemove; i++)
                {
                    shoulderCenterX.RemoveAt(0);
                    shoulderCenterY.RemoveAt(0);
                    shoulderCenterZ.RemoveAt(0);

                    hipCenterX.RemoveAt(0);
                    hipCenterY.RemoveAt(0);
                    hipCenterZ.RemoveAt(0);

                    spineX.RemoveAt(0);
                    spineY.RemoveAt(0);
                    spineZ.RemoveAt(0);

                    shoulderCenterX.RemoveAt(shoulderCenterX.Count - 1);
                    shoulderCenterY.RemoveAt(shoulderCenterY.Count - 1);
                    shoulderCenterZ.RemoveAt(shoulderCenterZ.Count - 1);

                    hipCenterX.RemoveAt(hipCenterX.Count - 1);
                    hipCenterY.RemoveAt(hipCenterZ.Count - 1);
                    hipCenterZ.RemoveAt(hipCenterZ.Count - 1);

                    spineX.RemoveAt(spineX.Count - 1);
                    spineY.RemoveAt(spineY.Count - 1);
                    spineZ.RemoveAt(spineZ.Count - 1);
                }

                double shoulderCenterSumX = shoulderCenterX.Sum();
                double shoulderCenterSumY = shoulderCenterY.Sum();
                double shoulderCenterSumZ = shoulderCenterZ.Sum();

                double hipCenterSumX = hipCenterX.Sum();
                double hipCenterSumY = hipCenterY.Sum();
                double hipCenterSumZ = hipCenterZ.Sum();

                double spineSumX = spineX.Sum();
                double spineSumY = spineX.Sum();
                double spineSumZ = spineX.Sum();

                double avgShoulderX = shoulderCenterSumX / (double)shoulderCenterX.Count;
                double avgShoulderY = shoulderCenterSumY / (double)shoulderCenterX.Count;
                double avgShoulderZ = shoulderCenterSumZ / (double)shoulderCenterX.Count;

                double avgSpineX = shoulderCenterSumX / (double)shoulderCenterX.Count;
                double avgSpineY = shoulderCenterSumY / (double)shoulderCenterX.Count;
                double avgSpineZ = shoulderCenterSumZ / (double)shoulderCenterX.Count;

                double avgHipX = shoulderCenterSumX / (double)shoulderCenterX.Count;
                double avgHipY = shoulderCenterSumY / (double)shoulderCenterX.Count;
                double avgHipZ = shoulderCenterSumZ / (double)shoulderCenterX.Count;

                double avgTorsoX = (avgShoulderX + avgSpineX + avgHipX) / 3.0;
                double avgTorsoY = (avgShoulderY + avgSpineY + avgHipY) / 3.0;
                double avgTorsoZ = (avgShoulderZ + avgSpineZ + avgHipZ) / 3.0;

                _avgTorsoPosition = new DepthPoint((int) (_avgTorsoPosition.x * (1 - TORSO_LEARNING_ALPHA) + avgTorsoX * TORSO_LEARNING_ALPHA),
                                                   (int) (_avgTorsoPosition.y * (1 - TORSO_LEARNING_ALPHA) + avgTorsoY * TORSO_LEARNING_ALPHA),
                                                   (long) (_avgTorsoPosition.depth * (1 - TORSO_LEARNING_ALPHA) + avgTorsoZ * TORSO_LEARNING_ALPHA));
            }

            if (shoulderCenterPointsSupplemental.Count == MAX_POINTS_IN_READING)
            {
                // Determine if we should switch to the supplemental queue because the user has moved
                double torsoSumX = 0.0;
                double torsoSumY = 0.0;
                double torsoSumZ = 0.0;

                double torsoSDX = 0.0;
                double torsoSDY = 0.0;
                double torsoSDZ = 0.0;

                for (int i = 0; i < shoulderCenterPointsSupplemental.Count; i++)
                {
                    torsoSumX += (shoulderCenterPointsSupplemental.ElementAt(i).x +
                        hipCenterPointsSupplemental.ElementAt(i).x +
                        spinePointsSupplemental.ElementAt(i).x) / 3.0;
                    torsoSumY += (shoulderCenterPointsSupplemental.ElementAt(i).y +
                        hipCenterPointsSupplemental.ElementAt(i).y +
                        spinePointsSupplemental.ElementAt(i).y) / 3.0;
                    torsoSumZ += (shoulderCenterPointsSupplemental.ElementAt(i).depth +
                        hipCenterPointsSupplemental.ElementAt(i).depth +
                        spinePointsSupplemental.ElementAt(i).depth) / 3.0;
                }
                double avgTorsoX = torsoSumX / shoulderCenterPointsSupplemental.Count;
                double avgTorsoY = torsoSumY / shoulderCenterPointsSupplemental.Count;
                double avgTorsoZ = torsoSumZ / shoulderCenterPointsSupplemental.Count;
                for (int i = 0; i < shoulderCenterPointsSupplemental.Count; i++)
                {
                    torsoSDX += Math.Pow(((shoulderCenterPointsSupplemental.ElementAt(i).x +
                        hipCenterPointsSupplemental.ElementAt(i).x +
                        spinePointsSupplemental.ElementAt(i).x) / 3.0) - avgTorsoX, 2);
                    torsoSDY += Math.Pow(((shoulderCenterPointsSupplemental.ElementAt(i).y +
                        hipCenterPointsSupplemental.ElementAt(i).y +
                        spinePointsSupplemental.ElementAt(i).y) / 3.0) - avgTorsoY, 2);
                    torsoSDZ += Math.Pow(((shoulderCenterPointsSupplemental.ElementAt(i).depth +
                        hipCenterPointsSupplemental.ElementAt(i).depth +
                        spinePointsSupplemental.ElementAt(i).depth) / 3.0) - avgTorsoZ, 2);
                }
                torsoSDX /= (shoulderCenterPointsSupplemental.Count - 1);
                torsoSDY /= (shoulderCenterPointsSupplemental.Count - 1);
                torsoSDZ /= (shoulderCenterPointsSupplemental.Count - 1);
                DepthPoint current = AvgTorsoPosition;
                double xZScore = Math.Abs((current.x - avgTorsoX) / torsoSDX);
                double yZScore = Math.Abs((current.y - avgTorsoY) / torsoSDY);
                double zZScore = Math.Abs((current.depth - avgTorsoZ) / torsoSDZ);
                if (xZScore + yZScore + zZScore > Z_SCORE_SUM_BOUND)
                {
                    //Console.WriteLine("Adjusting torso center, z score: " + (xZScore + yZScore + zZScore));

                    shoulderCenterPoints = shoulderCenterPointsSupplemental;
                    spinePoints = spinePointsSupplemental;
                    hipCenterPoints = hipCenterPointsSupplemental;

                    shoulderCenterPointsSupplemental.Clear();
                    spinePointsSupplemental.Clear();
                    hipCenterPointsSupplemental.Clear();
                }
                else
                {
                    while (shoulderCenterPointsSupplemental.Count > MAX_POINTS_IN_READING)
                    {
                        shoulderCenterPointsSupplemental.Dequeue();
                        spinePointsSupplemental.Dequeue();
                        hipCenterPointsSupplemental.Dequeue();
                    }
                }
            }

            //long shoulderCenterZ = shoulderCenter.depth;
            //long spineZ = spine.depth;
            //long hipCenterZ = hipCenter.depth;

            this.torsoPosition = new DepthPoint((shoulderCenter.x + spine.x + hipCenter.x) / 3,
                                                (shoulderCenter.y + spine.y + hipCenter.y) / 3,
                                                (long) ((shoulderCenter.depth + spine.depth + hipCenter.depth) / 3));

            /*
            this.torsoPosition.x = (shoulderCenter.x + spine.x + hipCenter.x) / 3;
            this.torsoPosition.y = (shoulderCenter.y + spine.y + hipCenter.y) / 3;
            this.torsoPosition.depth = (shoulderCenter.depth + spine.Position.Z + hipCenter.Position.Z) / 3;
             * */

            /*
            //System.Console.WriteLine("shoulder z is: " + shoulderCenterZ + " spine z is: " + spineZ + " hipCenter z is: " + hipCenterZ);
            if (torsoCounter < MINDATAPOINTSREQ)
            {
                torsoPositions[torsoCounter].X = (shoulderCenter.Position.X + spine.Position.X + hipCenter.Position.X) / 3;
                torsoPositions[torsoCounter].Y = (shoulderCenter.Position.Y + spine.Position.Y + hipCenter.Position.Y) / 3;
                torsoPositions[torsoCounter].Z = (shoulderCenter.Position.Z + spine.Position.Z + hipCenter.Position.Z) / 3;
                torsoCounter++;
            }
            else
            {
                this.torsoPosition = new Point3d();
                for (int i = 0; i < torsoCounter; i++)
                {
                    this.torsoPosition =
                        this.torsoPosition + torsoPositions[i];
                }
                this.torsoPosition.X /= (torsoCounter);
                this.torsoPosition.Y /= (torsoCounter);
                this.torsoPosition.Z /= (torsoCounter);
                //System.Console.WriteLine("The depth of torso is: " + this.torsoPosition);
            }
             */
        }
예제 #34
0
        public bool IsValidPoint(DepthPoint point)
        {
            long now = System.DateTime.UtcNow.Ticks;
            if (previousPoints.Count < MIN_POINTS)
            {
                previousPoints.Enqueue(new Tuple<DepthPoint, long>(point, now));
                return true;
            }
            else
            {
                // Apply the 6-dimensional gaussian
                // If it's 2+ std dev's away in any dimension, reject it
                ICollection<double> xPos = new LinkedList<double>();
                ICollection<double> yPos = new LinkedList<double>();
                ICollection<double> depthPos = new LinkedList<double>();
                ICollection<long> times = new LinkedList<long>();

                ICollection<double> xVel = new LinkedList<double>();
                ICollection<double> yVel = new LinkedList<double>();
                ICollection<double> depthVel = new LinkedList<double>();
                foreach (Tuple<DepthPoint, long> pointTuple in previousPoints)
                {
                    xPos.Add(pointTuple.Item1.x);
                    yPos.Add(pointTuple.Item1.y);
                    depthPos.Add(pointTuple.Item1.depth);
                    times.Add(pointTuple.Item2);
                    if (xPos.Count > 1 && yPos.Count > 1 && depthPos.Count > 1 && times.Count > 1)
                    {
                        int prev2Index = times.Count - 2;
                        int prev1Index = times.Count - 1;
                        long timeInterval = times.ElementAt(prev1Index) - times.ElementAt(prev2Index);
                        double deltaX = xPos.ElementAt(prev1Index) - xPos.ElementAt(prev2Index);
                        double deltaY = yPos.ElementAt(prev1Index) - yPos.ElementAt(prev2Index);
                        double deltaDepth = depthPos.ElementAt(prev1Index) - depthPos.ElementAt(prev2Index);
                        xVel.Add(deltaX / timeInterval);
                        yVel.Add(deltaY / timeInterval);
                        depthVel.Add(deltaDepth / timeInterval);
                    }
                }
                GaussianHolder xPosGaussian = GaussianHolder.GenerateGaussianFromValueCollection(xPos);
                GaussianHolder yPosGaussian = GaussianHolder.GenerateGaussianFromValueCollection(yPos);
                GaussianHolder depthPosGaussian = GaussianHolder.GenerateGaussianFromValueCollection(depthPos);

                GaussianHolder xVelGaussian = GaussianHolder.GenerateGaussianFromValueCollection(xVel);
                GaussianHolder yVelGaussian = GaussianHolder.GenerateGaussianFromValueCollection(yVel);
                GaussianHolder depthVelGaussian = GaussianHolder.GenerateGaussianFromValueCollection(depthVel);

                double newPointTimeDelta = now - times.ElementAt(times.Count - 1);
                double newXVel = (point.x - xPos.ElementAt(xPos.Count - 1)) / newPointTimeDelta;
                double newYVel = (point.y - yPos.ElementAt(yPos.Count - 1)) / newPointTimeDelta;
                double newDepthVel = (point.depth - depthPos.ElementAt(depthPos.Count - 1)) / newPointTimeDelta;

                // approximate the new expected position
                GaussianHolder deltaXPosGaussian = GaussianHolder.GenerateScalarProductOfGaussian(xVelGaussian, newPointTimeDelta);
                GaussianHolder deltaYPosGaussian = GaussianHolder.GenerateScalarProductOfGaussian(yVelGaussian, newPointTimeDelta);
                GaussianHolder deltaDepthPosGaussian = GaussianHolder.GenerateScalarProductOfGaussian(depthVelGaussian, newPointTimeDelta);

                GaussianHolder newXPosGaussian = GaussianHolder.GenerateSumOfGaussians(xPosGaussian, deltaXPosGaussian);
                GaussianHolder newYPosGaussian = GaussianHolder.GenerateSumOfGaussians(yPosGaussian, deltaYPosGaussian);
                GaussianHolder newDepthPosGaussian = GaussianHolder.GenerateSumOfGaussians(depthPosGaussian, deltaDepthPosGaussian);

                double xVelPhi = xVelGaussian.GetPhiValue(newXVel);
                double yVelPhi = yVelGaussian.GetPhiValue(newYVel);
                double depthVelPhi = depthVelGaussian.GetPhiValue(newDepthVel);
                double xPosPhi = newXPosGaussian.GetPhiValue(point.x);
                double yPosPhi = newYPosGaussian.GetPhiValue(point.y);
                double depthPosPhi = newDepthPosGaussian.GetPhiValue(point.depth);

                //Console.WriteLine("phi: " + xPosPhi + " | " + yPosPhi + " | " + depthPosPhi + " | " +
                //                                            xVelPhi + " | " + yVelPhi + " | " + depthVelPhi);

                if ( (xVelPhi > PHI_CUTOFF && xVelPhi < (1 - PHI_CUTOFF)) &&
                     (yVelPhi > PHI_CUTOFF && yVelPhi < (1 - PHI_CUTOFF)) &&
                     (depthVelPhi > PHI_CUTOFF && depthVelPhi < (1 - PHI_CUTOFF)) &&
                     (xPosPhi > PHI_CUTOFF && xPosPhi < (1 - PHI_CUTOFF)) &&
                     (yPosPhi > PHI_CUTOFF && yPosPhi < (1 - PHI_CUTOFF)) &&
                     (depthPosPhi > PHI_CUTOFF && depthPosPhi < (1 - PHI_CUTOFF)) )
                {
                    previousPoints.Enqueue(new Tuple<DepthPoint, long>(point, now));
                    if (previousPoints.Count > HISTORY_COUNT)
                    {
                        previousPoints.Dequeue();
                    }
                    return true;
                }
                else
                {
                    //Console.WriteLine("Rejected a point!!!!!!!!!!!!!!!!!!!!!!");
                    rejectedPoints.Enqueue(new Tuple<DepthPoint, long>(point, now));
                    while (now - rejectedPoints.First().Item2 > ERROR_TIME_CUTOFF_TICKS)
                    {
                        //Console.WriteLine("dumping rejected points");
                        rejectedPoints.Dequeue();
                    }
                    if (rejectedPoints.Count > ERROR_POINT_LIMIT)
                    {
                        // Received so many error points recently we should probably start over
                        rejectedPoints.Clear();
                        previousPoints.Clear();
                        previousPoints.Enqueue(new Tuple<DepthPoint, long>(point, now));
                        //Console.WriteLine("***************** STARTING OVER ************************");
                        return true;
                    }
                    else
                    {
                        // Haven't received that many error points ecently and we rejected the most recent one
                        return false;
                    }
                }
            }
        }
예제 #35
0
        public bool IsValidPoint(DepthPoint point)
        {
            long now = System.DateTime.UtcNow.Ticks;

            if (previousPoints.Count < MIN_POINTS)
            {
                previousPoints.Enqueue(new Tuple <DepthPoint, long>(point, now));
                return(true);
            }
            else
            {
                // Apply the 6-dimensional gaussian
                // If it's 2+ std dev's away in any dimension, reject it
                ICollection <double> xPos     = new LinkedList <double>();
                ICollection <double> yPos     = new LinkedList <double>();
                ICollection <double> depthPos = new LinkedList <double>();
                ICollection <long>   times    = new LinkedList <long>();

                ICollection <double> xVel     = new LinkedList <double>();
                ICollection <double> yVel     = new LinkedList <double>();
                ICollection <double> depthVel = new LinkedList <double>();
                foreach (Tuple <DepthPoint, long> pointTuple in previousPoints)
                {
                    xPos.Add(pointTuple.Item1.x);
                    yPos.Add(pointTuple.Item1.y);
                    depthPos.Add(pointTuple.Item1.depth);
                    times.Add(pointTuple.Item2);
                    if (xPos.Count > 1 && yPos.Count > 1 && depthPos.Count > 1 && times.Count > 1)
                    {
                        int    prev2Index   = times.Count - 2;
                        int    prev1Index   = times.Count - 1;
                        long   timeInterval = times.ElementAt(prev1Index) - times.ElementAt(prev2Index);
                        double deltaX       = xPos.ElementAt(prev1Index) - xPos.ElementAt(prev2Index);
                        double deltaY       = yPos.ElementAt(prev1Index) - yPos.ElementAt(prev2Index);
                        double deltaDepth   = depthPos.ElementAt(prev1Index) - depthPos.ElementAt(prev2Index);
                        xVel.Add(deltaX / timeInterval);
                        yVel.Add(deltaY / timeInterval);
                        depthVel.Add(deltaDepth / timeInterval);
                    }
                }
                GaussianHolder xPosGaussian     = GaussianHolder.GenerateGaussianFromValueCollection(xPos);
                GaussianHolder yPosGaussian     = GaussianHolder.GenerateGaussianFromValueCollection(yPos);
                GaussianHolder depthPosGaussian = GaussianHolder.GenerateGaussianFromValueCollection(depthPos);

                GaussianHolder xVelGaussian     = GaussianHolder.GenerateGaussianFromValueCollection(xVel);
                GaussianHolder yVelGaussian     = GaussianHolder.GenerateGaussianFromValueCollection(yVel);
                GaussianHolder depthVelGaussian = GaussianHolder.GenerateGaussianFromValueCollection(depthVel);

                double newPointTimeDelta = now - times.ElementAt(times.Count - 1);
                double newXVel           = (point.x - xPos.ElementAt(xPos.Count - 1)) / newPointTimeDelta;
                double newYVel           = (point.y - yPos.ElementAt(yPos.Count - 1)) / newPointTimeDelta;
                double newDepthVel       = (point.depth - depthPos.ElementAt(depthPos.Count - 1)) / newPointTimeDelta;

                // approximate the new expected position
                GaussianHolder deltaXPosGaussian     = GaussianHolder.GenerateScalarProductOfGaussian(xVelGaussian, newPointTimeDelta);
                GaussianHolder deltaYPosGaussian     = GaussianHolder.GenerateScalarProductOfGaussian(yVelGaussian, newPointTimeDelta);
                GaussianHolder deltaDepthPosGaussian = GaussianHolder.GenerateScalarProductOfGaussian(depthVelGaussian, newPointTimeDelta);

                GaussianHolder newXPosGaussian     = GaussianHolder.GenerateSumOfGaussians(xPosGaussian, deltaXPosGaussian);
                GaussianHolder newYPosGaussian     = GaussianHolder.GenerateSumOfGaussians(yPosGaussian, deltaYPosGaussian);
                GaussianHolder newDepthPosGaussian = GaussianHolder.GenerateSumOfGaussians(depthPosGaussian, deltaDepthPosGaussian);

                double xVelPhi     = xVelGaussian.GetPhiValue(newXVel);
                double yVelPhi     = yVelGaussian.GetPhiValue(newYVel);
                double depthVelPhi = depthVelGaussian.GetPhiValue(newDepthVel);
                double xPosPhi     = newXPosGaussian.GetPhiValue(point.x);
                double yPosPhi     = newYPosGaussian.GetPhiValue(point.y);
                double depthPosPhi = newDepthPosGaussian.GetPhiValue(point.depth);

                //Console.WriteLine("phi: " + xPosPhi + " | " + yPosPhi + " | " + depthPosPhi + " | " +
                //                                            xVelPhi + " | " + yVelPhi + " | " + depthVelPhi);


                if ((xVelPhi > PHI_CUTOFF && xVelPhi < (1 - PHI_CUTOFF)) &&
                    (yVelPhi > PHI_CUTOFF && yVelPhi < (1 - PHI_CUTOFF)) &&
                    (depthVelPhi > PHI_CUTOFF && depthVelPhi < (1 - PHI_CUTOFF)) &&
                    (xPosPhi > PHI_CUTOFF && xPosPhi < (1 - PHI_CUTOFF)) &&
                    (yPosPhi > PHI_CUTOFF && yPosPhi < (1 - PHI_CUTOFF)) &&
                    (depthPosPhi > PHI_CUTOFF && depthPosPhi < (1 - PHI_CUTOFF)))
                {
                    previousPoints.Enqueue(new Tuple <DepthPoint, long>(point, now));
                    if (previousPoints.Count > HISTORY_COUNT)
                    {
                        previousPoints.Dequeue();
                    }
                    return(true);
                }
                else
                {
                    //Console.WriteLine("Rejected a point!!!!!!!!!!!!!!!!!!!!!!");
                    rejectedPoints.Enqueue(new Tuple <DepthPoint, long>(point, now));
                    while (now - rejectedPoints.First().Item2 > ERROR_TIME_CUTOFF_TICKS)
                    {
                        //Console.WriteLine("dumping rejected points");
                        rejectedPoints.Dequeue();
                    }
                    if (rejectedPoints.Count > ERROR_POINT_LIMIT)
                    {
                        // Received so many error points recently we should probably start over
                        rejectedPoints.Clear();
                        previousPoints.Clear();
                        previousPoints.Enqueue(new Tuple <DepthPoint, long>(point, now));
                        //Console.WriteLine("***************** STARTING OVER ************************");
                        return(true);
                    }
                    else
                    {
                        // Haven't received that many error points ecently and we rejected the most recent one
                        return(false);
                    }
                }
            }
        }
예제 #36
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="leftWristJoint"></param>
        /// <param name="leftShoulderJoint"></param>
        /// <param name="rightWristJoint"></param>
        /// <param name="rightShoulderJoint"></param>
        public void computeArmLengthPixels(DepthPoint leftWristPoint, DepthPoint leftShoulderPoint, DepthPoint rightWristPoint, DepthPoint rightShoulderPoint)
        {
            totalArmPoints++;
            if (totalArmPoints > MIN_POINTS_BEFORE_READING && leftWristPoints.Count < MAX_POINTS_IN_READING)
            {
                leftWristPoints.Enqueue(leftWristPoint);
                leftShoulderPoints.Enqueue(leftShoulderPoint);
                rightWristPoints.Enqueue(rightWristPoint);
                rightShoulderPoints.Enqueue(rightShoulderPoint);
            }

            int leftArmX = leftWristPoint.x - leftShoulderPoint.x;
            int leftArmY = leftWristPoint.y - leftShoulderPoint.y;
            //int leftArmZ = leftWristPoint.Position.Z - leftShoulderPoint.Position.Z;
            int rightArmX = rightWristPoint.x - rightShoulderPoint.x;
            int rightArmY = rightWristPoint.y - rightShoulderPoint.y;
            //int rightArmZ = rightWristPoint.Position.Z - rightShoulderPoint.Position.Z;
            double leftArm = Math.Sqrt(leftArmX * leftArmX + leftArmY * leftArmY /*+ leftArmZ * leftArmZ*/);
            double rightArm = Math.Sqrt(rightArmX * rightArmX + rightArmY * rightArmY /*+ rightArmZ * rightArmZ*/);

            this.armLengthPixels = (int) ((leftArm + rightArm) / 2.0);

            /*
             * The length of both arms changes depending on the location of the person due to noise in data
             * and also inaccuracy of depth cammera at too far and too close postions.
             * so we collect at least 50 data points of the four joint we need and calculate the avregae
             *
             */
            /*
            if (armCounter < MINDATAPOINTSREQ)
            {
                armLengths[armCounter] = (leftArm + rightArm) / 2;
                armCounter++;
            }
            else
            {
                for (int i = 0; i < armCounter; i++)
                {
                    this.armLength += armLengths[i];
                }
                //this.armLength /= (armCounter);
                this.armLength = (leftArm + rightArm) / 2;
            }*/
        }
예제 #37
0
 public FlatPlane(DepthPoint center, double depth)
 {
     this.depth  = depth * 1000; // Assuming we get depth in meters from the skeleton tracker
     this.center = center;
 }
예제 #38
0
        private Tuple<int, int> ProjectPoint(Tuple<int, int> basePoint,
                                            DepthPoint torsoPosition,
                                            int armLengthPixels,
                                            int planeDepthFromTorsoPixels,
                                            double alpha,
                                            int windowWidth,
                                            int windowHeight)
        {
            // return basePoint;

            //armLength *= 1000; // Convert meters to mm
            // Get pixel length of the arm

            // We wish to find how many millimeters away from the corner of the target box our torso center is

            // If we're at torsoPosition and the plane is planeDepthFromTorso away from us,
            // then we construct a right triangle where one side is the vector
            // of our torso to the plane,
            // the other side is the vector from the center of the plane to the corner of the plane
            // and the hypotenuse is our required arm

            // Vector of torso to plane has length planeDepthFromTorso
            // Vector of our required arm length is alpha * armLength
            // By the pythagorean theorem, (alpha * armLength)^2 = (planeDepthFromTorso)^2 + (distance to corner)^2
            // so distance to corner = + sqrt( (alpha * armLength)^2 - (planeDepthFromTorso)^2 )

            double tempValue = Math.Pow(alpha * armLengthPixels, 2) - Math.Pow(planeDepthFromTorsoPixels, 2);
            // If this tempValue is less than 0 then holding the arm straight out infront of you
            // (with the given alpha) will not cross the plane and we have bigger problems
            if (tempValue < 0)
            {
                // Sanity check
                return null;
            }

            double distanceToCornermm = Math.Sqrt(tempValue);

            // Now find the x and y offset required to get to the corner
            // if we consider our torso position as at the center of the box (they should be standing there)
            // then we consider the angle the vector to the upper right corner forms with the horizontal plane
            // to be a value theta

            // our x offset to the corner will be cos(theta) * distanceToCornermm
            // (cos(angle) = adj / hyp, so adj = cos(angle) * hyp)

            // our y offset to the corner will be sin(theta) * distanceToCornermm
            // (sin(angle) = adj / hyp, so adj = sin(angle) * hyp)

            // By similar triangles (rectangles), tan(theta) = windowHeight / windowWidth, both of which we know
            // so theta = arctan(windowHeight / windowWidth);

            double theta = Math.Atan((double)windowHeight / (double)windowWidth);
            double xOffset = Math.Cos(theta) * distanceToCornermm;
            double yOffset = Math.Sin(theta) * distanceToCornermm;

            Microsoft.Kinect.SkeletonPoint cornerSkeletonPoint = new Microsoft.Kinect.SkeletonPoint();
            cornerSkeletonPoint.X = (float)(torsoPosition.x + xOffset);
            cornerSkeletonPoint.Y = (float)(torsoPosition.y + yOffset);
            //DepthPoint lowerRightCornerDepthPoint = this.SkeletonPointToScreen(cornerSkeletonPoint);

            // This cornerPoint should represent the bottom right corner more or less
            // So its x value should be our pre-projected target box width,
            // and its y value should be our pre-projected target box height

            double xScale = (double)windowWidth / (double)(torsoPosition.x + xOffset);
            double yScale = (double)windowHeight / (double)(torsoPosition.y + yOffset);

            Tuple<int, int> shiftedPoint = new Tuple<int, int>(basePoint.Item1 - torsoPosition.x, basePoint.Item2 - torsoPosition.y);

            int xProj = (int)Math.Floor(xScale * shiftedPoint.Item1);
            int yProj = (int)Math.Floor(yScale * shiftedPoint.Item2);

            // unshift the point
            xProj = xProj + torsoPosition.x;
            yProj = yProj + torsoPosition.y;

            //bound checking
            if (xProj > windowWidth) xProj = windowWidth - 1;
            if (yProj > windowHeight) yProj = windowHeight - 1;
            if (xProj <= 0) xProj = 1;
            if (yProj <= 0) yProj = 1;

            //Console.WriteLine("(" + basePoint.Item1 + ", " + basePoint.Item2 + ") -> (" + xProj + ", " + yProj + ")" +
                                //"     Arm length: " + armLengthPixels);

            return new Tuple<int, int>(xProj, yProj);
        }
예제 #39
0
        /// <summary>
        /// Start Siavash
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SensorDepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        {
            if (lastPoint == null)
            {
                lastPoint = new DepthPoint(0, 0, 0);
            }
            using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
            {
                if (depthFrame != null)
                {
                    this.maxDepth = depthFrame.MaxDepth;
                    this.minDepth = depthFrame.MinDepth;
                    this.closestPoint.Depth = Convert.ToInt16(this.maxDepth);

                    if (this.imagePixelData == null || this.imadeData == null)
                    {
                        this.imadeData = new short[depthFrame.PixelDataLength];
                        this.imagePixelData = new DepthImagePixel[depthFrame.PixelDataLength];
                    }

                    depthFrame.CopyDepthImagePixelDataTo(imagePixelData);
                    depthFrame.CopyPixelDataTo(imadeData);

                    // This cutoff allows us to control how often the closest point is calculated (it doesn't necessarily need to be calculated every frame)
                    closestPointCounter %= CLOSEST_POINT_COUNTER_CUTOFF;
                    if (closestPointCounter == 0)
                    {
                        findTheClosestPoint(depthFrame.PixelDataLength, depthFrame.Width, depthFrame.Height);
                    }
                    closestPointCounter++;



                    // Flood fill from this point then send a point to the distributor

                    // If the nearest point hasn't broken the plane, then don't bother doing anything with it


                    // The array index is computed as x + y*width,
                    // So x = idx % width
                    // y = (idx - x)/width
                    int xIdx = this.pixelIndex % depthFrame.Width;
                    int yIdx = this.pixelIndex / depthFrame.Width;

                    myPointCluster = ThreeDAuth.Util.FloodFill2(imagePixelData, xIdx, yIdx, depthFrame.Width, depthFrame.Height - 1);
                    ThreeDAuth.DepthPoint centroid = myPointCluster.Centroid;


                    // send centroid to filter and draw if valid
                    int counter = 0;
                    while (myPointCluster.points.Count < 50 && counter < 20)
                    {
                        imagePixelData[pixelIndex].Depth = short.MaxValue;
                        counter++;

                        findTheClosestPoint(depthFrame.PixelDataLength, depthFrame.Width, depthFrame.Height);
                        xIdx = this.pixelIndex % depthFrame.Width;
                        yIdx = this.pixelIndex / depthFrame.Width;

                        myPointCluster = ThreeDAuth.Util.FloodFill2(imagePixelData, xIdx, yIdx, depthFrame.Width, depthFrame.Height - 1);
                        centroid = myPointCluster.Centroid;
                    }
                    if (counter < 20)
                    {
                        using (DrawingContext dc = this.liveFeedbackGroup.Open())
                        {
                            drawHands(dc, centroid, positionMotionFilter.IsValidPoint(centroid), depthFrame);
                        }
                        if (depthViewWindow != null && depthViewWindow.Running)
                        {
                            depthViewWindow.GiveFrame(depthFrame, myPointCluster);
                        }
                    }
                }
            }
        }