Beispiel #1
0
        /// <summary>
        /// Subtracts two points.
        /// </summary>
        /// <param name="point1">Minuend point.</param>
        /// <param name="point2">Subtrahend point.</param>
        /// <returns>Returns the difference .</returns>
        public static PointsFingers subtract(PointsFingers point1, PointsFingers point2)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X - point2.X;
            sol.Y = point1.Y - point2.Y;
            return(sol);
        }
Beispiel #2
0
        /// <summary>
        /// Subtracts a scalar to all the coordinates of the source point.
        /// </summary>
        /// <param name="point1">Source point.</param>
        /// <param name="value">The scalar to substract.</param>
        /// <returns>Returs the difference.</returns>
        public static PointsFingers subtract(PointsFingers point1, int value)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X - value;
            sol.Y = point1.Y - value;
            return(sol);
        }
Beispiel #3
0
        /// <summary>
        /// Multiplies two points.
        /// </summary>
        /// <param name="point1">Source point.</param>
        /// <param name="point2">Source point.</param>
        /// <returns>Returns the product.</returns>
        public static PointsFingers multiply(PointsFingers point1, PointsFingers point2)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X * point2.X;
            sol.Y = point1.Y * point2.Y;
            return(sol);
        }
Beispiel #4
0
        /// <summary>
        /// Divides the source point by an scalar.
        /// </summary>
        /// <param name="point1">Source point.</param>
        /// <param name="value">The divisor.</param>
        /// <returns>Returns the division.</returns>
        public static PointsFingers operator /(PointsFingers point1, int value)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X / value;
            sol.Y = point1.Y / value;
            return(sol);
        }
Beispiel #5
0
        /// <summary>
        /// Multiplies the source point by a scalar.
        /// </summary>
        /// <param name="point1">Source point.</param>
        /// <param name="value">The factor.</param>
        /// <returns>Returns the product.</returns>
        public static PointsFingers multiply(PointsFingers point1, int value)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X * value;
            sol.Y = point1.Y * value;
            return(sol);
        }
Beispiel #6
0
        /// <summary>
        /// Divides two points.
        /// </summary>
        /// <param name="point1">The dividend.</param>
        /// <param name="point2">The divisor.</param>
        /// <returns>Returns the division.</returns>
        public static PointsFingers operator /(PointsFingers point1, PointsFingers point2)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X / point2.X;
            sol.Y = point1.Y / point2.Y;
            return(sol);
        }
Beispiel #7
0
        /// <summary>
        /// Adds a scalar to all the coordinates of the source point.
        /// </summary>
        /// <param name="point1">Source point.</param>
        /// <param name="value">The scalar to add.</param>
        /// <returns>Returs the sum.</returns>
        public static PointsFingers add(PointsFingers point1, int value)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X + value;
            sol.Y = point1.Y + value;
            return(sol);
        }
Beispiel #8
0
        /// <summary>
        /// Adds two points.
        /// </summary>
        /// <param name="point1">Source point.</param>
        /// <param name="point2">Source point.</param>
        /// <returns>Returns the sum.</returns>
        public static PointsFingers add(PointsFingers point1, PointsFingers point2)
        {
            PointsFingers sol = new PointsFingers();

            sol.X = point1.X + point2.X;
            sol.Y = point1.Y + point2.Y;
            return(sol);
        }
Beispiel #9
0
        // Normalize in the interval [-1, 1] the given 3D point.
        // The Z value is in the inverval [-1, 0], being 0 the closest distance.
        private Coordinates3D transformTo3DCoord(PointsFingers p, int width, int height, int distance)
        {
            Coordinates3D v = new Coordinates3D();

            v.X = p.Y / (width * 1.0f) * 2 - 1;
            v.Y = (1 - p.X / (height * 1.0f)) * 2 - 1;
            v.Z = (distance - 400) / -7600.0f;
            return(v);
        }
