Beispiel #1
0
        public static bool IsRectangle(Contour <Point> contour, double toleranceAngle = 10.0)
        {
            if (contour.Total != 4)
            {
                return(false);
            }

            // determine if all the angles in the contour are within [80, 100] degree
            var pts   = contour.ToArray();
            var edges = PointCollection.PolyLine(pts, true);

            var isRectangle = true;

            for (var i = 0; i < edges.Length; i++)
            {
                var edge = edges[(i + 1) % edges.Length];

                var angle = Math.Abs(edge.GetExteriorAngleDegree(edges[i]));

                var absAngle = Math.Abs(90.0 - angle);
                if (absAngle > toleranceAngle)
                {
                    isRectangle = false;
                    break;
                }
            }

            return(isRectangle);
        }
Beispiel #2
0
        private static RotatedRect?getCheckboxPatternFromContoursOfImage(VectorOfPoint approxContour)
        {
            if (approxContour.Size == 4)
            {
                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;
                    }
                }
                if (isRectangle)
                {
                    return(CvInvoke.MinAreaRect(approxContour));
                }
            }
            return(null);
        }
Beispiel #3
0
        private IEnumerable <Rectangle> GetBoundariesForProcessedImage(Mat edges)
        {
            List <Rectangle> boxList = new List <Rectangle>();

            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                CvInvoke.FindContours(edges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                int contourCount = contours.Size;
                for (int i = 0; i < contourCount; i++)
                {
                    using (VectorOfPoint approxContour = new VectorOfPoint())
                        using (VectorOfPoint approx = contours[i])
                        {
                            CvInvoke.ApproxPolyDP(approx, approxContour, CvInvoke.ArcLength(approx, true) * 0.035, true);
                            Point[]         pts         = approxContour.ToArray();
                            LineSegment2D[] edgesList   = PointCollection.PolyLine(pts, true);
                            double          contourArea = CvInvoke.ContourArea(approxContour, true);
                            if (contourArea >= 500 && contourArea <= edges.Width * edges.Height / 5.0)
                            {
                                Rectangle contourRectangle = GetRectangleFromContour(approxContour, edgesList);
                                if (contourRectangle != default(Rectangle))
                                {
                                    boxList.Add(contourRectangle);
                                }
                            }
                        }
                }
            }

            return(boxList);
        }
Beispiel #4
0
        private bool IsRectangle(VectorOfPoint contour)
        {
            if (contour.Size != 4)
            {
                return(false);
            }

            Point[] points = contour.ToArray();

            int delta = 10;

            LineSegment2D[] edges = PointCollection.PolyLine(points, true);

            for (int i = 0; i < edges.Length; i++)
            {
                double angle = Math.Abs(edges[(i + 1) %
                                              edges.Length].GetExteriorAngleDegree(edges[i]));
                if (angle < 90 - delta || angle > 90 + delta)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #5
0
        public static List <Shapes.Rectangle> FindRectangles(VideoProcessing vp, Bitmap frame)
        {
            List <Shapes.Rectangle> rects = new List <Shapes.Rectangle>();

            using (Image <Bgr, Byte> img = new Image <Bgr, byte>(frame)) {
                //  double cannyThresholdLinking = 120.0;
                //  double cannyThreshold = 180.0;

                //Convert the image to grayscale and filter out the noise
                Image <Gray, Byte> gray = img.Convert <Gray, Byte>().PyrDown().PyrUp();
                //Image<Gray, Byte> cannyEdges = gray.Canny(cannyThreshold, cannyThresholdLinking);

                using (MemStorage storage = new MemStorage()) { //allocate storage for contour approximation
                    Contour <System.Drawing.Point> contours = gray.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, RETR_TYPE.CV_RETR_LIST, storage);
                    for (; contours != null; contours = contours.HNext)
                    {
                        Contour <System.Drawing.Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage);

                        if (currentContour.Area > 250)     //only consider contours with area greater than 250
                        {
                            if (currentContour.Total == 4) //The contour has 4 vertices.
                            {
                                #region determine if all the angles in the contour are within [80, 100] degree
                                bool isRectangle             = true;
                                System.Drawing.Point[] pts   = currentContour.ToArray();
                                LineSegment2D[]        edges = PointCollection.PolyLine(pts, true);

                                for (int i = 0; i < edges.Length; i++)
                                {
                                    double angle = Math.Abs(edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i]));
                                    if (angle < 80 || angle > 100)
                                    {
                                        isRectangle = false;
                                        break;
                                    }
                                }
                                #endregion

                                if (isRectangle)
                                {
                                    var box            = currentContour.GetMinAreaRect();
                                    Shapes.Rectangle r = new Shapes.Rectangle(box.center.X, box.center.Y, box.angle);
                                    r.Height = box.size.Height;
                                    r.Width  = box.size.Width;
                                    rects.Add(r);
                                }
                            }
                        }
                    }
                }
            }
            //ensure we dont have massive rectangles
            rects = rects.Where(x => (x.Height < .8 * vp.FrameSize.Height && x.Width < .8 * vp.FrameSize.Width)).ToList();
            SetVideoProcessing(rects, vp);
            return(rects);
        }
