예제 #1
0
        public Template(Contour<Point> cp, double sourceArea)
        {
            this.sourceArea = sourceArea;
            startPoint = cp.ToArray()[0];
            contour = new Contour(cp);
            contour.Equalization(templateSize);
            contourNorma = contour.norm;
            autoCorr = contour.AutoCorrelation(true);

            CalcAutoCorrDescriptions();
        }
예제 #2
0
 public Template(SerializationInfo info, StreamingContext ctxt)
 {
     this.startPoint = (Point)info.GetValue("StartPoint", typeof(Point));
     this.preferredAngleNoMore90 = (bool)info.GetValue("PreferredAngleNoMore90", typeof(bool));
     this.autoCorrDescriptor1 = (int)info.GetValue("AutoCorrDescriptor1", typeof(int));
     this.autoCorrDescriptor2 = (int)info.GetValue("AutoCorrDescriptor2", typeof(int));
     this.autoCorrDescriptor3 = (int)info.GetValue("AutoCorrDescriptor3", typeof(int));
     this.autoCorrDescriptor4 = (int)info.GetValue("AutoCorrDescriptor4", typeof(int));
     this.contourNorma = (double)info.GetValue("ContourNorma", typeof(double));
     this.sourceArea = (double)info.GetValue("SourceArea", typeof(double));
     this.autoCorr = (Contour)info.GetValue("AutoCorrContour", typeof(Contour));
     this.contour = (Contour)info.GetValue("Contour", typeof(Contour));
 }
예제 #3
0
        /// <summary>
        /// Get the nearest templateClass for the refContour
        /// </summary>
        /// <param name="refContour">the contour wich class's is to be found</param>
        /// <param name="r">the area of the contour</param>
        /// <param name="classes">the list of the classes within to search</param>
        /// <returns>the nearest class or "not found"</returns>
        public static FoundTemplateDesc GetNearestClass(Contour<Point> refContour, Rectangle r, List<TemplateClass> classes, HandType handType)
        {
            contourClasses = classes;
            List<FoundTemplateDesc> foundedTemplates = new List<FoundTemplateDesc>();
            Template refTemp = new Template(refContour, r.Height * r.Width);

            foreach (TemplateClass tc in contourClasses)
            {
                if (tc.htype == handType)
                {
                    FoundTemplateDesc templateDesc = TemplateFinder.CompareTemplates(tc, refTemp);
                    if (templateDesc != null) foundedTemplates.Add(templateDesc);
                }

            }

            foundedTemplates = foundedTemplates.OrderBy(t => t.rate).ToList();

            return (foundedTemplates.Count == 0) ? null : foundedTemplates.First();
        }
예제 #4
0
 public Contour(Contour<Point> c)
     : this(c.ToArray(), 0, c.ToArray().Length)
 {
 }
예제 #5
0
        /// <summary>
        /// Normalized Scalar Product
        /// </summary>
        public Complex NormDot(Contour c)
        {
            var count = this.Count;
            double sumA = 0;
            double sumB = 0;
            double norm1 = 0;
            double norm2 = 0;
            for (int i = 0; i < count; i++)
            {
                var x1 = this[i];
                var x2 = c[i];
                sumA += x1.a * x2.a + x1.b * x2.b;
                sumB += x1.b * x2.a - x1.a * x2.b;
                norm1 += x1.NormSquare;
                norm2 += x2.NormSquare;
            }

            double k = 1d / Math.Sqrt(norm1 * norm2);
            return new Complex(sumA * k, sumB * k);
        }
예제 #6
0
 /// <summary>
 /// Intercorrelcation function (ICF)
 /// maxShift - max deviation (left+right)
 /// </summary>
 public Contour InterCorrelation(Contour c, int maxShift)
 {
     Contour result = new Contour(maxShift);
     int i = 0;
     int count = Count;
     while (i < maxShift / 2)
     {
         result.vc[i] = Dot(c, i);
         result.vc[maxShift - i - 1] = Dot(c, c.Count - i - 1);
         i++;
     }
     return result;
 }
예제 #7
0
        /// <summary>
        /// Intercorrelcation function (ICF)
        /// </summary>
        public Contour InterCorrelation(Contour c)
        {
            int count = Count;
            Contour result = new Contour(count);
            for (int i = 0; i < count; i++)
                result.vc[i] = Dot(c, i);

            return result;
        }