Beispiel #10
0
 // Check if a point is inside the hand countour box
 public bool isPointInsideContainerBox(PointsFingers p) // Takes a point as an arg and returns if point is inside the hand contour box or not.
 {
     if (p.X < rightDownCorner.X && p.X > leftUpperCorner.X &&
         p.Y > leftUpperCorner.Y && p.Y < rightDownCorner.Y)    // Note that the origin is on the upper-left corner of the box.
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Beispiel #11
0
        // Constructor of Hand Class. When Hand class is instantiated, it is automatically called and the default properties are set for various attributes.
        public HandDetection()
        {
            palm = new PointsFingers(-1, -1); // Set to impossible coordinates before capturing data.

            fingertips = new List<PointsFingers>(5); // List to the 5 fingertips to be tracked.
            fingertips3D = new List<Coordinates3D>(5); // Basically is used to track the X,Y,Z coordinates of all the 5 fingertips. List has five elements each of which have 3 properites each.

            contour = new List<PointsFingers>(2000);
            inside = new List<PointsFingers>(6000);

            leftUpperCorner = new PointsFingers(int.MaxValue, int.MaxValue);
            rightDownCorner = new PointsFingers(int.MinValue, int.MinValue);
        }
Beispiel #12
0
        /// <summary>
        /// Checks if two points are equals.
        /// </summary>
        /// <param name="obj">The point to compare with.</param>
        /// <returns>Returns true if the points are equals, or false otherwise.</returns>
        public override bool Equals(object obj)
        {
            PointsFingers other = (PointsFingers)obj;

            if (this.X == other.X && this.Y == other.Y)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #13
0
        public HandDetection()                          // Constructor of Hand Class. When Hand class is instantiated, it is automatically called and the default properties are set for various attributes.
        {
            palm = new PointsFingers(-1, -1);           // Set to impossible coordinates before capturing data.

            fingertips   = new List <PointsFingers>(5); // List to the 5 fingertips to be tracked.
            fingertips3D = new List <Coordinates3D>(5); // Basically is used to track the X,Y,Z coordinates of all the 5 fingertips. List has five elements each of which have 3 properites each.

            contour = new List <PointsFingers>(2000);
            inside  = new List <PointsFingers>(6000);

            leftUpperCorner = new PointsFingers(int.MaxValue, int.MaxValue);
            rightDownCorner = new PointsFingers(int.MinValue, int.MinValue);
        }
Beispiel #14
0
 // Obtain the 3D normalized point and add it to the list of fingertips
 public void calculate3DPoints(int width, int height, int[] distance)
 {
     if (palm.X != -1 && palm.Y != -1)
     {
         palm3D = transformTo3DCoord(palm, width, height, distance[palm.X * width + palm.Y]); // Calculate 3-D position of palm
     }
     fingertips3D.Clear();                                                                    // Empty any unwanted data.
     for (int i = 0; i < fingertips.Count; ++i)
     {
         PointsFingers f = fingertips[i];                                                         // Store the value of each element in f use it as parameter in transformTo3DCoord
         if (palm.X - fingertips[i].X < 20)                                                       //reduces the noise, limits fingertips to 20 pixel distance from center.
         {
             fingertips3D.Add(transformTo3DCoord(f, width, height, distance[f.X * width + f.Y])); // Append the modified elements. The useful set of points are actually in fingertips3D
         }
     }
 }
Beispiel #15
0
        public bool isCircleInsideContainerBox(PointsFingers p, float r)
        {
            if (leftUpperCorner.X > p.X - r)
            {
                return(false);
            }
            if (rightDownCorner.X < p.X + r)
            {
                return(false);
            }
            if (leftUpperCorner.Y > p.Y - r)
            {
                return(false);
            }
            if (rightDownCorner.Y < p.Y + r)
            {
                return(false);
            }

            return(true);
        }
Beispiel #16
0
        // Calculate the contour box of the hand if it possible
        public bool calculateContainerBox(float reduction = 0)
        {
            if (contour != null && contour.Count > 0)
            {
                for (int j = 0; j < contour.Count; ++j)
                {
                    if (leftUpperCorner.X > contour[j].X)
                    {
                        leftUpperCorner.X = contour[j].X;
                    }

                    if (rightDownCorner.X < contour[j].X)
                    {
                        rightDownCorner.X = contour[j].X;
                    }

                    if (leftUpperCorner.Y > contour[j].Y)
                    {
                        leftUpperCorner.Y = contour[j].Y;
                    }

                    if (rightDownCorner.Y < contour[j].Y)
                    {
                        rightDownCorner.Y = contour[j].Y;
                    }
                }

                int           incX = (int)((rightDownCorner.X - leftUpperCorner.X) * (reduction / 2));
                int           incY = (int)((rightDownCorner.Y - leftUpperCorner.Y) * (reduction / 2));
                PointsFingers inc  = new PointsFingers(incX, incY);
                leftUpperCorner = leftUpperCorner + inc;
                rightDownCorner = rightDownCorner + inc;

                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #17
0
        /*
         * This function calcute the border of a closed figure starting in one of the contour points.
         * The turtle algorithm is used.
         */
        private List <PointsFingers> CalculateFrontier(ref bool[][] valid, PointsFingers start, ref bool[][] contour)
        {
            List <PointsFingers> list    = new List <PointsFingers>();
            PointsFingers        last    = new PointsFingers(-1, -1);
            PointsFingers        current = new PointsFingers(start);
            int dir = 0;

            do
            {
                if (valid[current.X][current.Y])
                {
                    dir = (dir + 1) % 4;
                    if (current != last)
                    {
                        list.Add(new PointsFingers(current.X, current.Y));
                        last = new PointsFingers(current);
                        contour[current.X][current.Y] = false;
                    }
                }
                else
                {
                    dir = (dir + 4 - 1) % 4;
                }

                switch (dir)
                {
                case 0: current.X += 1; break;     // Down

                case 1: current.Y += 1; break;     // Right

                case 2: current.X -= 1; break;     // Up

                case 3: current.Y -= 1; break;     // Left
                }
            } while (current != start);

            return(list);
        }
Beispiel #18
0
 /// <summary>
 /// Calculates the Euclidean distance between two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the distance between the points squared.</returns>
 public static float distanceEuclideanSquared(PointsFingers point1, PointsFingers point2)
 {
     return((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y));
 }
Beispiel #19
0
 /// <summary>
 /// Calculates the dot product of two points. Returns a floating point value between -1 and 1.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the dot product of the source points.</returns>
 public static float dot(PointsFingers point1, PointsFingers point2)
 {
     return((point1.X * point2.X + point1.Y * point2.Y) / (length(point1) * length(point2)));
 }
Beispiel #20
0
 /// <summary>
 /// Multiplies two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the product.</returns>
 public static PointsFingers multiply(PointsFingers point1, PointsFingers point2)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X * point2.X;
     sol.Y = point1.Y * point2.Y;
     return sol;
 }
Beispiel #21
0
 /// <summary>
 /// Calculates the Euclidean distance between two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the distance between the points.</returns>
 public static float distanceEuclidean(PointsFingers point1, PointsFingers point2)
 {
     return((float)Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y)));
 }
Beispiel #22
0
 /// <summary>
 /// Copy and create a new instance of PointFT.
 /// </summary>
 /// <param name="other">The PointFT to copy.</param>
 public PointsFingers(PointsFingers other)
 {
     this.X = other.X;
     this.Y = other.Y;
 }
Beispiel #23
0
 /// <summary>
 /// Multiplies the source point by a scalar.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="value">The factor.</param>
 /// <returns>Returns the product.</returns>
 public static PointsFingers operator *(PointsFingers point1, int value)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X * value;
     sol.Y = point1.Y * value;
     return sol;
 }