Beispiel #6
0
 private void fnFindTriangleRect()
 {
     triangleRectImage = img.CopyBlank();
     using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
     {
         CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
         int count = contours.Size;
         for (int i = 0; i < count; i++)
         {
             using (VectorOfPoint contour = contours[i])
                 using (VectorOfPoint approxContour = new VectorOfPoint())
                 {
                     CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true);
                     if (CvInvoke.ContourArea(approxContour, false) > 250) //only consider contour with area > 250
                     {
                         if (approxContour.Size == 3)                      //The contour has 3 vertices, 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 contours 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 dAngle = Math.Abs(edges[(j + 1) % edges.Length].GetExteriorAngleDegree(edges[j]));
                                 if (dAngle < 80 || dAngle > 100)
                                 {
                                     isRectangle = false;
                                     break;
                                 }
                             }
                             #endregion
                             if (isRectangle)
                             {
                                 boxList.Add(CvInvoke.MinAreaRect(approxContour));
                             }
                         }
                     }
                 }
         }
     }
     foreach (Triangle2DF triangle in triangleList)
     {
         triangleRectImage.Draw(triangle, new Bgr(Color.DarkBlue), 2);
     }
     foreach (RotatedRect box in boxList)
     {
         triangleRectImage.Draw(box, new Bgr(Color.Red), 2);
     }
     ImgBox_Triangle_Rect.Image = triangleRectImage.Bitmap;
 }
Beispiel #7
0
    //fonction pour dessiner les limits des obj et creer leur centroide
    List <RotatedRect> DrawRectangle(Image <Gray, byte> imageSeuil, String name)
    {
        List <RotatedRect> boxList = new List <RotatedRect>();

        contours = new VectorOfVectorOfPoint();
        Mat m = new Mat();

        CvInvoke.FindContours(imageSeuil, contours, m, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple);

        for (int i = 0; i < contours.Size; i++)
        {
            double        perimeter = CvInvoke.ArcLength(contours[i], true);
            VectorOfPoint approx    = new VectorOfPoint();
            CvInvoke.ApproxPolyDP(contours[i], approx, 0.04 * perimeter, true);
            if (CvInvoke.ContourArea(approx, false) > 250) //only consider contours with area greater than 250
            {
                if (approx.Size == 4)                      //The contour has 4 vertices, it is a rectangle
                {
                    bool            isRectangle = true;
                    Point[]         pts         = approx.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;
                        }
                    }
                    if (isRectangle)
                    {
                        boxList.Add(CvInvoke.MinAreaRect(approx));
                    }
                }

                foreach (RotatedRect box in boxList)
                {
                    CvInvoke.Polylines(imageMat, Array.ConvertAll(box.GetVertices(), Point.Round), true,
                                       new Bgr(System.Drawing.Color.Blue).MCvScalar, 2);
                    var moments = CvInvoke.Moments(contours[i]);
                    int x       = (int)(moments.M10 / moments.M00);
                    int y       = (int)(moments.M01 / moments.M00);
                    CvInvoke.PutText(imageMat, name, new Point(x, y), Emgu.CV.CvEnum.FontFace.HersheySimplex, 0.5, new MCvScalar(0, 0, 255), 2);
                }
            }
        }

        return(boxList);
    }
Beispiel #8
0
        } // ShapeDetection() ////

        private static void FindTrianglesAndRectangles(UMat cannyEdges, List <Triangle2DF> triangleList, List <RotatedRect> boxList)
        {
            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                int count = contours.Size;
                for (int i = 0; i < count; i++)
                {
                    using (VectorOfPoint contour = contours[i])
                        using (VectorOfPoint approxContour = new 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));
                                    }
                                }
                            }
                        }
                }
            }
        } // FindTrianglesAndRectangles() ///
        /// <summary>
        /// Check if the four points forms a parallelogram
        /// </summary>
        /// <param name="pts">The four points that defines a polygon</param>
        /// <returns>True if the four points defines a parallelogram</returns>
        private static bool IsParallelogram(Point[] pts)
        {
            LineSegment2D[] edges = PointCollection.PolyLine(pts, true);

            double diff1 = Math.Abs(edges[0].Length - edges[2].Length);
            double diff2 = Math.Abs(edges[1].Length - edges[3].Length);

            if (diff1 / edges[0].Length <= 0.05 && diff1 / edges[2].Length <= 0.05 &&
                diff2 / edges[1].Length <= 0.05 && diff2 / edges[3].Length <= 0.05)
            {
                return(true);
            }
            return(false);
        }
        private static bool isRectangle(Point[] pts)
        {
            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)
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #11
0
 private bool isRectangle(Point[] points, int delta)
 {
     LineSegment2D[] edges = PointCollection.PolyLine(points, true);
     for (int i = 0; i < edges.Length; i++)
     {
         double angle = Math.Abs(edges[(i + 1) %
                                       edges.Length].GetExteriorAngleDegree(edges[i]));
         if (angle < 90 - delta || angle > 90 + delta)
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #12
0
        private bool isRectangle(Point[] points)
        {
            int delta = 10; // максимальное отклонение от прямого угла

            LineSegment2D[] edges = PointCollection.PolyLine(points, true);
            for (int i = 0; i < edges.Length; i++) // обход всех ребер контура
            {
                double angle = Math.Abs(edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i]));
                if (angle < 90 - delta || angle > 90 + delta) // если угол непрямой
                {
                    return(false);
                }
            }
            return(true);
        }
Beispiel #13
0
        private List <Tuple <Point[], double> > BoxDetection(IImage cannyEdges)
        {
            List <Tuple <Point[], double> > boxList = new List <Tuple <Point[], double> >();

            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                CvInvoke.FindContours((IImage)((ICloneable)cannyEdges).Clone(), contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                int count = contours.Size;
                for (int i = 0; i < count; i++)
                {
                    using (VectorOfPoint contour = contours[i])
                        using (VectorOfPoint approxContour = new VectorOfPoint())
                        {
                            CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true);
                            var area = CvInvoke.ContourArea(approxContour, false);
                            if (area > 250)                  //only consider contours with area greater than 250
                            {
                                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 < 40 || angle > 130)
                                        {
                                            isRectangle = false;
                                            break;
                                        }
                                    }
                                    #endregion

                                    if (isRectangle)
                                    {
                                        boxList.Add(new Tuple <Point[], double>(approxContour.ToArray(), area));        // CvInvoke.MinAreaRect(approxContour));
                                    }
                                }
                            }
                        }
                }
            }
            return(boxList);
        }
