示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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;
        }