Beispiel #24
0
 /// <summary>
 /// Divides two points.
 /// </summary>
 /// <param name="point1">The dividend.</param>
 /// <param name="point2">The divisor.</param>
 /// <returns>Returns the division.</returns>
 public static PointsFingers divide(PointsFingers point1, PointsFingers point2)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X / point2.X;
     sol.Y = point1.Y / point2.Y;
     return sol;
 }
Beispiel #25
0
 /// <summary>
 /// Calculates the smaller angle between two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the angle in radians.</returns>
 public static float angle(PointsFingers point1, PointsFingers point2)
 {
     return (float)Math.Acos((point1.X * point2.X + point1.Y * point2.Y) / (length(point1) * length(point2)));
 }
Beispiel #26
0
 // Takes a point as an arg and returns if point is inside the hand contour box or not.
 // Check if a point is inside the hand countour box
 public bool isPointInsideContainerBox(PointsFingers p)
 {
     if (p.X < rightDownCorner.X && p.X > leftUpperCorner.X
         && p.Y > leftUpperCorner.Y && p.Y < rightDownCorner.Y) // Note that the origin is on the upper-left corner of the box.
     {
         return true;
     }
     else
     {
         return false;
     }
 }
Beispiel #27
0
 /// <summary>
 /// Divides the source point by an scalar.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="value">The divisor.</param>
 /// <returns>Returns the division.</returns>
 public static PointsFingers divide(PointsFingers point1, int value)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X / value;
     sol.Y = point1.Y / value;
     return sol;
 }