Beispiel #14
0
        private void ContourImage(Mat frame, VectorOfPoint contour, Rectangle boundingBox, double area)
        {
            // contour collection for the contour image output frame
            using (VectorOfPoint approxContour = new VectorOfPoint())
            {
                bool            isRectangle = true;
                Point[]         pts         = approxContour.ToArray();
                LineSegment2D[] edges       = PointCollection.PolyLine(pts, true);

                CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.10, true);
                // get an array of points in the contour

                if (contour.Size > 20 && area < 5000) // filters size of shapes shown
                {
                    // Drawing contour and box around it
                    if (approxContour.Size == 3)                                                  //The contour has 3 vertices, it is a triangle
                    {
                        CvInvoke.Polylines(frame, contour, true, new Bgr(Color.Green).MCvScalar); // adds colors to shapes
                    }
                    else if (approxContour.Size == 4)                                             //The contour has 4 vertices, it is a square
                    {
                        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) // verifies square edge angles
                            {
                                isRectangle = false;
                            }
                        }

                        if (isRectangle == true)
                        {
                            CvInvoke.Polylines(frame, contour, true, new Bgr(Color.Red).MCvScalar); // adds colors to shapes
                        }
                    }
                    else
                    {
                    }

                    // Write information next to marked object
                    Point center = new Point(boundingBox.X + boundingBox.Width / 2, boundingBox.Y + boundingBox.Height / 2); // center of bounding box

                    CvInvoke.Circle(frame, center, 2, new Bgr(Color.Orange).MCvScalar, 3);                                   // orange dot in center of bounding box
                }
            }
        }
Beispiel #15
0
        private List <RotatedRect> Contours(Mat img)
        {
            List <RotatedRect> boxList = new List <RotatedRect>();

            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                using (VectorOfPoint approxContour = new VectorOfPoint())
                {
                    Mat output = new Mat();
                    CvInvoke.FindContours(img, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                    int count = contours.Size;
                    for (int i = 0; i < count; i++)
                    {
                        CvInvoke.ApproxPolyDP(contours[i], approxContour, CvInvoke.ArcLength(contours[i], true) * 0.05, true);
                        if (CvInvoke.ContourArea(approxContour, false) > 200)
                        {
                            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 < 70 || angle > 110)
                                    {
                                        isRectangle = false;
                                        break;
                                    }
                                }

                                #endregion
                                if (isRectangle)
                                {
                                    boxList.Add(CvInvoke.MinAreaRect(approxContour));
                                }
                            }
                        }
                    }
                }
            }
            return(boxList);
        }
Beispiel #16
0
        private void rbRectangle_CheckedChanged(object sender, EventArgs e)
        {
            if (!rbRChecked)
            {
                CvInvoke.cvCvtColor(ori, edit, COLOR_CONVERSION.CV_BGR2GRAY);
                CvInvoke.cvCanny(edit, edit, 150, 60, 3);
                result = ori.Clone();

                List <MCvBox2D> box = new List <MCvBox2D>();
                for (Contour <Point> con = edit.FindContours(); con != null; con = con.HNext)
                {
                    Contour <Point> conPoint = con.ApproxPoly(con.Perimeter * 0.16);
                    if (conPoint.Total == 4)
                    {
                        bool            Rect = true;
                        Point[]         pts  = conPoint.ToArray();
                        LineSegment2D[] line = PointCollection.PolyLine(pts, true);
                        for (int i = 0; i < line.Length; i++)
                        {
                            double angle = Math.Abs(line[(i + 1) % line.Length].GetExteriorAngleDegree(line[i]));
                            if (angle < 80 || angle > 100)
                            {
                                Rect = false;
                                break;
                            }
                        }

                        if (Rect)
                        {
                            box.Add(conPoint.GetMinAreaRect());
                        }

                        foreach (MCvBox2D boxs in box)
                        {
                            result.Draw(boxs, new Bgr(Color.Blue), 5);
                        }
                    }
                }

                rbRChecked       = true;
                rbLChecked       = false;
                rbCChecked       = false;
                pictureBox.Image = result.ToBitmap();
            }
        }