예제 #8
0
 public Complex DotProduct(Contour other)
 {
     return Contour.DotProduct(this, other);
 }
예제 #9
0
 public Complex DotProduct(Contour other)
 {
     return(Contour.DotProduct(this, other));
 }
예제 #10
0
        /// <summary>
        /// Autocorrelation function (ACF)
        /// </summary>
        public unsafe Contour AutoCorrelation(bool normalize)
        {
            int count = Count / 2;
            Contour result = new Contour(count);
            fixed (Complex* ptr = &result.vc[0])
            {
                Complex* p = ptr;
                double maxNormaSq = 0;
                for (int i = 0; i < count; i++)
                {
                    *p = Dot(this, i);
                    double normaSq = (*p).NormSquare;
                    if (normaSq > maxNormaSq)
                        maxNormaSq = normaSq;
                    p++;
                }
                if (normalize)
                {
                    maxNormaSq = Math.Sqrt(maxNormaSq);
                    p = ptr;
                    for (int i = 0; i < count; i++)
                    {
                        *p = new Complex((*p).a / maxNormaSq, (*p).b / maxNormaSq);
                        p++;
                    }
                }
            }

            return result;
        }
예제 #11
0
        public static Complex DotProduct(Contour c1, Contour c2)
        {
            Complex res = new Complex(0, 0);

            for (int i = 0; i < c1.vc.Length - 1; i++)
            {
                res += Complex.DotProduct(c1.vc[i], c2.vc[i]);
            }

            return res;
        }
예제 #12
0
        public static Complex ComputeNSP(Contour c1, Contour c2)
        {
            Complex res = new Complex(0, 0);

            res = Contour.DotProduct(c1, c2);
            res *= 1 / (c1.ComputeNorm() * c2.ComputeNorm());

            return res;
        }
예제 #13
0
 public void AddContour(Contour <Point> contour, double area)
 {
     this.templates.Add(new Template(contour, area));
 }
예제 #14
0
 public Contour(Contour <Point> c)
     : this(c.ToArray(), 0, c.ToArray().Length)
 {
 }
예제 #15
0
        /// <summary>
        /// find hands based on the informations provided by the skeleton
        /// </summary>
        /// <param name="skeleton">the skeleton provided by Kinect</param>
        /// <param name="depthFrame">the depthFrame</param>
        /// <returns>a handgesture as a string</returns>
        public string FindHandGesture(HandType handtype)
        {
            //reset the values for hand detection
            this.currentContour = null;
            this.depthImage = new Image<Gray, byte>(this.depthFrameWidth, this.depthFrameHeight);

            this.handJoint = KinectHelper.Instance.GetHandJoint(handtype, skeleton);
            float zhand = handJoint.Position.Z;
            JointType jointtype = (handtype == HandType.LEFT) ? JointType.HandLeft : JointType.HandRight;

            if (min < zhand && zhand < max && CheckOrientation(handtype))
            {
                //set the ROI around the hand
                Joint hand = skeleton.Joints[jointtype].ScaleTo((int)(this.depthFrameWidth * 1), (int)(this.depthFrameHeight * 1));
                PointF center = new PointF(hand.Position.X, hand.Position.Y);
                this.depthImage = new Image<Gray, byte>(this.depthFrameWidth, this.depthFrameHeight);
                depthImage.Bytes = GetEverythingBetween(min, max, depthFrame);
                recSize = new Size(75 - (int)(50 * (zhand - MinDepthDistance)), 90 - (int)(35.7 * (zhand - MinDepthDistance)));

                if (CheckRectangleIsInside(depthImageBoth.Width, depthImageBoth.Height, recSize, center))
                {
                    depthImage.ROI = new Rectangle((int)center.X - recSize.Width / 2, (int)center.Y - recSize.Height / 2, recSize.Width, recSize.Height);

                    if (!CheckForMovement(handtype))
                    {
                        //get the contour
                        ExtractContourAndHull(depthImage.Copy(), handtype);

                        //find the name of the gesture if there is one
                        if (this.currentContour != null)
                        {
                            FoundTemplateDesc result = TemplateFinder.GetNearestClass(this.currentContour, depthImage.ROI, this.templates, handtype);
                            if (result != null) return result.name.ToString();
                        }

                    }

                    if ((isLeftHandTracked == false && handtype == HandType.LEFT) || (isRightHandTracked == false && handtype == HandType.RIGHT))
                    {
                        if (handtype == HandType.RIGHT)
                        {
                            isRightHandTracked = true;
                        }
                        else
                        {
                            isLeftHandTracked = true;
                        }
                    }
                }
            }
            else
            {
                if (handtype == HandType.LEFT)
                {
                    isLeftHandTracked = false;
                }
                else
                {
                    isRightHandTracked = false;
                }
            }
            return null;
        }