Beispiel #28
0
 /// <summary>
 /// Calculates the dot product of two points. Returns a floating point value between -1 and 1.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the dot product of the source points.</returns>
 public static float dot(PointsFingers point1, PointsFingers point2)
 {
     return (point1.X * point2.X + point1.Y * point2.Y) / (length(point1) * length(point2));
 }
Beispiel #29
0
        public void depthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        //  public void depthFrameReady(int img_count, DepthImageFrameReadyEventArgs e)//,int img_count)

        {
            // Get the depth frame from Kinect
            using (DepthImageFrame frame = e.OpenDepthImageFrame())
            {
                // Check that the frame is not null
                if (frame == null)
                {
                    return;
                }
                // Calculate the real distance for every pixel in the depth image
                int[] distances = generateDistances(frame);

                // Return a 0 or 1 matrix, which contains wich pixels are near enough
                bool[][] near = generateValidMatrix(frame, distances);

                // Return the tracked hands based on the near pixels
                hands = localizeHands(near);

                byte[] pixels = new byte[frame.PixelDataLength * 4];

                // Free last depth Matrix
                Marshal.FreeHGlobal(depthPtr);
                depthPtr = Marshal.AllocHGlobal(pixels.Length);
                Marshal.Copy(pixels, 0, depthPtr, pixels.Length);

                // Create the bitmap
                int height = near.Length;
                int width  = 0;
                if (near.Length > 0)
                {
                    width = near[0].Length;
                }
                int stride = width * 4;

                depthImage = new Bitmap(
                    width,
                    height,
                    stride,
                    PixelFormat.Format32bppRgb,
                    depthPtr);

                // Calculate 3D points for the hands
                for (int i = 0; i < hands.Count; ++i)
                {
                    hands[i].calculate3DPoints(settings.screenWidth, settings.screenHeight, distances);
                }

                // Call the rest of the functions
                afterDepthReady();

                // Draw fingertips and palm center
                Graphics gBmp        = Graphics.FromImage(depthImage);
                Brush    greenBrush  = new SolidBrush(Color.Green);
                Brush    yellowBrush = new SolidBrush(Color.Yellow);

                for (int i = 0; i < hands.Count; ++i)
                {
                    // Yellow point which is the center of the palm
                    gBmp.FillEllipse(yellowBrush, hands[i].palm.Y - 5, hands[i].palm.X - 5, 10, 10);

                    // Draw inside points
                    //for (int j = 0; j < hands[i].inside.Length; ++j)
                    //{
                    //    Point p = hands[i].inside.Get(j);
                    //    depthImage.SetPixel(p.Y, p.X, Color.Blue);
                    //}

                    // Draw the contour of the hands
                    for (int j = 0; j < hands[i].contour.Count; ++j)
                    {
                        PointsFingers p = hands[i].contour[j];
                        depthImage.SetPixel(p.Y, p.X, Color.Snow);
                    }

                    // Blue points which represent the fingertips
                    for (int j = 0; j < hands[i].fingertips.Count; ++j)
                    {
                        if (hands[i].fingertips[j].X != -1)
                        {
                            gBmp.FillEllipse(greenBrush, hands[i].fingertips[j].Y - 5,
                                             hands[i].fingertips[j].X - 5, 10, 10);
                        }
                    }
                }

                greenBrush.Dispose();
                yellowBrush.Dispose();
                gBmp.Dispose();
            }
        }
Beispiel #30
0
 /// <summary>
 /// Copy and create a new instance of PointFT.
 /// </summary>
 /// <param name="other">The PointFT to copy.</param>
 public PointsFingers(PointsFingers other)
 {
     this.X = other.X;
     this.Y = other.Y;
 }
Beispiel #31
0
 /// <summary>
 /// Calculates the smaller angle between two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the angle in radians.</returns>
 public static float angle(PointsFingers point1, PointsFingers point2)
 {
     return((float)Math.Acos((point1.X * point2.X + point1.Y * point2.Y) / (length(point1) * length(point2))));
 }
Beispiel #32
0
 /// <summary>
 /// Calculates the Euclidean distance between two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the distance between the points squared.</returns>
 public static float distanceEuclideanSquared(PointsFingers point1, PointsFingers point2)
 {
     return (point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y);
 }