Beispiel #17
0
        void Shapedetection(Image <Gray, byte> img, int contour)
        {
            boxList.Clear();
            triList.Clear();
            for (Contour <Point> con = img.FindContours(); con != null; con = con.HNext)
            {
                Contour <Point> con2 = con.ApproxPoly(con.Perimeter * 0.16, storage);
                if (con.Area > 250)
                {
                    //Triangle
                    if (contour == 3)
                    {
                        if (con2.Total == 3)
                        {
                            Point[] pts = con2.ToArray();
                            triList.Add(new Triangle2DF(pts[0], pts[1], pts[2]));
                        }
                    }
                    //Rectangle
                    else if (contour == 4)
                    {
                        if (con2.Total == 4)
                        {
                            bool            isRect = true;
                            Point[]         pts    = con2.ToArray();
                            LineSegment2D[] edge   = PointCollection.PolyLine(pts, true);

                            for (int i = 0; i < edge.Length; i++)
                            {
                                double angle = Math.Abs(edge[(i + 1) % edge.Length].GetExteriorAngleDegree(edge[i]));
                                if (angle < 80 || angle > 100)
                                {
                                    isRect = false;
                                    break;
                                }
                            }
                            if (isRect)
                            {
                                boxList.Add(con2.GetMinAreaRect());
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Determines whether the angles are close enough to 90 degrees
        /// </summary>
        /// <param name="contour"></param>
        /// <returns></returns>
        private bool IsRectangle(Contour <Point> contour)
        {
            Point[]         pts   = contour.ToArray();
            LineSegment2D[] edges = PointCollection.PolyLine(pts, true);

            for (int i = 0; i < edges.Length; i++)
            {
                LineSegment2D currentEdge = edges[i];
                LineSegment2D nextEdge    = edges[(i + 1) % edges.Length];

                double angle = Math.Abs(nextEdge.GetExteriorAngleDegree(currentEdge));
                if (angle < 80 || angle > 100)
                {
                    return(false);
                }
            }

            return(true);
        }
        private bool isRectangle(Point[] points, int minAreaOfRect)
        {
            int delta = 10;

            VectorOfPoint arr = new VectorOfPoint(points);

            LineSegment2D[] edges = PointCollection.PolyLine(points, true);

            for (int i = 0; i < edges.Length; i++)
            {
                double andle = Math.Abs(edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i]));

                if (andle < 90 - delta || andle > 90 + delta || CvInvoke.ContourArea(arr, false) < minAreaOfRect)
                {
                    return(false);
                }
            }
            return(true);
        }
        private List <MCvBox2D> GetQuadrilaterals(Image <Gray, Byte> image)
        {
            //List to store rectangles
            List <MCvBox2D> rectList = new List <MCvBox2D>();

            using (MemStorage storage1 = new MemStorage())
                for (Contour <System.Drawing.Point> contours1 = image.FindContours(); contours1 != null; contours1 = contours1.HNext)
                {
                    //Polygon Approximations
                    Contour <System.Drawing.Point> contoursAP = contours1.ApproxPoly(contours1.Perimeter * 0.05, storage1);
                    //Use area to wipe out the unnecessary result
                    if (contours1.Area >= 200)
                    {
                        //Use vertices to determine the shape
                        if (contoursAP.Total == 4)
                        {
                            //Rectangle
                            bool isRectangle = true;
                            System.Drawing.Point[] points = contoursAP.ToArray();
                            LineSegment2D[]        edges  = PointCollection.PolyLine(points, true);
                            //degree within the range of [75, 105] will be detected
                            for (int i = 0; i < edges.Length; i++)
                            {
                                double angle = Math.Abs(edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i]));
                                if (angle < 75 || angle > 105)
                                {
                                    isRectangle = false;
                                    break;
                                }
                            }
                            if (isRectangle)
                            {
                                rectList.Add(contoursAP.GetMinAreaRect());
                            }
                        }
                    }
                }

            return(rectList);
        }
            /// <summary>

            /// Determina si un contorno es un rectangulo verificando que tenga 4 vertices y sus angulos sean 90°

            /// </summary>

            /// <param name="MaxAngleDeviationDeg"> Máxima desviacion permitida respecto a 90° </param>

            /// <returns></returns>

            public static bool isRectangle(this VectorOfPoint contour, float MaxAngleDeviationDeg = 10)
            {
                bool result = false;



                if (contour.Size == 4)
                {
                    result = true;

                    Point[] pts = contour.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 < 90 - MaxAngleDeviationDeg || angle > 90 + MaxAngleDeviationDeg)
                        {
                            result = false;

                            break;
                        }
                    }



                    pts = null;

                    edges = null;
                }



                return(result);
            }
Beispiel #22
0
        private void DetectTriangle()
        {
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(gray, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
            for (int i = 0; i < contours.Size; i++)
            {
                VectorOfPoint contour       = contours[i];
                VectorOfPoint contourApprox = new VectorOfPoint();

                CvInvoke.ApproxPolyDP(contour, contourApprox, CvInvoke.ArcLength(contour, true) * 0.1, true);
                Point[] points = contourApprox.ToArray();
                if (contourApprox.Size == 3)
                {
                    LineSegment2D[] lines = PointCollection.PolyLine(points, true);

                    for (int j = 0; j < lines.Length; j++)
                    {
                        edit.Draw(lines[j], new Bgr(Color.Red), 2);
                    }
                }
            }
        }
Beispiel #23
0
        /// <summary>
        /// Determine if all the angles in the contour are within min/max angle.
        /// </summary>
        /// <param name="contour"></param>
        /// <param name="minAngle"></param>
        /// <param name="maxAngle"></param>
        /// <param name="minDetectAngles"></param>
        /// <param name="points"></param>
        /// <returns></returns>
        private bool IsPlausibleRectangle(Seq <DPoint> contour, int minAngle, int maxAngle, int minDetectAngles, out List <DPoint> points)
        {
            points = new List <DPoint>();

            if (contour.Total < 4)
            {
                return(false);                   //The contour has less than 3 vertices.
            }
            var pts   = contour.ToArray();
            var edges = PointCollection.PolyLine(pts, true);

            var rightAngle = 0;

            for (var i = 0; i < edges.Length; i++)
            {
                var edge1 = edges[i];
                var edge2 = edges[(i + 1) % edges.Length];

                var edgeRatio = (edge1.Length / edge2.Length);

                points.Add(edge1.P1);

                var angle = Math.Abs(edge1.GetExteriorAngleDegree(edge2));

                // stop if an angle is not in min/max angle range, no need to continue
                // also stop if connected edges are more than double in ratio
                if ((angle < minAngle || angle > maxAngle) ||
                    (edgeRatio > 5.0 || 1 / edgeRatio > 5.0))
                {
                    continue;
                }

                rightAngle++;
            }

            return(rightAngle >= minDetectAngles);
        }
Beispiel #24
0
        /// <summary>
        /// Megkeresi openCV segítségével a paraméterként kapott képen az összes lehetséges négyszöget.
        /// </summary>
        /// <param name="img">A kép, melyen négyszögeket keresünk.</param>
        /// <returns>Az összes detektált négyzetet adja vissza.</returns>
        private List <MCvBox2D> Boxes(Image <Bgr, Byte> img)
        {
            List <MCvBox2D> boxList = new List <MCvBox2D>();

            Image <Gray, Byte> gray       = img.Convert <Gray, Byte>();
            Image <Gray, Byte> cannyEdges = img.Canny(100.0, 60.0);

            Contour <Point> contours;

            using (MemStorage storage = new MemStorage())
                for (contours = cannyEdges.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); contours != null; contours = contours.HNext)
                {
                    Contour <Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage);

                    bool            isRectangle = true;
                    Point[]         pts         = currentContour.ToArray();
                    LineSegment2D[] edges       = PointCollection.PolyLine(pts, true);

                    for (int i = 0; i < edges.Length; i++)
                    {
                        double angle = Math.Abs(
                            edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i]));
                        if (angle < 80 || angle > 100)
                        {
                            isRectangle = false;
                            break;
                        }
                    }

                    if (isRectangle)
                    {
                        boxList.Add(currentContour.GetMinAreaRect());
                    }
                }

            return(boxList);
        }
