public static Emgu.CV.Util.VectorOfPoint ToClockwise(this Emgu.CV.Util.VectorOfPoint vectorOfPoint) { var array = new List <Point>(vectorOfPoint.ToArray()); array.Reverse(); if (Emgu.CV.CvInvoke.ContourArea(vectorOfPoint, true) < 0) { return(new Emgu.CV.Util.VectorOfPoint(array.ToArray())); } return(vectorOfPoint); }
public static Point[] findCutPoint(Emgu.CV.Util.VectorOfPoint contours) { Point[] con1 = contours.ToArray(); Array.Sort(con1, compareY); int size = con1.Length; int top_x = con1[0].X; int top_y = con1[0].Y; int bottom_x = con1[size - 1].X; int bottom_y = con1[size - 1].Y; int top_x_count = 1; int bottom_x_count = 1; int flag1 = 0; for (int i = 1; i < size / 10; i++) { if (top_y == con1[i].Y) { flag1 = 1; top_x_count += 1; top_x += con1[i].X; } if (bottom_y == con1[size - 1 - i].Y) { flag1 = 1; bottom_x_count += 1; bottom_x += con1[size - 1 - i].X; } if (flag1 == 0) { break; } } float top_x_temp = (float)(top_x * 1.0F / top_x_count * 1.0); float bottom_x_temp = (float)(bottom_x * 1.0F / bottom_x_count * 1.0); Point[] con2 = con1; Array.Sort(con2, compareX); int left_x = con2[0].X; int left_y = con2[0].Y; int right_x = con2[size - 1].X; int right_y = con2[size - 1].Y; int left_y_count = 1; int right_y_count = 1; int flag2 = 0; for (int i = 1; i < size / 10; i++) { if (left_x == con2[i].X) { flag2 = 1; left_y_count += 1; left_y += con2[i].Y; } if (right_x == con2[size - 1 - i].X) { flag2 = 1; right_y_count += 1; right_y += con2[size - 1 - i].Y; } if (flag2 == 0) { break; } } float left_y_temp = left_y * 1.0F / (float)(left_y_count * 1.0F); float right_y_temp = right_y * 1.0F / (float)right_y_count * 1.0F; System.Drawing.Point[] p1 = new Point[4]; p1[0].X = (int)top_x_temp; p1[0].Y = top_y; p1[1].X = right_x; p1[1].Y = (int)right_y_temp; p1[2].X = (int)bottom_x_temp; p1[2].Y = bottom_y; p1[3].X = left_x; p1[3].Y = (int)left_y_temp; return(p1); }
private void button2_Click(object sender, EventArgs e) { Image triangleRectangleImageBox1; Image circleImageBox1; Image lineImageBox1; StringBuilder msgBuilder = new StringBuilder("Performance: "); Bitmap clip_bmp = new Bitmap(cliped_image); //Load the image from file and resize it for display Image <Bgr, Byte> img = new Image <Bgr, byte>(clip_bmp).Resize(400, 400, Emgu.CV.CvEnum.Inter.Linear, true); //Convert the image to grayscale and filter out the noise UMat uimage = new UMat(); CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray); //use image pyr to remove noise UMat pyrDown = new UMat(); CvInvoke.PyrDown(uimage, pyrDown); CvInvoke.PyrUp(pyrDown, uimage); #region circle detection Stopwatch watch = Stopwatch.StartNew(); double cannyThreshold = 180.0; // 180 double circleAccumulatorThreshold = 120.0; // 120 CircleF[] circles = CvInvoke.HoughCircles(uimage, HoughType.Gradient, 2.0, 20.0, cannyThreshold, circleAccumulatorThreshold, 5); watch.Stop(); msgBuilder.Append(String.Format("Hough circles - {0} ms; ", watch.ElapsedMilliseconds)); #endregion #region Canny and edge detection watch.Reset(); watch.Start(); double cannyThresholdLinking = 120.0; // 120 UMat cannyEdges = new UMat(); CvInvoke.Canny(uimage, cannyEdges, cannyThreshold, cannyThresholdLinking); LineSegment2D[] lines = CvInvoke.HoughLinesP( cannyEdges, 1, //Distance resolution in pixel-related units - 1 Math.PI / 45.0, //Angle resolution measured in radians. 0, //threshold - 20 0, //min Line width - 30 10); //gap between lines - 10 watch.Stop(); msgBuilder.Append(String.Format("Canny & Hough lines - {0} ms; ", watch.ElapsedMilliseconds)); #endregion #region Find triangles and rectangles watch.Reset(); watch.Start(); List <Triangle2DF> triangleList = new List <Triangle2DF>(); List <RotatedRect> boxList = new List <RotatedRect>(); //a box is a rotated rectangle using (Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint()) { CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple); int count = contours.Size; for (int i = 0; i < count; i++) { using (Emgu.CV.Util.VectorOfPoint contour = contours[i]) using (Emgu.CV.Util.VectorOfPoint approxContour = new Emgu.CV.Util.VectorOfPoint()) { CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true); if (CvInvoke.ContourArea(approxContour, false) > 250) //only consider contours with area greater than 250 { if (approxContour.Size == 3) //The contour has 3 vertices, it is a triangle { Point[] pts = approxContour.ToArray(); triangleList.Add(new Triangle2DF( pts[0], pts[1], pts[2] )); } else if (approxContour.Size == 4) //The contour has 4 vertices. { #region determine if all the angles in the contour are within [80, 100] degree bool isRectangle = true; Point[] pts = approxContour.ToArray(); LineSegment2D[] edges = PointCollection.PolyLine(pts, true); for (int j = 0; j < edges.Length; j++) { double angle = Math.Abs( edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j])); if (angle < 80 || angle > 100) { isRectangle = false; break; } } #endregion if (isRectangle) { boxList.Add(CvInvoke.MinAreaRect(approxContour)); } } } } } } watch.Stop(); msgBuilder.Append(String.Format("Triangles & Rectangles - {0} ms; ", watch.ElapsedMilliseconds)); #endregion //originalImageBox.Image = img.ToBitmap(); this.Text = msgBuilder.ToString(); #region draw triangles and rectangles Image <Bgr, Byte> triangleRectangleImage = img.CopyBlank(); foreach (Triangle2DF triangle in triangleList) { triangleRectangleImage.Draw(triangle, new Bgr(Color.DarkBlue), 2); } foreach (RotatedRect box in boxList) { triangleRectangleImage.Draw(box, new Bgr(Color.DarkOrange), 2); } triangleRectangleImageBox1 = triangleRectangleImage.ToBitmap(); #endregion #region draw circles Image <Bgr, Byte> circleImage = img.CopyBlank(); foreach (CircleF circle in circles) { circleImage.Draw(circle, new Bgr(Color.Brown), 2); } circleImageBox1 = circleImage.ToBitmap(); #endregion #region draw lines Image <Bgr, Byte> lineImage = img.CopyBlank(); foreach (LineSegment2D line in lines) { lineImage.Draw(line, new Bgr(Color.Green), 2); } lineImageBox1 = lineImage.ToBitmap(); #endregion cv_image = lineImageBox1; pictureBox2.Image = lineImageBox1; }