Beispiel #33
0
 /// <summary>
 /// Calculate the number of points you have to cross to go from one point to another.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the distance between the points.</returns>
 public static int distance(PointsFingers point1, PointsFingers point2)
 {
     return Math.Abs(point1.X - point2.X) + Math.Abs(point1.Y - point2.Y);
 }
Beispiel #34
0
 /// <summary>
 /// Calculates the Euclidean distance between two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the distance between the points.</returns>
 public static float distanceEuclidean(PointsFingers point1, PointsFingers point2)
 {
     return (float)Math.Sqrt((point1.X - point2.X) * (point1.X - point2.X) + (point1.Y - point2.Y) * (point1.Y - point2.Y));
 }
Beispiel #35
0
 /// <summary>
 /// Adds a scalar to all the coordinates of the source point.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="value">The scalar to add.</param>
 /// <returns>Returs the sum.</returns>
 public static PointsFingers add(PointsFingers point1, int value)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X + value;
     sol.Y = point1.Y + value;
     return sol;
 }
Beispiel #36
0
 /// <summary>
 /// Returns the length of the source point.
 /// </summary>
 /// <returns>The length of the point.</returns>
 public static float length(PointsFingers point1)
 {
     return((float)Math.Sqrt(point1.X * point1.X + point1.Y * point1.Y));
 }
Beispiel #37
0
 /// <summary>
 /// Adds two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the sum.</returns>
 public static PointsFingers add(PointsFingers point1, PointsFingers point2)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X + point2.X;
     sol.Y = point1.Y + point2.Y;
     return sol;
 }
Beispiel #38
0
 /// <summary>
 /// Calculate the number of points you have to cross to go from one point to another.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the distance between the points.</returns>
 public static int distance(PointsFingers point1, PointsFingers point2)
 {
     return(Math.Abs(point1.X - point2.X) + Math.Abs(point1.Y - point2.Y));
 }
Beispiel #39
0
 /// <summary>
 /// Multiplies the source point by a scalar.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="value">The factor.</param>
 /// <returns>Returns the product.</returns>
 public static PointsFingers multiply(PointsFingers point1,int value)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X * value;
     sol.Y = point1.Y * value;
     return sol;
 }
Beispiel #40
0
 /// <summary>
 /// Returns the length of the source point.
 /// </summary>
 /// <returns>The length of the point.</returns>
 public static float length(PointsFingers point1)
 {
     return (float)Math.Sqrt(point1.X * point1.X + point1.Y * point1.Y);
 }