Beispiel #25
0
        private LineSegment2D[] GetRightAngleEdges(Contour <Point> contour)
        {
            var pts   = contour.ToArray();
            var edges = PointCollection.PolyLine(pts, true);

            var longestEdge = edges[0];
            var index       = 0;

            for (var i = 1; i < edges.Length; i++)
            {
                var edge = edges[i];

                // Assumption is that the longest edge defines the width of the tracked device in the blob
                if (edge.Length > longestEdge.Length)
                {
                    index       = i;
                    longestEdge = edges[i];
                }
            }

            var nextEdgeToLongestEdge = edges[(index + 1) % edges.Length];

            return(new[] { longestEdge, nextEdgeToLongestEdge });
        }
        public Result PerformShapeDetection(VisionProfile profile, Mat img)
        {
            using (var gray = new Image <Gray, byte>(img.Bitmap))
                using (var blurredGray = new Mat())
                    using (var finalOutput = new Mat())
                    {
                        //K Must always be odd.

                        CvInvoke.GaussianBlur(gray, blurredGray, System.Drawing.Size.Empty, profile.GaussianSigmaX);

                        //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(img, pyrDown);
                        CvInvoke.PyrUp(pyrDown, img);

                        //Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp();

                        var circles = CvInvoke.HoughCircles(img, HoughType.Gradient, profile.HoughCirclesDP, profile.HoughCirclesMinDistance, profile.HoughCirclesParam1, profile.HoughCirclesParam2, profile.HoughCirclesMinRadius, profile.HoughCirclesMaxRadius);

                        UMat cannyEdges = new UMat();
                        CvInvoke.Canny(img, cannyEdges, profile.CannyLowThreshold, profile.CannyHighThreshold, profile.CannyApetureSize, profile.CannyGradient);

                        var lines = CvInvoke.HoughLinesP(cannyEdges, profile.HoughLinesRHO, profile.HoughLinesTheta, profile.HoughLinesThreshold, profile.HoughLinesMinLineLength, profile.HoughLinesMaxLineGap);

                        List <Triangle2DF> triangleList = new List <Triangle2DF>();
                        List <RotatedRect> boxList      = new List <RotatedRect>(); //a box is a rotated rectangle

                        using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
                        {
                            CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                            int count = contours.Size;
                            for (int i = 0; i < count; i++)
                            {
                                using (VectorOfPoint contour = contours[i])
                                    using (VectorOfPoint approxContour = new 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
                                            {
                                                var 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;
                                                var             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));
                                                }
                                            }
                                        }
                                    }
                            }
                        }


                        var results = new Result();
                        results.Triangles = triangleList;
                        results.Rects     = boxList;
                        results.Circles   = circles.ToList();
                        results.Lines     = lines.ToList();

                        return(results);
                    }
        }
