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(); }
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)); }
/// <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(); }
public Contour(Contour<Point> c) : this(c.ToArray(), 0, c.ToArray().Length) { }
/// <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); }
/// <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; }
/// <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; }
public Complex DotProduct(Contour other) { return Contour.DotProduct(this, other); }
public Complex DotProduct(Contour other) { return(Contour.DotProduct(this, other)); }
/// <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; }
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; }
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; }
public void AddContour(Contour <Point> contour, double area) { this.templates.Add(new Template(contour, area)); }
public Contour(Contour <Point> c) : this(c.ToArray(), 0, c.ToArray().Length) { }
/// <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; }
/// <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); }
/// <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]); // } //} } } }
public void AddContour(Contour<Point> contour, double area) { this.templates.Add(new Template(contour, area)); }