예제 #16
0
        /// <summary>
        /// Scalar product
        /// </summary>
        public unsafe Complex Dot(Contour c, int shift)
        {
            var count = Count;
            double sumA = 0;
            double sumB = 0;
            fixed (Complex* ptr1 = &vc[0])
            fixed (Complex* ptr2 = &c.vc[shift])
            fixed (Complex* ptr22 = &c.vc[0])
            fixed (Complex* ptr3 = &c.vc[c.Count - 1])
            {
                Complex* p1 = ptr1;
                Complex* p2 = ptr2;
                for (int i = 0; i < count; i++)
                {
                    Complex x1 = *p1;
                    Complex x2 = *p2;
                    sumA += x1.a * x2.a + x1.b * x2.b;
                    sumB += x1.b * x2.a - x1.a * x2.b;

                    p1++;
                    if (p2 == ptr3)
                        p2 = ptr22;
                    else
                        p2++;
                }
            }
            return new Complex(sumA, sumB);
        }
예제 #17
0
        /// <summary>
        /// extract the the contour and the hull of one hand
        /// </summary>
        /// <param name="depthImage">the depth image to manipulate</param>
        private void ExtractContourAndHull(Image<Gray, byte> depthImage, HandType handType)
        {
            using (MemStorage storage = new MemStorage())
            {
                Contour<Point> contours = depthImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage);
                Contour<Point> biggestContour = null;

                Double Result1 = 0;
                Double Result2 = 0;
                while (contours != null)
                {
                    Result1 = contours.Area;
                    if (Result1 > Result2)
                    {
                        Result2 = Result1;
                        biggestContour = contours;
                    }
                    contours = contours.HNext;
                }

                if (biggestContour != null)
                {
                    this.currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage);

                    //smooth contour
                    Point[] pc = currentContour.ToArray();
                    Point p;
                    for (int i = 2; i < pc.Length - 2; i++)
                    {
                        //triangular smooth
                        int X = (pc[i - 2].X + 2 * pc[i - 1].X + 3 * pc[i].X + 2 * pc[i + 1].X + pc[i + 2].X) / 9;
                        int Y = (pc[i - 2].Y + 2 * pc[i - 1].Y + 3 * pc[i].Y + 2 * pc[i + 1].Y + pc[i + 2].Y) / 9;

                        p = new Point(X, Y);
                        currentContour.RemoveAt(i);
                        currentContour.Insert(i, p);
                    }

                    //if (handType == HandType.LEFT)
                    //{
                    //    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE);
                    //}
                    //else
                    //{
                    //    hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                    //}

                    //box = biggestContour.GetMinAreaRect();
                    //CircleF boxCircle = new CircleF(box.center, 5f);
                    //PointF[] points = box.GetVertices();

                    //handRect = box.MinAreaRect();

                    //Point[] ps = new Point[points.Length];
                    //for (int i = 0; i < points.Length; i++)
                    //    ps[i] = new Point((int)points[i].X, (int)points[i].Y);

                    //filteredHull = new Seq<Point>(storage);
                    //for (int i = 0; i < hull.Total; i++)
                    //{
                    //    if (Math.Sqrt(Math.Pow(hull[i].X - hull[i + 1].X, 2) + Math.Pow(hull[i].Y - hull[i + 1].Y, 2)) > box.size.Width / 10)
                    //    {
                    //        filteredHull.Push(hull[i]);
                    //    }
                    //}
                }
            }
        }
예제 #18
0
 public void AddContour(Contour<Point> contour, double area)
 {
     this.templates.Add(new Template(contour, area));
 }