Beispiel #41
0
        private List <HandDetection> localizeHands(bool[][] valid)
        {
            int i, j, k;

            List <HandDetection> hands = new List <HandDetection>();

            List <PointsFingers> insidePoints  = new List <PointsFingers>();
            List <PointsFingers> contourPoints = new List <PointsFingers>();


            bool[][] contour = new bool[valid.Length][];
            for (i = 0; i < valid.Length; ++i)
            {
                contour[i] = new bool[valid[0].Length];
            }

            // Divide points in contour and inside points
            int count = 0;

            for (i = 1; i < valid.Length - 1; ++i)
            {
                for (j = 1; j < valid[i].Length - 1; ++j)
                {
                    if (valid[i][j])
                    {
                        // Count the number of valid adjacent points
                        count = this.numValidPixelAdjacent(ref i, ref j, ref valid);

                        if (count == 4) // Inside
                        {
                            insidePoints.Add(new PointsFingers(i, j));
                        }
                        else // Contour
                        {
                            contour[i][j] = true;
                            contourPoints.Add(new PointsFingers(i, j));
                        }
                    }
                }
            }

            // Create the sorted contour list, using the turtle algorithm
            for (i = 0; i < contourPoints.Count; ++i)
            {
                HandDetection hand = new HandDetection();

                // If it is a possible start point
                if (contour[contourPoints[i].X][contourPoints[i].Y])
                {
                    // Calculate the contour
                    hand.contour = CalculateFrontier(ref valid, contourPoints[i], ref contour);

                    // Check if the contour is big enough to be a hand
                    if (hand.contour.Count / (contourPoints.Count * 1.0f) > 0.20f &&
                        hand.contour.Count > settings.k)
                    {
                        // Calculate the container box
                        hand.calculateContainerBox(settings.containerBoxReduction);

                        // Add the hand to the list
                        hands.Add(hand);
                    }

                    // Don't look for more hands, if we reach the limit
                    if (hands.Count >= settings.maxTrackedHands)
                    {
                        break;
                    }
                }
            }

            // Allocate the inside points to the correct hand using its container box

            //List<int> belongingHands = new List<int>();
            for (i = 0; i < insidePoints.Count; ++i)
            {
                for (j = 0; j < hands.Count; ++j)
                {
                    if (hands[j].isPointInsideContainerBox(insidePoints[i]))
                    {
                        hands[j].inside.Add(insidePoints[i]);
                        //belongingHands.Add(j);
                    }
                }

                // A point can only belong to one hand, if not we don't take that point into account

                /*if (belongingHands.Count == 1)
                 * {
                 *  hands[belongingHands.ElementAt(0)].inside.Add(insidePoints[i]);
                 * }
                 * belongingHands.Clear();*/
            }

            // Find the center of the palm
            float min, max, distance = 0;

            for (i = 0; i < hands.Count; ++i)
            {
                max = float.MinValue;
                for (j = 0; j < hands[i].inside.Count; j += settings.findCenterInsideJump)
                {
                    min = float.MaxValue;
                    for (k = 0; k < hands[i].contour.Count; k += settings.findCenterInsideJump)
                    {
                        distance = PointsFingers.distanceEuclidean(hands[i].inside[j], hands[i].contour[k]);
                        if (!hands[i].isCircleInsideContainerBox(hands[i].inside[j], distance))
                        {
                            continue;
                        }
                        if (distance < min)
                        {
                            min = distance;
                        }
                        if (min < max)
                        {
                            break;
                        }
                    }

                    if (max < min && min != float.MaxValue)
                    {
                        max           = min;
                        hands[i].palm = hands[i].inside[j];
                    }
                }
            }

            // Find the fingertips
            PointsFingers p1, p2, p3, pAux, r1, r2;
            int           size;
            double        angle;
            int           jump;

            for (i = 0; i < hands.Count; ++i)
            {
                // Check if there is a point at the beginning to avoid checking the last ones of the list
                max  = hands[i].contour.Count;
                size = hands[i].contour.Count;
                jump = (int)(size * settings.fingertipFindJumpPerc);
                for (j = 0; j < settings.k; j += 1)
                {
                    p1 = hands[i].contour[(j - settings.k + size) % size];
                    p2 = hands[i].contour[j];
                    p3 = hands[i].contour[(j + settings.k) % size];
                    r1 = p1 - p2;
                    r2 = p3 - p2;

                    angle = PointsFingers.angle(r1, r2);

                    if (angle > 0 && angle < settings.theta)
                    {
                        pAux = p3 + ((p1 - p3) / 2);
                        if (PointsFingers.distanceEuclideanSquared(pAux, hands[i].palm) >
                            PointsFingers.distanceEuclideanSquared(hands[i].contour[j], hands[i].palm))
                        {
                            continue;
                        }

                        hands[i].fingertips.Add(hands[i].contour[j]);
                        max = hands[i].contour.Count + j - jump;
                        max = Math.Min(max, hands[i].contour.Count);
                        j  += jump;
                        break;
                    }
                }

                // Continue with the rest of the points
                for ( ; j < max; j += settings.findFingertipsJump)
                {
                    p1 = hands[i].contour[(j - settings.k + size) % size];
                    p2 = hands[i].contour[j];
                    p3 = hands[i].contour[(j + settings.k) % size];
                    r1 = p1 - p2;
                    r2 = p3 - p2;

                    angle = PointsFingers.angle(r1, r2);

                    if (angle > 0 && angle < settings.theta)
                    {
                        pAux = p3 + ((p1 - p3) / 2);
                        if (PointsFingers.distanceEuclideanSquared(pAux, hands[i].palm) >
                            PointsFingers.distanceEuclideanSquared(hands[i].contour[j], hands[i].palm))
                        {
                            continue;
                        }

                        hands[i].fingertips.Add(hands[i].contour[j]);
                        j += jump;
                    }
                }
            }

            return(hands);
        }
