// chiết xuất ra đường viền bao bọc bàn tay private void ExtractContourAndHull(Image <Gray, byte> skin) { { // tìm đường viền bao bọc bàn tay Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); // biggest contour chính là đường biểu thị đường bao bọc bàn tay Contour <Point> biggestContour = null; // class contour() đê taọ đường viền, sử dụng bộ nhớ storage 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) { // class ApproxPoly(Double, MemStorage) xấp xỉ 1 đường cong và trả về kết quả xấp xỉ Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); // dung màu xanh là cây để biểu diễn đường viền bao tay currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); 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); } currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } }
private List <MCvBox2D> GetOrderedInsideBoxes(List <MCvBox2D> allFoundRectangles, int startIndex) { PointF[] vertices = m_OuterBox.GetVertices(); List <MCvBox2D> insideBoxes = new List <MCvBox2D>(m_CellInfos.Length); // The first three boxes are the outer boxes. Hence we skip them. for (int i = startIndex; i < allFoundRectangles.Count; i++) { if (PolygonContains(vertices, allFoundRectangles[i].center)) { insideBoxes.Add(allFoundRectangles[i]); } } if (insideBoxes.Count != m_CellInfos.Length) { return(null); } insideBoxes.Sort(delegate(MCvBox2D box1, MCvBox2D box2) { if (Math.Abs(box1.center.Y - box2.center.Y) < box1.size.Height / 2) { // the x location determines the order return(box1.center.X.CompareTo(box2.center.X)); } else { // the x location determines the order return(box1.center.Y.CompareTo(box2.center.Y)); } }); return(insideBoxes); }
private void GetContour_Hull(Image <Gray, byte> skin) { using (MemStorage Mem = new MemStorage()) { Contour <Point> Contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, Mem); Contour <Point> Maxium = null; Double area_cur = 0, area_max = 0; while (Contours != null) { area_cur = Contours.Area; if (area_cur > area_max) { area_max = area_cur; Maxium = Contours; } Contours = Contours.HNext; } if (Maxium != null) { Contour <Point> CurrentContour = Maxium.ApproxPoly(Maxium.Perimeter * 0.0025, Mem); Cam_Income.Draw(CurrentContour, new Bgr(Color.LimeGreen), 2); Maxium = CurrentContour; hull = Maxium.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = Maxium.GetMinAreaRect(); PointF[] points = box.GetVertices(); //box.center.Y += 30; judge.X = (float)(box.center.X - (box.size.Width - box.center.X) * 0.20); judge.Y = (float)(box.center.Y + (box.size.Height - box.center.Y) * 0.40); //dif = box.center.Y + (box.size.Height - box.center.Y) * 0.30; Point[] P_To_int = new Point[points.Length]; for (int i = 0; i < points.Length; i++) { P_To_int[i] = new Point((int)points[i].X, (int)points[i].Y); } Cam_Income.DrawPolyline(hull.ToArray(), true, new Bgr(Color.Pink), 2); Cam_Income.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(Color.DarkOrchid), 5); Cam_Income.Draw(new CircleF(new PointF(judge.X, judge.Y), 3), new Bgr(Color.Cyan), 5); FilterHull = new Seq <Point>(Mem); for (int i = 0; i < hull.Total - 1; 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) { FilterHull.Push(hull[i]); } } Defects = Maxium.GetConvexityDefacts(Mem, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); DefectArray = Defects.ToArray(); Get_Result(); //MessageBox.Show(DefectArray.Count().ToString()); } } }
/// <summary> /// Use camshift to track the feature /// </summary> /// <param name="observedFeatures">The feature found from the observed image</param> /// <param name="initRegion">The predicted location of the model in the observed image. If not known, use MCvBox2D.Empty as default</param> /// <param name="priorMask">The mask that should be the same size as the observed image. Contains a priori value of the probability a match can be found. If you are not sure, pass an image fills with 1.0s</param> /// <returns>If a match is found, the homography projection matrix is returned. Otherwise null is returned</returns> public HomographyMatrix CamShiftTrack(SURFFeature[] observedFeatures, MCvBox2D initRegion, Image <Gray, Single> priorMask) { using (Image <Gray, Single> matchMask = new Image <Gray, Single>(priorMask.Size)) { #region get the list of matched point on the observed image Single[, ,] matchMaskData = matchMask.Data; //Compute the matched features MatchedSURFFeature[] matchedFeature = _matcher.MatchFeature(observedFeatures, 2, 20); matchedFeature = VoteForUniqueness(matchedFeature, 0.8); foreach (MatchedSURFFeature f in matchedFeature) { PointF p = f.ObservedFeature.Point.pt; matchMaskData[(int)p.Y, (int)p.X, 0] = 1.0f / (float)f.SimilarFeatures[0].Distance; } #endregion Rectangle startRegion; if (initRegion.Equals(MCvBox2D.Empty)) { startRegion = matchMask.ROI; } else { startRegion = PointCollection.BoundingRectangle(initRegion.GetVertices()); if (startRegion.IntersectsWith(matchMask.ROI)) { startRegion.Intersect(matchMask.ROI); } } CvInvoke.cvMul(matchMask.Ptr, priorMask.Ptr, matchMask.Ptr, 1.0); MCvConnectedComp comp; MCvBox2D currentRegion; //Updates the current location CvInvoke.cvCamShift(matchMask.Ptr, startRegion, new MCvTermCriteria(10, 1.0e-8), out comp, out currentRegion); #region find the SURF features that belongs to the current Region MatchedSURFFeature[] featuesInCurrentRegion; using (MemStorage stor = new MemStorage()) { Contour <System.Drawing.PointF> contour = new Contour <PointF>(stor); contour.PushMulti(currentRegion.GetVertices(), Emgu.CV.CvEnum.BACK_OR_FRONT.BACK); CvInvoke.cvBoundingRect(contour.Ptr, 1); //this is required before calling the InContour function featuesInCurrentRegion = Array.FindAll(matchedFeature, delegate(MatchedSURFFeature f) { return(contour.InContour(f.ObservedFeature.Point.pt) >= 0); }); } #endregion return(GetHomographyMatrixFromMatchedFeatures(VoteForSizeAndOrientation(featuesInCurrentRegion, 1.5, 20))); } }
/// <summary> /// Use camshift to track the feature /// </summary> /// <param name="observedFeatures">The feature found from the observed image</param> /// <param name="initRegion">The predicted location of the model in the observed image. If not known, use MCvBox2D.Empty as default</param> /// <param name="priorMask">The mask that should be the same size as the observed image. Contains a priori value of the probability a match can be found. If you are not sure, pass an image fills with 1.0s</param> /// <returns>If a match is found, the homography projection matrix is returned. Otherwise null is returned</returns> public HomographyMatrix CamShiftTrack(SURFFeature[] observedFeatures, MCvBox2D initRegion, Image<Gray, Single> priorMask) { using (Image<Gray, Single> matchMask = new Image<Gray, Single>(priorMask.Size)) { #region get the list of matched point on the observed image Single[, ,] matchMaskData = matchMask.Data; //Compute the matched features MatchedSURFFeature[] matchedFeature = _matcher.MatchFeature(observedFeatures, 2, 20); matchedFeature = VoteForUniqueness(matchedFeature, 0.8); foreach (MatchedSURFFeature f in matchedFeature) { PointF p = f.ObservedFeature.Point.pt; matchMaskData[(int)p.Y, (int)p.X, 0] = 1.0f / (float) f.SimilarFeatures[0].Distance; } #endregion Rectangle startRegion; if (initRegion.Equals(MCvBox2D.Empty)) startRegion = matchMask.ROI; else { startRegion = PointCollection.BoundingRectangle(initRegion.GetVertices()); if (startRegion.IntersectsWith(matchMask.ROI)) startRegion.Intersect(matchMask.ROI); } CvInvoke.cvMul(matchMask.Ptr, priorMask.Ptr, matchMask.Ptr, 1.0); MCvConnectedComp comp; MCvBox2D currentRegion; //Updates the current location CvInvoke.cvCamShift(matchMask.Ptr, startRegion, new MCvTermCriteria(10, 1.0e-8), out comp, out currentRegion); #region find the SURF features that belongs to the current Region MatchedSURFFeature[] featuesInCurrentRegion; using (MemStorage stor = new MemStorage()) { Contour<System.Drawing.PointF> contour = new Contour<PointF>(stor); contour.PushMulti(currentRegion.GetVertices(), Emgu.CV.CvEnum.BACK_OR_FRONT.BACK); CvInvoke.cvBoundingRect(contour.Ptr, 1); //this is required before calling the InContour function featuesInCurrentRegion = Array.FindAll(matchedFeature, delegate(MatchedSURFFeature f) { return contour.InContour(f.ObservedFeature.Point.pt) >= 0; }); } #endregion return GetHomographyMatrixFromMatchedFeatures(VoteForSizeAndOrientation(featuesInCurrentRegion, 1.5, 20 )); } }
private Polygon MCvBox2D2Polygon(MCvBox2D box) { System.Windows.Media.PointCollection polyPoints = new System.Windows.Media.PointCollection(); foreach (var p in box.GetVertices()) { polyPoints.Add(new System.Windows.Point(p.X, p.Y)); } Polygon poly = new Polygon(); poly.Points = polyPoints; return(poly); }
void ExtractContourAndHull(Image <Gray, Byte> skin) { Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST); 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) { Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); 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); } currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); PointF center; float radius; filterredHull = 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) { filterredHull.Push(hull[i]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } }
public static RectangleF GetBoundingRectangleF(this MCvBox2D cvRotatedBox2D) { List <PointF> verticesList = new List <PointF>(cvRotatedBox2D.GetVertices()); float verticesMinX = verticesList.Min(ptf => ptf.X); float verticesMinY = verticesList.Min(ptf => ptf.Y); float verticesMaxX = verticesList.Max(ptf => ptf.X); float verticesMaxY = verticesList.Max(ptf => ptf.Y); RectangleF resRect = new RectangleF(verticesMinX, verticesMinY, verticesMaxX - verticesMinX, verticesMaxY - verticesMinY); return(resRect); }
/// <summary> /// Returns the end points of the major and minor axes of an ellipse. /// </summary> /// <param name="ellipse"></param> /// <returns></returns> public static PointF[] EllipseAxes(MCvBox2D ellipse) { var vertices = ellipse.GetVertices(); var midPoints = new PointF[vertices.Length]; for (int i = 0; i < midPoints.Length; i++) { var p1 = vertices[i]; var p2 = vertices[(i + 1) % vertices.Length]; var mid = new PointF((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2); // Correct the bug in the angle of the ellipse in OpenCV. midPoints[i] = Rotate(mid, ellipse.center, Math.PI / 2); } return(midPoints); }
private void DrawHand(MCvBox2D rect, Image<Bgr, Byte> image, HandEnum handEnum) { System.Drawing.Point[] points = rect.GetVertices().Select(x => x.ToPoint()).ToArray(); DrawPoly(points, image, new MCvScalar(0, 0, 255)); Point center = rect.center.ToPoint(); DrawPoint(image, center, new MCvScalar(255, 0, 0)); if (handEnum == HandEnum.Right) { RightHandCenter = center; } if (handEnum == HandEnum.Left) { LeftHandCenter = center; } if (handEnum == HandEnum.Intersect) { RightHandCenter = center; } }
// Extrait la "coque" du contour et les verticles afin de pouvoir calculer plus tard le nombre de doigts détectés // Ce code vient en partie de ce projet : https://www.youtube.com/watch?v=Fjj9gqTCTfc public void ExtractHull() { try { // Récupère la "coque" du plus grand contour ainsi que le rectangle qui l'englobe hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); // Récupère les vertexes de la box PointF[] points = box.GetVertices(); // On va créer un tableau de "Point" avec tous les points trouvés par "GetVerticles" 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); } // Dessine la "coque" (qui entoure tous les verticles) en rouge sur l'image traitée imgProc.DrawPolyline(hull.ToArray(), true, new Bgr(Color.Red), 2); // Dessine un cercle bleu au centre de la box imgProc.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 5), new Bgr(Color.Blue), 2); // Va filtrer les points de la "coque" afin de ne garder que ceux qui sont vraiment utiles filteredHull = new Seq <Point>(hullStorage); 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]); } } defects = biggestContour.GetConvexityDefacts(hullStorage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } catch (Exception ex) { return; } }
public static FeatureVector ExtractFeatures(Image<Gray, byte> skin, Image<Bgr, Byte> imagen) { Contour<Point> currentContour = null; Contour<Point> biggestContour = null; using (MemStorage storage = new MemStorage()) { #region extractContourAndHull Contour<Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); 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) { currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); imagen.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); 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); imagen.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); // imagen.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); // PointF center; // float radius; 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } #endregion #region find palm center(needs change) searchRadius = 6; contourReduction = 3; //this.result = null; DetectarCentroPalma(biggestContour.ToList<Point>(), obtenerListaCandidatos(box)); PointF punto = new PointF(405, 380); Point punt = new Point(405, 380); CircleF centerCircle = new CircleF(punto, 5f); //CircleF centerCircle = new CircleF(result.Location, 5f); imagen.Draw(centerCircle, new Bgr(Color.Brown), 3); /* for (int i = 0; i < defects.Total; i++) { LineSegment2D lineaDedoCentro = new LineSegment2D(defectArray[i].StartPoint, punt); imagen.Draw(lineaDedoCentro, new Bgr(Color.Green), 2); } * */ #endregion List<PointF> fingertips = defectsDrawing(imagen, ref punt); #region create feature vector List<PointF> newFingertips = ordenarFingertips(fingertips); List<float> angles = calculateFingerAngles(fingertips, punto); FeatureVector vector = new FeatureVector(newFingertips, angles, punto, 5); //MessageBox.Show("Done"); // frmPruebaDatos datos = new frmPruebaDatos(vector); // datos.Show(); #endregion return vector; }
private void ExtractContourAndHull(Image<Gray, byte> skin) { using (MemStorage storage = new MemStorage()) { Contour<Point> contours = skin.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) { // currentFrame.Draw(biggestContour, new Bgr(Color.Black), 2); Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); //currentFrame.Draw(currentContour, new Bgr(Color.Red), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); handRect = box.MinAreaRect(); //int xx = (handRect.Width) / 2; //int yy = (handRect.Height) / 2; currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1); // currentFrame.Draw(new CircleF(new PointF(xx, yy), 3), new Bgr(200, 125, 75), 2); 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); currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); // currentFrame.Draw(new CircleF(new PointF(handRect.center.X, handRect.center.Y), 3), new Bgr(200, 125, 75), 2); //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr); //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3); // PointF center; // float radius; //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out center, out radius); //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2); //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2); //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2); //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2); 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } MCvMoments moment = new MCvMoments(); // a new MCvMoments object try { moment = biggestContour.GetMoments(); // Moments of biggestContour } catch (NullReferenceException) { } int fingerNum = 0; CvInvoke.cvMoments(biggestContour, ref moment, 0); double m_00 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 0); double m_10 = CvInvoke.cvGetSpatialMoment(ref moment, 1, 0); double m_01 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 1); int current_X = Convert.ToInt32(m_10 / m_00) / 10; // X location of centre of contour int current_Y = Convert.ToInt32(m_01 / m_00) / 10; // Y location of center of contour if (fingerNum == 1 || fingerNum == 0 || blue == 6) { Cursor.Position = new Point(current_X * 10, current_Y * 10); } //Leave the cursor where it was and Do mouse click, if finger count >= 3 } }
//::::::::::::Method to calculate the convex hull::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: public List<object> HandConvexHull(Image<Gray, Byte> frame, Rectangle Roi) { List<object> ListReturn = new List<object>(); Image<Gray, Byte> BinaryImage; //PointF centerPalm; BinaryImage = frame.Copy(Roi); BinaryImage = openingOperation(BinaryImage); BinaryImage = closeOperation(BinaryImage); BinaryImage.Save(path1 + numFrames.ToString() + ".png"); BinaryImage = binaryNiBlack(BinaryImage); //naryImage = binaryThresholdNiBlack(BinaryImage); // using (MemStorage storage = new MemStorage()) { Double result1 = 0; Double result2 = 0; Contour<System.Drawing.Point> contours = BinaryImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); Contour<System.Drawing.Point> biggestContour = null; while (contours != null) { result1 = contours.Area; if (result1 > result2) { result2 = result1; biggestContour = contours; } contours = contours.HNext; } if (biggestContour != null) { Contour<System.Drawing.Point> concurrentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); biggestContour = concurrentContour; Hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE); defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE); defectsArray = defects.ToArray(); box = biggestContour.GetMinAreaRect(); points = box.GetVertices(); contourArea = result2; contourPerimeter = biggestContour.Perimeter; convexHullArea = Hull.Area; convexHullPerimeter = Hull.Perimeter; BinaryImage.Draw(Hull, new Gray(155), 1); //ABinaryImage.Save(path1 + "ConvexHull_" + numFrames.ToString() + ".png"); ListReturn = GetFingersHand(BinaryImage); ListReturn.Add(contourPerimeter); ListReturn.Add(contourArea); ListReturn.Add(convexHullPerimeter); ListReturn.Add(convexHullArea); } } numFrames++; return ListReturn; }//end HandConvexHull
// chi?t xu?t ra du?ng vi?n bao b?c bàn tay private void ExtractContourAndHull(Image <Gray, byte> skin) { { // tìm du?ng vi?n bao b?c bàn tay Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); // biggest contour chính là du?ng bi?u th? du?ng bao b?c bàn tay Contour <Point> biggestContour = null; // class contour() dê ta? du?ng vi?n s? d?ng b? nh? storage 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) { // class ApproxPoly(Double, MemStorage) x?p x? 1 du?ng cong và tr? v? k?t qu? x?p x? Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); // dung màu xanh là cây d? bi?u di?n du?ng vi?n bao tay currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); /* hi?n th? toàn b? khung chua bàn tay khi s? d?ng 2 câu l?nh sau * -handRect = box.MinAreaRect(); * -currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1);*/ 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); } currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); PointF center; float radius; #region v? ellip gi?i h?n // v? du?ng ellip gi?i h?n bao quanh khi s? d?ng nh?ng câu l?nh du?i dây (2 câu l?nh s? ra 1 màu khác nhau) //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr); //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3); //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out center, out radius); //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2); //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2); //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2); //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2); #endregion 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } }
private void ExtractContourAndHull(Image<Gray, byte> skin) { using (MemStorage storage = new MemStorage()) { Contour<Point> contours = skin.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) { //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2); Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); mv = biggestContour.GetMoments(); CvInvoke.cvMoments(biggestContour,ref mv, 1); double m00 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 0) ; double m10 = CvInvoke.cvGetSpatialMoment(ref mv, 1, 0) ; double m01 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 1) ; if (m00 != 0) { // calculate center int xCenter = (int) Math.Round(m10/m00)*2; //scale = 2 int yCenter = (int) Math.Round(m01/m00)*2; cogPt.X =xCenter; cogPt.Y =yCenter; } double m11 = CvInvoke.cvGetCentralMoment(ref mv, 1, 1); double m20 = CvInvoke.cvGetCentralMoment(ref mv, 2, 0); double m02 = CvInvoke.cvGetCentralMoment(ref mv, 0, 2); contourAxisAngle = calculateTilt(m11, m20, m02); 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); currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } }
private void ExtractDoor(NiFile model, Matrix4 worldMatrix, int fixtureid) { // take everything that is under a doorX node and use it for the hull... if (model == null) { return; } var doorVertices = new Dictionary <string, List <Vector3> >(); // find all trimeshs and tristrips foreach (var obj in model.ObjectsByRef.Values) { var avNode = obj as NiAVObject; if (avNode == null) { continue; } if (!IsMatched(avNode, new[] { "visible", "collidee", "collide" })) { continue; } var doorName = FindMatchRegex(avNode, new[] { DoorRegex }); if (doorName == string.Empty) { continue; } Vector3[] vertices = null; Triangle[] triangles = null; TryExtractTriShape(obj, worldMatrix, false, false, ref vertices, ref triangles); if (vertices == null) { TryExtractTriStrips(obj, worldMatrix, false, false, ref vertices, ref triangles); } if (vertices == null) { continue; } if (!doorVertices.ContainsKey(doorName)) { doorVertices.Add(doorName, new List <Vector3>()); } doorVertices[doorName].AddRange(vertices); } foreach (var key in doorVertices.Keys) { float hullMinZ = float.MaxValue; float hullMaxZ = float.MinValue; var verts = doorVertices[key].ToArray(); var pts = new List <PointF>(); foreach (Vector3 vert in verts) { hullMinZ = Math.Min(vert.Z, hullMinZ); hullMaxZ = Math.Max(vert.Z, hullMaxZ); pts.Add(new PointF(vert.X, vert.Y)); } MCvBox2D box = PointCollection.MinAreaRect(pts.ToArray()); float maxSize = box.size.Width; maxSize = Math.Max(maxSize, box.size.Height); maxSize = Math.Max(maxSize, hullMaxZ - hullMinZ); // There are some weird door ids in e.g. Jordheim (z120): "door01:0" e.g. -- how do they translate to IDs? var doorID = Regex.Match(key.Replace(":", ""), "([0-9]+)").Groups[1].Value; var heading = ((box.angle + (box.size.Width < box.size.Height ? 0.0 : 90.0 + 90.0)) * DEGREES_TO_HEADING) % 0x1000; if (heading < 0) { heading += 0x1000; } DoorWriter.WriteDoor(Zone.ID * 1000000 + fixtureid * 100 + int.Parse(doorID), model.FileName, (int)box.center.X, (int)box.center.Y, (int)hullMinZ, (int)heading, (int)maxSize); // Make sure we have a min of 20f for doors on width/height box.size.Width = Math.Max(20f, box.size.Width); box.size.Height = Math.Max(20f, box.size.Height); // Make sure the door touches the ground... hullMinZ -= 16.0f; var boxVertices = box.GetVertices(); GeomSetWriter.WriteConvexVolume(boxVertices.Length, hullMinZ, hullMaxZ, CEM.GeomSetWriter.eAreas.Door); foreach (var vert in boxVertices) { GeomSetWriter.WriteConvexVolumeVertex(new Vector3(vert.X, vert.Y, hullMinZ)); // debug } } }
public static List<PointF> obtenerListaCandidatos(MCvBox2D box) { PointF[] points = box.GetVertices(); float p1 = points[0].X; float p2 = points[0].Y; float p3 = points[1].X; float p4 = points[1].Y; float p5 = points[2].X; float p6 = points[2].Y; float p7 = points[3].X; float p8 = points[3].Y; float[] equises = new float[] { p1,p3,p5,p7 }; float[] yes = new float[] { p2,p4,p6,p8 }; float minimo = p1; float maximo = p1; foreach (float i in equises) { if (i < minimo) { minimo = i; } if (i > maximo) { maximo = i; } } float minimoY = p2; float maximoY = p2; foreach (float i in yes) { if (i < minimoY) { minimoY = i; } if (i > maximoY) { maximoY = i; } } PointF vertice1 = new PointF(minimo, minimoY); PointF vertice2 = new PointF(maximo, maximoY); List<PointF> listaPuntos = new List<PointF>(); for (float i = vertice1.X + 1; i < vertice2.X; i = i + 4) { for (float j = vertice1.Y - 1; j < vertice2.Y; j = j + 4) { PointF punto = new PointF(i, j); listaPuntos.Add(punto); } } return listaPuntos; }
private void ExtractContourAndHull(Image <Gray, byte> skin) { using (MemStorage storage = new MemStorage()) { Contour <Point> contours = skin.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) { //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2); Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); mv = biggestContour.GetMoments(); CvInvoke.cvMoments(biggestContour, ref mv, 1); double m00 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 0); double m10 = CvInvoke.cvGetSpatialMoment(ref mv, 1, 0); double m01 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 1); if (m00 != 0) // calculate center { int xCenter = (int)Math.Round(m10 / m00) * 2; //scale = 2 int yCenter = (int)Math.Round(m01 / m00) * 2; cogPt.X = xCenter; cogPt.Y = yCenter; } double m11 = CvInvoke.cvGetCentralMoment(ref mv, 1, 1); double m20 = CvInvoke.cvGetCentralMoment(ref mv, 2, 0); double m02 = CvInvoke.cvGetCentralMoment(ref mv, 0, 2); contourAxisAngle = calculateTilt(m11, m20, m02); 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); } currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); PointF center; float radius; 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } }
public static float GetTrueArea(this MCvBox2D rec) { PointF[] pl = rec.GetVertices(); return(pl[0].DistanceTo(pl[1]) * pl[1].DistanceTo(pl[2])); }
private unsafe void ProcessImage(ref Image <Bgr, byte> img) { Image <Gray, byte> gray_image = img.Convert <Gray, byte>(); grayImg = gray_image; binaryImg = gray_image.ThresholdBinaryInv(new Gray(200), new Gray(255)); //Find contours with no holes try CV_RETR_EXTERNAL to find holes IntPtr Dyncontour = new IntPtr();//存放检测到的图像块的首地址 IntPtr Dynstorage = CvInvoke.cvCreateMemStorage(0); int n = CvInvoke.cvFindContours(binaryImg.Ptr, Dynstorage, ref Dyncontour, sizeof(MCvContour), Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_TREE, Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, new Point(0, 0)); Seq <Point> DyncontourTemp1 = new Seq <Point>(Dyncontour, null);//方便对IntPtr类型进行操作 Seq <Point> DyncontourTemp = DyncontourTemp1; List <MCvBox2D> rectList = new List <MCvBox2D>(); for (; DyncontourTemp != null && DyncontourTemp.Ptr.ToInt32() != 0; DyncontourTemp = DyncontourTemp.HNext) { CvInvoke.cvDrawContours(image, DyncontourTemp, new MCvScalar(255, 0, 0), new MCvScalar(0, 255, 0), 10, 1, Emgu.CV.CvEnum.LINE_TYPE.FOUR_CONNECTED, new Point(0, 0)); PointF[] rect1 = DyncontourTemp.GetMinAreaRect().GetVertices(); rectList.Add(DyncontourTemp.GetMinAreaRect()); var pointfSeq = from p in rect1 select new Point((int)p.X, (int)p.Y); Point[] points = pointfSeq.ToArray(); for (int j = 0; j < 4; j++) { CvInvoke.cvLine(image, points[j], points[(j + 1) % 4], new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); } //CvInvoke.cvNamedWindow("main"); } for (int i = 0; i < rectList.Count(); i++) { MCvBox2D rect = rectList[i]; PointF[] pl = rect.GetVertices(); var points = from p in pl orderby p.Y ascending select p; pl = points.ToArray(); PointF startP = pl[0]; PointF shortP = pl[1]; PointF longP = pl[2]; if (pl[1].DistanceTo(startP) > pl[2].DistanceTo(startP)) { shortP = pl[2]; longP = pl[1]; } float longDis = longP.DistanceTo(startP); if (longDis < minLength) { continue; } float shortDis = shortP.DistanceTo(startP); float longslope = Math.Abs(longP.X - startP.X) / longDis; float min = 9999; PointF ap1 = new PointF(); PointF ap2 = new PointF(); if (longslope < 0.707)//vert { for (int y = begin; y < Convert.ToInt32(Math.Abs(longP.Y - startP.Y)) && Math.Abs(y) < width; y++) { PointF p1 = InterPolateP(startP, longP, y / Math.Abs(longP.Y - startP.Y)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } else { for (int X = begin; X < Convert.ToInt32(Math.Abs(longP.X - startP.X)) && Math.Abs(X) < width; X++) { PointF p1 = InterPolateP(startP, longP, X / Math.Abs(longP.X - startP.X)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } CvInvoke.cvLine(image, ap1.ToPoint(), ap2.ToPoint(), new MCvScalar(0, 0, 255), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); } //CvInvoke.cvShowImage("main", tempImage); //image = binaryImg.Convert<Bgr, Byte>(); //Bitmap bmp = image.ToBitmap(); //using (Graphics g = Graphics.FromImage(bmp)) //{ // List<Rectangle> recList = new List<Rectangle>(); // double max_area = 0; // for (int i = 0; contours != null; contours = contours.HNext) // { // if ((contours.Area > Math.Pow(25, 2)) && (contours.Area < Math.Pow(300, 2))) // { // // Console.WriteLine(contours.Area); // Seq<Point> seq = contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); // var pointfSeq = // from p in seq // select new PointF(p.X, p.Y); // //max_area = contours.Area; // // MCvBox2D ellp = CvInvoke.cvFitEllipse2(seq.Ptr); // MCvBox2D ellp = contours.GetMinAreaRect(); // //g.DrawPolygon(new Pen(Brushes.Red, 2), contours.ToArray()); // //Ellipse elps = PointCollection.EllipseLeastSquareFitting(pointfSeq.ToArray()); // g.TranslateTransform(ellp.center.X, ellp.center.Y); // g.RotateTransform(ellp.angle); // g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // -ellp.MinAreaRect().Height / 2, // ellp.MinAreaRect().Width, // ellp.MinAreaRect().Height); // g.RotateTransform(-ellp.angle); // g.DrawRectangle(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // -ellp.MinAreaRect().Height / 2, // ellp.MinAreaRect().Width, // ellp.MinAreaRect().Height); // // g.DrawRectangle(new Pen(Brushes.Red, 2), -elps.MCvBox2D.MinAreaRect().Width / 2, -elps.MCvBox2D.MinAreaRect().Height / 2, elps.MCvBox2D.MinAreaRect().Width, elps.MCvBox2D.MinAreaRect().Height); // //g.DrawEllipse(new Pen(Brushes.Red, 2), -ellp.MinAreaRect().Width / 2, // // -ellp.MinAreaRect().Height / 2, // // ellp.MinAreaRect().Width, // // ellp.MinAreaRect().Height); // g.ResetTransform(); // // break; // } // } //} //imageBox1.Image = new Image<Bgr, byte>(bmp); }
private MCvBox2D SplitHand(MCvBox2D rect, HandEnum handEnum, PointF Elbow2HandVector) { if (handEnum == HandEnum.Both || handEnum == HandEnum.Intersect) { return new MCvBox2D(rect.center, rect.MinAreaRect().Size, 0); } PointF[] pl = rect.GetVertices(); Point[] splittedHands = new Point[4]; //find angle of long edge PointF startP = pl[1]; PointF shortP = pl[0]; PointF longP = pl[2]; PointF ap1 = new PointF(); PointF ap2 = new PointF(); if (pl[0].DistanceTo(startP) > pl[2].DistanceTo(startP)) { shortP = pl[2]; longP = pl[0]; } SizeF size = new SizeF(); size.Width = shortP.DistanceTo(startP); size.Height = longP.DistanceTo(startP); PointF shortEdge = new PointF(shortP.X - startP.X, shortP.Y - startP.Y); float t_angle = (float)(Math.Atan(shortEdge.Tan())*180/Math.PI); MCvBox2D box = new MCvBox2D(); box.size = size; box.center = pl.GetCenter(); float longDis = longP.DistanceTo(startP); float shortDis = shortP.DistanceTo(startP); // x and long edge slope float longslope = Math.Abs(longP.X - startP.X) / longDis; float min = float.MaxValue; float factor = Math.Max(Math.Abs(longP.Y - startP.Y) / longDis, Math.Abs(longP.X - startP.X) / longDis); int TransformEnd = Convert.ToInt32(factor * end); int TransformBegin = Convert.ToInt32(factor * begin); //Console.WriteLine(TransformBegin); //Console.WriteLine(TransformEnd); // > 45 if (longslope < 0.707)//vert { // point up if (Elbow2HandVector.Y <= 0) { box.angle = t_angle; startP = pl.OrderBy((x => x.Y)).First(); } else { box.angle = t_angle + 180; startP = pl.OrderByDescending((x => x.Y)).First(); } if (longDis < minLength) { return box; } pl = pl.OrderBy(x => x.DistanceTo(startP)).ToArray(); shortP = pl[1]; longP = pl[2]; for (int y = TransformBegin; y < Convert.ToInt32(Math.Abs(longP.Y - startP.Y)) && Math.Abs(y) < TransformEnd; y++) { PointF p1 = InterPolateP(startP, longP, y / Math.Abs(longP.Y - startP.Y)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } else // horizontal { // point top for right hand if (t_angle <0) { if (handEnum == HandEnum.Right) { box.angle = t_angle; } else { box.angle = t_angle + 180; } } // point bottom for right hand else { if (handEnum == HandEnum.Right) { box.angle = t_angle - 180; } else { box.angle = t_angle; } } if (handEnum == HandEnum.Right) { startP = pl.OrderBy((x => x.X)).ToArray()[0]; } else if (handEnum == HandEnum.Left) { startP = pl.OrderByDescending((x => x.X)).ToArray()[0]; } if (longDis < minLength) { return box; } pl = pl.OrderBy(x => x.DistanceTo(startP)).ToArray(); shortP = pl[1]; longP = pl[2]; for (int X = TransformBegin; X < Convert.ToInt32(Math.Abs(longP.X - startP.X)) && Math.Abs(X) < TransformEnd; X++) { PointF p1 = InterPolateP(startP, longP, X / Math.Abs(longP.X - startP.X)); PointF p2 = new PointF(p1.X + shortP.X - startP.X, p1.Y + shortP.Y - startP.Y); float dis = GetHandWidthBetween(p1, p2); if (dis < min) { min = dis; ap1 = p1; ap2 = p2; } } } if (ap1 == null || ap1 == PointF.Empty) { return box; } splittedHands[0] = startP.ToPoint(); splittedHands[1] = ap1.ToPoint(); splittedHands[2] = ap2.ToPoint(); splittedHands[3] = shortP.ToPoint(); //Point lowP = p.OrderByDescending(x => x.Y).First(); //Point highP = p.OrderByDescending(x => x.DistanceTo(lowP)).First(); //Point widthP = p.OrderBy(x => x.TanWith(lowP)).First(); box.center = splittedHands.GetCenter(); box.size.Height = startP.DistanceTo(ap1); return box; }
public static FeatureVector ExtractFeatures(Image <Gray, byte> skin, Image <Bgr, Byte> imagen) { Contour <Point> currentContour = null; Contour <Point> biggestContour = null; using (MemStorage storage = new MemStorage()) { #region extractContourAndHull Contour <Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); 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) { currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); imagen.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); 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); } imagen.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); // imagen.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); // PointF center; // float radius; 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } #endregion #region find palm center(needs change) searchRadius = 6; contourReduction = 3; //this.result = null; DetectarCentroPalma(biggestContour.ToList <Point>(), obtenerListaCandidatos(box)); PointF punto = new PointF(405, 380); Point punt = new Point(405, 380); CircleF centerCircle = new CircleF(punto, 5f); //CircleF centerCircle = new CircleF(result.Location, 5f); imagen.Draw(centerCircle, new Bgr(Color.Brown), 3); /* * for (int i = 0; i < defects.Total; i++) * { * LineSegment2D lineaDedoCentro = new LineSegment2D(defectArray[i].StartPoint, punt); * imagen.Draw(lineaDedoCentro, new Bgr(Color.Green), 2); * * } * */ #endregion List <PointF> fingertips = defectsDrawing(imagen, ref punt); #region create feature vector List <PointF> newFingertips = ordenarFingertips(fingertips); List <float> angles = calculateFingerAngles(fingertips, punto); FeatureVector vector = new FeatureVector(newFingertips, angles, punto, 5); //MessageBox.Show("Done"); // frmPruebaDatos datos = new frmPruebaDatos(vector); // datos.Show(); #endregion return(vector); }
public static List <PointF> obtenerListaCandidatos(MCvBox2D box) { PointF[] points = box.GetVertices(); float p1 = points[0].X; float p2 = points[0].Y; float p3 = points[1].X; float p4 = points[1].Y; float p5 = points[2].X; float p6 = points[2].Y; float p7 = points[3].X; float p8 = points[3].Y; float[] equises = new float[] { p1, p3, p5, p7 }; float[] yes = new float[] { p2, p4, p6, p8 }; float minimo = p1; float maximo = p1; foreach (float i in equises) { if (i < minimo) { minimo = i; } if (i > maximo) { maximo = i; } } float minimoY = p2; float maximoY = p2; foreach (float i in yes) { if (i < minimoY) { minimoY = i; } if (i > maximoY) { maximoY = i; } } PointF vertice1 = new PointF(minimo, minimoY); PointF vertice2 = new PointF(maximo, maximoY); List <PointF> listaPuntos = new List <PointF>(); for (float i = vertice1.X + 1; i < vertice2.X; i = i + 4) { for (float j = vertice1.Y - 1; j < vertice2.Y; j = j + 4) { PointF punto = new PointF(i, j); listaPuntos.Add(punto); } } return(listaPuntos); }
public void TestGetBox2DPoints() { MCvBox2D box = new MCvBox2D( new PointF(3.0f, 2.0f), new SizeF(4.0f, 6.0f), 0.0f); PointF[] vertices = box.GetVertices(); Assert.IsTrue(vertices[0].Equals(new PointF(0.0f, 0.0f))); Assert.IsTrue(vertices[1].Equals(new PointF(6.0f, 0.0f))); }
private void ExtractContourAndHull(Image <Gray, byte> skin) { using (MemStorage storage = new MemStorage()) { Contour <Point> contours = skin.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) { // currentFrame.Draw(biggestContour, new Bgr(Color.Black), 2); Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); //currentFrame.Draw(currentContour, new Bgr(Color.Red), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); handRect = box.MinAreaRect(); //int xx = (handRect.Width) / 2; //int yy = (handRect.Height) / 2; currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1); // currentFrame.Draw(new CircleF(new PointF(xx, yy), 3), new Bgr(200, 125, 75), 2); 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); } currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); // currentFrame.Draw(new CircleF(new PointF(handRect.center.X, handRect.center.Y), 3), new Bgr(200, 125, 75), 2); //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr); //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3); // PointF center; // float radius; //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out center, out radius); //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2); //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2); //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2); //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2); 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } MCvMoments moment = new MCvMoments(); // a new MCvMoments object try { moment = biggestContour.GetMoments(); // Moments of biggestContour } catch (NullReferenceException) { } int fingerNum = 0; CvInvoke.cvMoments(biggestContour, ref moment, 0); double m_00 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 0); double m_10 = CvInvoke.cvGetSpatialMoment(ref moment, 1, 0); double m_01 = CvInvoke.cvGetSpatialMoment(ref moment, 0, 1); int current_X = Convert.ToInt32(m_10 / m_00) / 10; // X location of centre of contour int current_Y = Convert.ToInt32(m_01 / m_00) / 10; // Y location of center of contour if (fingerNum == 1 || fingerNum == 0 || blue == 6) { Cursor.Position = new Point(current_X * 10, current_Y * 10); } //Leave the cursor where it was and Do mouse click, if finger count >= 3 } }
//::::::::::::Method to calculate the convex hull::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: public List<object> HandConvexHull(Image<Gray, Byte> frame, Rectangle Roi) { List<object> ListReturn = new List<object>(); Image<Gray, Byte> BinaryImage; Image<Gray,Byte> frameImagePtr; BinaryImage = frame.Copy(Roi); //BinaryImage.Save(path1 + numFrames.ToString() + ".png"); //Binarization using Otsu algortihm frameImagePtr= BinaryImage; IntPtr framePtr = frameImagePtr.Ptr; IntPtr binaryPrt = BinaryImage.Ptr; CvInvoke.cvThreshold(framePtr, binaryPrt, 0, 255, Emgu.CV.CvEnum.THRESH.CV_THRESH_OTSU); BinaryImage.Save(path1 + numFrames.ToString() + "B_Otsu.png"); //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: BinaryImage = openingOperation(BinaryImage); BinaryImage = closeOperation(BinaryImage); //BinaryImage.Save(path1 + numFrames.ToString() + "B_OC.png"); using (MemStorage storage = new MemStorage()) { Double result1 = 0; Double result2 = 0; Contour<System.Drawing.Point> contours = BinaryImage.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); Contour<System.Drawing.Point> biggestContour = null; while (contours != null) { result1 = contours.Area; if (result1 > result2) { result2 = result1; biggestContour = contours; } contours = contours.HNext; } if (biggestContour != null) { Contour<System.Drawing.Point> concurrentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); biggestContour = concurrentContour; Hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE); defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_COUNTER_CLOCKWISE); defectsArray = defects.ToArray(); box = biggestContour.GetMinAreaRect(); points = box.GetVertices(); CircleF centerBoxDraw = new CircleF(box.center, 4f); contourArea = result2; contourPerimeter = biggestContour.Perimeter; convexHullArea = Hull.Area; convexHullPerimeter = Hull.Perimeter; BinaryImage.Draw(Hull, new Gray(155), 1); BinaryImage.Draw(box, new Gray(100), 1); BinaryImage.Draw(centerBoxDraw, new Gray(200), 1); BinaryImage.Save(path1 + "ConvexHull_" + numFrames.ToString() + ".png"); ListReturn = GetFingers(BinaryImage); //::::::Old features //ListReturn.Add(contourPerimeter); //ListReturn.Add(contourArea); //ListReturn.Add(convexHullPerimeter); //ListReturn.Add(convexHullArea); } } numFrames++; return ListReturn; }//end HandConvexHull
// Extrait la "coque" du contour et les verticles afin de pouvoir calculer plus tard le nombre de doigts détectés // Ce code vient en partie de ce projet : https://www.youtube.com/watch?v=Fjj9gqTCTfc public void ExtractHull() { try { // Récupère la "coque" du plus grand contour ainsi que le rectangle qui l'englobe hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); // Récupère les vertexes de la box PointF[] points = box.GetVertices(); // On va créer un tableau de "Point" avec tous les points trouvés par "GetVerticles" 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); } // Dessine la "coque" (qui entoure tous les verticles) en rouge sur l'image traitée imgProc.DrawPolyline(hull.ToArray(), true, new Bgr(Color.Red), 2); // Dessine un cercle bleu au centre de la box imgProc.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 5), new Bgr(Color.Blue), 2); // Va filtrer les points de la "coque" afin de ne garder que ceux qui sont vraiment utiles filteredHull = new Seq<Point>(hullStorage); 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]); } } defects = biggestContour.GetConvexityDefacts(hullStorage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } catch(Exception ex) { return; } }
/// <summary> /// Returns the end points of the major and minor axes of an ellipse. /// </summary> /// <param name="ellipse"></param> /// <returns></returns> public static PointF[] EllipseAxes(MCvBox2D ellipse) { var vertices = ellipse.GetVertices(); var midPoints = new PointF[vertices.Length]; for (int i = 0; i < midPoints.Length; i++) { var p1 = vertices[i]; var p2 = vertices[(i + 1) % vertices.Length]; var mid = new PointF((p1.X + p2.X) / 2, (p1.Y + p2.Y) / 2); // Correct the bug in the angle of the ellipse in OpenCV. midPoints[i] = Rotate(mid, ellipse.center, Math.PI / 2); } return midPoints; }
private Image<Gray, Byte> CalculateConvexityDefacts(Image<Gray, Byte> image) { Gray cannyThreshold = new Gray(80); Gray cannyThresholdLinking = new Gray(80); //image = image.Canny(cannyThreshold, cannyThresholdLinking); image = image.ThresholdBinary(cannyThreshold, cannyThresholdLinking); //image = image.Erode(1); //image = image.SmoothBilatral(1, 1, 1); //image = image.SmoothMedian(5); //image = image.SmoothBlur(1,1); using (MemStorage storage = new MemStorage()) { Contour<Point> contours = image.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; //takes the biggest contour to track (not really relevant if u paint only the hand.) while (contours != null) { Result1 = contours.Area; if (Result1 > Result2) { Result2 = Result1; biggestContour = contours; } contours = contours.HNext; } double contourArea = biggestContour.Area; if (biggestContour != null) { //Drawing the contour of the hand Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); image.Draw(currentContour, new Gray(250), 1); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); 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); } image.DrawPolyline(hull.ToArray(), true, new Gray(255), 1); image.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 2), new Gray(255), 1); 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } return image; }
/// /////////// paste here private void ExtractContourAndHull(Image <Gray, byte> skin) { using (MemStorage storage = new MemStorage()) { Contour <Point> contours = skin.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) { //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2); Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); mv = biggestContour.GetMoments(); CvInvoke.cvMoments(biggestContour, ref mv, 1); double m00 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 0); double m10 = CvInvoke.cvGetSpatialMoment(ref mv, 1, 0); double m01 = CvInvoke.cvGetSpatialMoment(ref mv, 0, 1); if (m00 != 0) // calculate center { int xCenter = (int)Math.Round(m10 / m00) * 2; //scale = 2 int yCenter = (int)Math.Round(m01 / m00) * 2; cogPt.X = xCenter; cogPt.Y = yCenter; } double m11 = CvInvoke.cvGetCentralMoment(ref mv, 1, 1); double m20 = CvInvoke.cvGetCentralMoment(ref mv, 2, 0); double m02 = CvInvoke.cvGetCentralMoment(ref mv, 0, 2); contourAxisAngle = calculateTilt(m11, m20, m02); tbHandAngle.Text = contourAxisAngle.ToString(); // deal with hand contour pointing downwards /* uses fingertips inf * ormation generated on the last update of * the hand, so will be out * - * of * - * date */ /* * if (fingerTips.size() > 0) { * int yTotal = 0; * for(Point pt : fingerTips) * yTotal += pt.y; * int avgYFinger = yTotal/fingerTips.size(); * if (avgYFinger > cogPt.y) // fingers below COG * contourAxisAngle += 180; * } * contourAxisAngle = 180-contourAxisAngle; * * * * /* this makes the angle relative to a positive y * - * axis that * runs up the screen */ //handRect = box.MinAreaRect(); //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1); 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); } currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr); //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3); PointF center; float radius; //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out center, out radius); //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2); //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2); //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2); //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); //currentFrame.Draw(new Ellipse((box.center.X, box.centernew PointF.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2); 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } }
private void ExtractContourAndHull(Image<Gray, byte> skin) { List<Contour<Point>> contourList = new List<Contour<Point>>(); Contour<Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, contourStorage); Contour<Point> biggestContour = null; Double current = 0; Double largest = 0; while (contours != null) { current = contours.Area; if (current > largest) { largest = current; biggestContour = contours; } contours = contours.HNext; } if (biggestContour != null) { //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2); Contour<Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, contourStorage); currentFrame.Draw(currentContour, new Bgr(System.Drawing.Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); //handRect = box.MinAreaRect(); //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1); 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); currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr); //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3); PointF center; float radius; //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out center, out radius); //currentFrame.Draw(new CircleF(center, radius), new Bgr(System.Drawing.Color.Gold), 2); //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2); //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2); //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2); filteredHull = new Seq<Point>(contourStorage); 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]); } } defects = biggestContour.GetConvexityDefacts(contourStorage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } }
private void ExtractContourAndHull(Image <Gray, byte> skin) { using (MemStorage storage = new MemStorage()) { Contour <Point> contours = skin.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) { //currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2); Contour <Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); currentFrame.Draw(currentContour, new Bgr(Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); //handRect = box.MinAreaRect(); //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1); 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); } currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); //ellip.MCvBox2D= CvInvoke.cvFitEllipse2(biggestContour.Ptr); //currentFrame.Draw(new Ellipse(ellip.MCvBox2D), new Bgr(Color.LavenderBlush), 3); PointF center; float radius; //CvInvoke.cvMinEnclosingCircle(biggestContour.Ptr, out center, out radius); //currentFrame.Draw(new CircleF(center, radius), new Bgr(Color.Gold), 2); //currentFrame.Draw(new CircleF(new PointF(ellip.MCvBox2D.center.X, ellip.MCvBox2D.center.Y), 3), new Bgr(100, 25, 55), 2); //currentFrame.Draw(ellip, new Bgr(Color.DeepPink), 2); //CvInvoke.cvEllipse(currentFrame, new Point((int)ellip.MCvBox2D.center.X, (int)ellip.MCvBox2D.center.Y), new System.Drawing.Size((int)ellip.MCvBox2D.size.Width, (int)ellip.MCvBox2D.size.Height), ellip.MCvBox2D.angle, 0, 360, new MCvScalar(120, 233, 88), 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, 0); //currentFrame.Draw(new Ellipse(new PointF(box.center.X, box.center.Y), new SizeF(box.size.Height, box.size.Width), box.angle), new Bgr(0, 0, 0), 2); 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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); } } }
private void ExtractContourAndHull(Image<Gray, byte> skin, Image<Bgr,byte> currentFrame) { using (MemStorage storage = new MemStorage()) { Contour<System.Drawing.Point> contours = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); Contour<System.Drawing.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) { currentFrame.Draw(biggestContour, new Bgr(Color.DarkViolet), 2); Contour<System.Drawing.Point> currentContour = biggestContour.ApproxPoly(biggestContour.Perimeter * 0.0025, storage); currentFrame.Draw(currentContour, new Bgr(System.Drawing.Color.LimeGreen), 2); biggestContour = currentContour; hull = biggestContour.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); box = biggestContour.GetMinAreaRect(); PointF[] points = box.GetVertices(); //handRect = box.MinAreaRect(); //currentFrame.Draw(handRect, new Bgr(200, 0, 0), 1); System.Drawing.Point[] ps = new System.Drawing.Point[points.Length]; for (int i = 0; i < points.Length; i++) ps[i] = new System.Drawing.Point((int)points[i].X, (int)points[i].Y); currentFrame.DrawPolyline(hull.ToArray(), true, new Bgr(200, 125, 75), 2); currentFrame.Draw(new CircleF(new PointF(box.center.X, box.center.Y), 3), new Bgr(200, 125, 75), 2); filteredHull = new Seq<System.Drawing.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]); } } defects = biggestContour.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE); defectArray = defects.ToArray(); DrawAndComputeFingersNum(currentFrame,filteredHull,defects,defectArray); } imageConvexHull.Source = toBitmapSourceFromImage(currentFrame); } }