Beispiel #27
0
        /// <summary>
        /// hand detection function
        /// </summary>
        /// <param name="skin">a binary image that contains skin like objects</param>
        /// <returns>a list that contains detected hands</returns>
        private List <Contour <Point> > HandDetection(Image <Gray, byte> skin)
        {
            Point first_peak      = new Point(),
                  first_valley    = new Point(),
                  reference_peak  = new Point(),
                  refernce_valley = new Point();

            double[,] v1 = new double[2, 1],
            v2           = new double[2, 1];

            double angle;

            int direction,
                length,
                mod;

            bool tester_peak   = false,
                 tester_valley = false;



            using (MemStorage storage = new MemStorage())
            {
                handCandiate.Clear();

                for (Contour <Point> i = skin.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                                                           Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL,
                                                           storage);
                     i != null;
                     i = i.HNext)
                {
                    area = i.BoundingRectangle.Height * i.BoundingRectangle.Width;


                    if (area > 3000 && !(i.Convex))
                    {
                        tester_peak   = false;
                        tester_valley = false;
                        skin.ROI      = i.BoundingRectangle;

                        this.center_pt = FindCentroidByDistanceTrans(skin);

                        this.center_pt.X += skin.ROI.X;
                        this.center_pt.Y += skin.ROI.Y;
                        skin.ROI          = Rectangle.Empty;

                        Contour <Point> tt = i.ApproxPoly(accuracy, storage);

                        LineSegment2D[] edges = PointCollection.PolyLine(tt.ToArray(), true);


                        length = edges.Length;
                        for (int ij = 0; ij < length; ij++)
                        {
                            mod = (ij + 1) % length;

                            v1[0, 0] = edges[ij].P2.X - edges[ij].P1.X;
                            v1[1, 0] = edges[ij].P2.Y - edges[ij].P1.Y;
                            v2[0, 0] = edges[mod].P1.X - edges[mod].P2.X;
                            v2[1, 0] = edges[mod].P1.Y - edges[mod].P2.Y;

                            // this equation is quoted from http://www.mathworks.com/matlabcentral/newsreader/view_thread/276582
                            // and it is working very good

                            angle = Math.Atan2(Math.Abs(det(v1, v2)), dot(v1, v2)) * (180.0 / Math.PI);

                            if (angle < 90)
                            {
                                direction = dir(edges[ij].P1, edges[ij].P2, edges[mod].P2);

                                if (direction > 0)
                                {
                                    if (
                                        ((edges[ij].Length <max_length && edges[ij].Length> min_length)
                                         ||
                                         (edges[mod].Length <max_length && edges[mod].Length> min_length))

                                        )
                                    {
                                        if (!tester_valley)
                                        {
                                            tester_valley   = true;
                                            refernce_valley = edges[ij].P2;

                                            numberOfValleys++;
                                        }
                                        else if (FindDistance(edges[ij].P2, first_valley) < min_length &&
                                                 FindDistance(edges[ij].P2, first_valley) > (0.5 * min_length)
                                                 //  && FindDistance(edges[ij].P2,center_pts) > min_length
                                                 //    && FindDistance(edges[ij].P2, center_pts) < max_length
                                                 )
                                        {
                                            if (tester_peak)
                                            {
                                                if (FindDistance(edges[ij].P2, first_peak) > min_length
                                                    &&
                                                    FindDistance(edges[ij].P2, first_peak) < max_length
                                                    )
                                                {
                                                    numberOfValleys++;
                                                }
                                            }
                                        }
                                        else if (FindDistance(edges[ij].P2, refernce_valley) < min_length &&
                                                 FindDistance(edges[ij].P2, refernce_valley) > (0.5 * min_length)
                                                 //   && FindDistance(edges[ij].P2, center_pts) > min_length
                                                 //     && FindDistance(edges[ij].P2, center_pts) < max_length
                                                 )
                                        {
                                            numberOfValleys++;
                                        }


                                        first_valley = edges[ij].P2;
                                    }
                                }

                                else
                                {
                                    if (
                                        (edges[ij].Length <max_length && edges[ij].Length> min_length)
                                        ||
                                        (edges[mod].Length <max_length && edges[mod].Length> min_length)

                                        )
                                    {
                                        if (!tester_peak)
                                        {
                                            tester_peak    = true;
                                            reference_peak = edges[ij].P2;
                                            numberOfPeaks++;
                                        }
                                        else if (FindDistance(edges[ij].P2, first_peak) > min_length
                                                 &&
                                                 FindDistance(edges[ij].P2, first_peak) < max_length)
                                        {
                                            if (tester_valley)
                                            {
                                                if (FindDistance(edges[ij].P2, first_valley) > min_length
                                                    &&
                                                    FindDistance(edges[ij].P2, first_valley) < max_length
                                                    )
                                                {
                                                    numberOfPeaks++;
                                                }
                                            }
                                        }

                                        else if (FindDistance(edges[ij].P2, reference_peak) > min_length
                                                 &&
                                                 FindDistance(edges[ij].P2, reference_peak) < max_length)
                                        {
                                            numberOfPeaks++;
                                        }

                                        first_peak = edges[ij].P2;
                                    }
                                }
                            }
                        }

                        if (numberOfPeaks >= 3 && numberOfValleys >= 3)
                        {
                            //double diff = CvInvoke.cvMatchShapes(i.Ptr, temp_contour.Ptr, CONTOURS_MATCH_TYPE.CV_CONTOUR_MATCH_I1, 0);

                            //  if (diff < 0.1)
                            //  {
                            newImage.Draw(i.BoundingRectangle, color_blue, 2);
                            imageBoxSkin.Image = newImage;

                            if (!hand_centers.Any())
                            {
                                hand_centers.Add(0, center_pt);
                            }
                            else
                            {
                                double dis = FindDistance(center_pt, hand_centers[0]);
                                if (dis < 200)
                                {
                                    continue;
                                }
                                else
                                {
                                    hand_centers.Add(1, center_pt);
                                }
                            }

                            Rectangle te = i.BoundingRectangle;

                            int teHeight = (int)(max_length + min_length);

                            if (te.Height > teHeight)
                            {
                                te.Height = teHeight;
                            }

                            if (te.Width > teHeight)
                            {
                                te.Width = teHeight;
                            }

                            skin.ROI = te;
                            Contour <Point> hand_ = ExtractBiggestContour(skin);

                            if (hand_ != null)
                            {
                                handCandiate.Add(hand_);
                            }


                            skin.ROI = Rectangle.Empty;
                            //  }
                        }


                        //    }


                        numberOfPeaks   = 0;
                        numberOfValleys = 0;
                    }
                }
            }

            return(handCandiate);
        }