Beispiel #42
0
 /// <summary>
 /// Subtracts two points.
 /// </summary>
 /// <param name="point1">Minuend point.</param>
 /// <param name="point2">Subtrahend point.</param>
 /// <returns>Returns the difference .</returns>
 public static PointsFingers subtract(PointsFingers point1, PointsFingers point2)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X - point2.X;
     sol.Y = point1.Y - point2.Y;
     return sol;
 }
Beispiel #43
0
        public bool isCircleInsideContainerBox(PointsFingers p, float r)
        {
            if (leftUpperCorner.X > p.X - r)
            {
                return false;
            }
            if (rightDownCorner.X < p.X + r)
            {
                return false;
            }
            if (leftUpperCorner.Y > p.Y - r)
            {
                return false;
            }
            if (rightDownCorner.Y < p.Y + r)
            {
                return false;
            }

            return true;
        }
Beispiel #44
0
 /// <summary>
 /// Subtracts a scalar to all the coordinates of the source point.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="value">The scalar to substract.</param>
 /// <returns>Returs the difference.</returns>
 public static PointsFingers subtract(PointsFingers point1, int value)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X - value;
     sol.Y = point1.Y - value;
     return sol;
 }
Beispiel #45
0
 // Normalize in the interval [-1, 1] the given 3D point.
 // The Z value is in the inverval [-1, 0], being 0 the closest distance.
 private Coordinates3D transformTo3DCoord(PointsFingers p, int width, int height, int distance)
 {
     Coordinates3D v = new Coordinates3D();
     v.X = p.Y / (width * 1.0f) * 2 - 1;
     v.Y = (1 - p.X / (height * 1.0f)) * 2 - 1;
     v.Z = (distance - 400) / -7600.0f;
     return v;
 }
Beispiel #46
0
 /// <summary>
 /// Multiplies two points.
 /// </summary>
 /// <param name="point1">Source point.</param>
 /// <param name="point2">Source point.</param>
 /// <returns>Returns the product.</returns>
 public static PointsFingers operator *(PointsFingers point1, PointsFingers point2)
 {
     PointsFingers sol = new PointsFingers();
     sol.X = point1.X * point2.X;
     sol.Y = point1.Y * point2.Y;
     return sol;
 }
Beispiel #47
0
        // Calculate the contour box of the hand if it possible
        public bool calculateContainerBox(float reduction = 0)
        {
            if (contour != null && contour.Count > 0)
            {
                for (int j = 0; j < contour.Count; ++j)
                {
                    if (leftUpperCorner.X > contour[j].X)
                        leftUpperCorner.X = contour[j].X;

                    if (rightDownCorner.X < contour[j].X)
                        rightDownCorner.X = contour[j].X;

                    if (leftUpperCorner.Y > contour[j].Y)
                        leftUpperCorner.Y = contour[j].Y;

                    if (rightDownCorner.Y < contour[j].Y)
                        rightDownCorner.Y = contour[j].Y;
                }

                int incX = (int)((rightDownCorner.X - leftUpperCorner.X) * (reduction / 2));
                int incY = (int)((rightDownCorner.Y - leftUpperCorner.Y) * (reduction / 2));
                PointsFingers inc = new PointsFingers(incX, incY);
                leftUpperCorner = leftUpperCorner + inc;
                rightDownCorner = rightDownCorner + inc;

                return true;
            }
            else
            {
                return false;
            }
        }
Beispiel #48
0
        /*
         * This function calcute the border of a closed figure starting in one of the contour points.
         * The turtle algorithm is used.
         */
        private List<PointsFingers> CalculateFrontier(ref bool[][] valid, PointsFingers start, ref bool[][] contour)
        {
            List<PointsFingers> list = new List<PointsFingers>();
            PointsFingers last = new PointsFingers(-1, -1);
            PointsFingers current = new PointsFingers(start);
            int dir = 0;

            do
            {
                if (valid[current.X][current.Y])
                {
                    dir = (dir + 1) % 4;
                    if (current != last)
                    {
                        list.Add(new PointsFingers(current.X, current.Y));
                        last = new PointsFingers(current);
                        contour[current.X][current.Y] = false;
                    }
                }
                else
                {
                    dir = (dir + 4 - 1) % 4;
                }

                switch (dir)
                {
                    case 0: current.X += 1; break; // Down
                    case 1: current.Y += 1; break; // Right
                    case 2: current.X -= 1; break; // Up
                    case 3: current.Y -= 1; break; // Left
                }
            } while (current != start);

            return list;
        }