Beispiel #28
0
        public string ProcessAndRender(IInputArray imageIn, IInputOutputArray imageOut)
        {
            Stopwatch watch = Stopwatch.StartNew();

            #region Pre-processing
            //Convert the image to grayscale and filter out the noise
            CvInvoke.CvtColor(imageIn, _gray, ColorConversion.Bgr2Gray);
            //Remove noise
            CvInvoke.GaussianBlur(_gray, _gray, new Size(3, 3), 1);
            double cannyThreshold        = 180.0;
            double cannyThresholdLinking = 120.0;
            CvInvoke.Canny(_gray, _cannyEdges, cannyThreshold, cannyThresholdLinking);
            #endregion

            #region circle detection
            double    circleAccumulatorThreshold = 120;
            CircleF[] circles = CvInvoke.HoughCircles(_gray, HoughModes.Gradient, 2.0, 20.0, cannyThreshold,
                                                      circleAccumulatorThreshold, 5);
            #endregion

            #region Edge detection
            LineSegment2D[] lines = CvInvoke.HoughLinesP(
                _cannyEdges,
                1,              //Distance resolution in pixel-related units
                Math.PI / 45.0, //Angle resolution measured in radians.
                20,             //threshold
                30,             //min Line width
                10);            //gap between lines
            #endregion

            #region Find triangles and rectangles
            List <Triangle2DF> triangleList = new List <Triangle2DF>();
            List <RotatedRect> boxList      = new List <RotatedRect>(); //a box is a rotated rectangle
            using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
            {
                CvInvoke.FindContours(_cannyEdges, contours, null, RetrType.List,
                                      ChainApproxMethod.ChainApproxSimple);
                int count = contours.Size;
                for (int i = 0; i < count; i++)
                {
                    using (VectorOfPoint contour = contours[i])
                        using (VectorOfPoint approxContour = new 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));
                                    }
                                }
                            }
                        }
                }
            }
            #endregion

            watch.Stop();

            using (Mat triangleRectangleImage = new Mat(_gray.Size, DepthType.Cv8U, 3)) //image to draw triangles and rectangles on
                using (Mat circleImage = new Mat(_gray.Size, DepthType.Cv8U, 3))        //image to draw circles on
                    using (Mat lineImage = new Mat(_gray.Size, DepthType.Cv8U, 3))      //image to draw lines on
                    {
                        #region draw triangles and rectangles

                        triangleRectangleImage.SetTo(new MCvScalar(0));
                        foreach (Triangle2DF triangle in triangleList)
                        {
                            CvInvoke.Polylines(triangleRectangleImage,
                                               Array.ConvertAll(triangle.GetVertices(), Point.Round),
                                               true, new Bgr(Color.DarkBlue).MCvScalar, 2);
                        }

                        foreach (RotatedRect box in boxList)
                        {
                            CvInvoke.Polylines(triangleRectangleImage, Array.ConvertAll(box.GetVertices(), Point.Round),
                                               true,
                                               new Bgr(Color.DarkOrange).MCvScalar, 2);
                        }

                        //Drawing a light gray frame around the image
                        CvInvoke.Rectangle(triangleRectangleImage,
                                           new Rectangle(Point.Empty,
                                                         new Size(triangleRectangleImage.Width - 1, triangleRectangleImage.Height - 1)),
                                           new MCvScalar(120, 120, 120));
                        //Draw the labels
                        CvInvoke.PutText(triangleRectangleImage, "Triangles and Rectangles", new Point(20, 20),
                                         FontFace.HersheyDuplex, 0.5, new MCvScalar(120, 120, 120));

                        #endregion

                        #region draw circles

                        circleImage.SetTo(new MCvScalar(0));
                        foreach (CircleF circle in circles)
                        {
                            CvInvoke.Circle(circleImage, Point.Round(circle.Center), (int)circle.Radius,
                                            new Bgr(Color.Brown).MCvScalar, 2);
                        }

                        //Drawing a light gray frame around the image
                        CvInvoke.Rectangle(circleImage,
                                           new Rectangle(Point.Empty, new Size(circleImage.Width - 1, circleImage.Height - 1)),
                                           new MCvScalar(120, 120, 120));
                        //Draw the labels
                        CvInvoke.PutText(circleImage, "Circles", new Point(20, 20), FontFace.HersheyDuplex, 0.5,
                                         new MCvScalar(120, 120, 120));

                        #endregion

                        #region draw lines

                        lineImage.SetTo(new MCvScalar(0));
                        foreach (LineSegment2D line in lines)
                        {
                            CvInvoke.Line(lineImage, line.P1, line.P2, new Bgr(Color.Green).MCvScalar, 2);
                        }
                        //Drawing a light gray frame around the image
                        CvInvoke.Rectangle(lineImage,
                                           new Rectangle(Point.Empty, new Size(lineImage.Width - 1, lineImage.Height - 1)),
                                           new MCvScalar(120, 120, 120));
                        //Draw the labels
                        CvInvoke.PutText(lineImage, "Lines", new Point(20, 20), FontFace.HersheyDuplex, 0.5,
                                         new MCvScalar(120, 120, 120));

                        #endregion


                        using (InputArray iaImageIn = imageIn.GetInputArray())
                            using (Mat imageInMat = iaImageIn.GetMat())
                                CvInvoke.VConcat(new Mat[] { imageInMat, triangleRectangleImage, circleImage, lineImage }, imageOut);
                    }
            return(String.Format("Detected in {0} milliseconds.", watch.ElapsedMilliseconds));
        }
Beispiel #29
0
        //megkeresi a négyszögeket a képen. A felismert négyszögeket méretük alapján megpróbálja kategóriákba sorolni és csak azokat tekinti négyszögnek, amelyek a legtöbb elemszámú kategóriába esnek. Ezzel elkerülve, hogy pl a rajzlapot is felismerje négyszögként
        private Image <Bgr, Byte> GetRectangles(Image <Bgr, Byte> img, out List <MCvBox2D> boxlist)
        {
            Image <Gray, Byte> gray = img.Convert <Gray, Byte>();

            Image <Gray, Byte> cannyEdges = img.Canny(100.0, 60.0);


            List <MCvBox2D> boxList = new List <MCvBox2D>();
            Contour <Point> contours;

            using (MemStorage storage = new MemStorage())
                for (
                    contours = cannyEdges.FindContours(
                        Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                        Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST,
                        storage);
                    contours != null;
                    contours = contours.HNext)
                {
                    Contour <Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage);

                    if (currentContour.Total == 4 && currentContour.Area > 50)
                    {
                        bool            isRectangle = true;
                        Point[]         pts         = currentContour.ToArray();
                        LineSegment2D[] edges       = PointCollection.PolyLine(pts, true);

                        for (int i = 0; i < edges.Length; i++)
                        {
                            double angle = Math.Abs(
                                edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i]));
                            if (angle < 80 || angle > 100)
                            {
                                isRectangle = false;
                                break;
                            }
                        }

                        if (isRectangle)
                        {
                            boxList.Add(currentContour.GetMinAreaRect());
                        }
                    }
                }

            Image <Bgr, Byte> triangleRectangleImage = img.Copy();
            bool tmp = false;
            int  avg = 0;
            int  max = 0;

            int[,] discVal = new int[20, 2];
            foreach (MCvBox2D box in boxList)
            {
                int i = box.MinAreaRect().Width / 10;
                if (i < 20 && i > 3)
                {
                    discVal[i, 0] += box.MinAreaRect().Width;
                    discVal[i, 1]++;
                    if (discVal[i, 1] > discVal[max, 1])
                    {
                        max = i;
                    }
                }
            }
            if (discVal[max, 1] != 0)
            {
                avg = discVal[max, 0] / discVal[max, 1];
            }

            for (int i = 0; i < boxList.Count; i++)
            {
                if (boxList[i].MinAreaRect().Width > avg - 10 && boxList[i].MinAreaRect().Width < avg + 10)
                {
                    triangleRectangleImage.Draw(boxList[i], new Bgr(0, 255, 0), 2);

                    for (int j = i + 1; j < boxList.Count; j++)
                    {
                        double dist = Math.Sqrt((boxList[i].center.X - boxList[j].center.X) * (boxList[i].center.X - boxList[j].center.X) + (boxList[i].center.Y - boxList[j].center.Y) * (boxList[i].center.Y - boxList[j].center.Y));
                        if (dist < 10)
                        {
                            boxList.RemoveAt(j);
                        }
                    }
                }
                else
                {
                    boxList.RemoveAt(i);
                    i--;
                }
            }

            boxlist = boxList;
            return(triangleRectangleImage); //cannyEdges.Convert<Bgr, Byte>();
        }
Beispiel #30
0
        /// <summary>
        ///
        /// </summary>
        public void PerformShapeDetection()
        {
            {
                StringBuilder msgBuilder = new StringBuilder("Performance: ");

                int w = 1665, h = 2286;
                //Load the image from file and resize it for display
                Image <Bgr, Byte> img = new Image <Bgr, byte>(@"D:\paper\1456141019_地理_p1.tif").Resize(w, h, Emgu.CV.CvEnum.Inter.Linear, true);

                //图片转换为灰度
                UMat uimage           = new UMat();
                CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray);

                //去噪处理
                UMat pyrDown = new UMat();
                CvInvoke.PyrDown(uimage, pyrDown);
                CvInvoke.PyrUp(pyrDown, uimage);
                Stopwatch watch      = Stopwatch.StartNew();
                UMat      cannyEdges = new UMat();
                //Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp();
                double cannyThreshold = 360.0;
#if false
                #region 1、识别圆形


                double    circleAccumulatorThreshold = 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
#endif
                #region Canny and edge detection
                watch.Reset(); watch.Start();
                double cannyThresholdLinking = 120.0;

                CvInvoke.Canny(uimage, cannyEdges, cannyThreshold, cannyThresholdLinking);

                LineSegment2D[] lines = CvInvoke.HoughLinesP(
                    cannyEdges,
                    1,       //Distance resolution in pixel-related units
                    Math.PI, //Angle resolution measured in radians.
                    20,      //threshold
                    30,      //min Line width
                    10);     //gap between lines 间隔

                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 (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint())
                {
                    CvInvoke.FindContours(cannyEdges, contours, null, RetrType.List, ChainApproxMethod.ChainApproxSimple);
                    int count = contours.Size;
                    for (int i = 0; i < count; i++)
                    {
                        using (VectorOfPoint contour = contours[i])
                            using (VectorOfPoint approxContour = new VectorOfPoint())
                            {
                                CvInvoke.ApproxPolyDP(contour, approxContour, CvInvoke.ArcLength(contour, true) * 0.05, true);
                                if (CvInvoke.ContourArea(approxContour, false) > 25) //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 确定轮廓所有的角度都在[ 80, 100 ]度之间
                                        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 1、识别圆形

                this.Text = msgBuilder.ToString();
                img.Save("D:\\aaaa.tiff");
                #region draw triangles and rectangles
                Mat triangleRectangleImage = new Mat(img.Size, DepthType.Cv8U, 3);
                triangleRectangleImage.SetTo(new MCvScalar(0));//三角形
                //foreach (Triangle2DF triangle in triangleList)
                //{
                //    CvInvoke.Polylines(triangleRectangleImage, Array.ConvertAll(triangle.GetVertices(), Point.Round), true, new Bgr(Color.DarkBlue).MCvScalar, 2);
                //}
                foreach (RotatedRect box in boxList)
                {
                    CvInvoke.Polylines(triangleRectangleImage, Array.ConvertAll(box.GetVertices(), Point.Round), true, new Bgr(Color.DarkOrange).MCvScalar, 2);
                }
                triangleRectangleImage.Save("D:\\ccc.tiff");
                this.pictureBox1.Image = triangleRectangleImage.Bitmap;
                #endregion
            }
        }