Пример #1
0
        private void LoadImage(string filePath)
        {
            try
            {
                using (Mat image = new Mat(filePath))
                    using (Mat resized = image.Resize(GetTargetSize(image.Size()))) //Scale the image, so we are working with something consistent
                    {
                        AddImage(resized);

                        using (Mat gray = resized.CvtColor(ColorConversionCodes.BGR2GRAY)) //Convert to gray scale since we don't want the color data
                            using (Mat blur = gray.GaussianBlur(new Size(5, 5), 0))        //Smooth the image to eliminate noise
                                using (Mat autoCanny = blur.AutoCanny())                   //Apply canny edge filter to find edges
                                    using (Mat structuringElement = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(9, 9)))
                                    {
                                        AddImage(autoCanny);

                                        //Smooth over small possible breaks in edges
                                        Cv2.Dilate(autoCanny, autoCanny, structuringElement);
                                        AddImage(autoCanny);
                                        Cv2.Erode(autoCanny, autoCanny, structuringElement);
                                        AddImage(autoCanny);

                                        //Change the RetrievalModes to CComp if you want internal polygons too, not just the outer most one.
                                        Point[][] contours = autoCanny.FindContoursAsArray(RetrievalModes.External, ContourApproximationModes.ApproxSimple);

                                        //Draw all of the found polygons for reference
                                        using (Mat allFound = resized.Clone())
                                        {
                                            for (int i = 0; i < contours.Length; i++)
                                            {
                                                Cv2.DrawContours(allFound, contours, i, Scalar.RandomColor(), 2);
                                            }
                                            AddImage(allFound);
                                        }

                                        //Find the largest polygons that four corners
                                        var found = (from contour in contours
                                                     let permimiter = Cv2.ArcLength(contour, true)
                                                                      let approx = Cv2.ApproxPolyDP(contour, 0.04 * permimiter, true)
                                                                                   where approx.Length == 4                     //Rectange
                                                                                   let area = Cv2.ContourArea(approx)
                                                                                              orderby area descending           //We are looking for the biggest thing
                                                                                              select approx).Take(3).ToArray(); //Grabbing three just for comparison

                                        //Colors the found polygons Green->Yellow->Red to indicate best matches.
                                        for (int i = 0; i < found.Length; i++)
                                        {
                                            Scalar color;
                                            switch (i)
                                            {
                                            case 0:
                                                color = Scalar.Green;
                                                break;

                                            case 1:
                                                color = Scalar.Yellow;
                                                break;

                                            case 2:
                                                color = Scalar.Red;
                                                break;

                                            default:
                                                color = Scalar.RandomColor();
                                                break;
                                            }

                                            resized.DrawContours(found, i, color, 3);
                                        }
                                        AddImage(resized);
                                    }
                    }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
            }

            Size GetTargetSize(Size size, int longSize = 512)
            {
                if (size.Width > size.Height)
                {
                    return(new Size(longSize, (int)(longSize * (double)size.Height / size.Width)));
                }
                return(new Size((int)(longSize * (double)size.Width / size.Height), longSize));
            }
        }
        private void LoadImage(string filePath)
        {
            //using (Mat mat1 = Mat.Zeros(2048, 1536, MatType.CV_8UC1))
            //using (Mat mat2 = Mat.Zeros(2048, 1536, MatType.CV_8UC1))
            //using (var intersection = new Mat(2048, 1536, MatType.CV_8UC1))
            //using (var union = new Mat(2048, 1536, MatType.CV_8UC1))
            //{
            //    mat1.FillPoly(new[] { new[]
            //    {
            //        new Point(565, 267),
            //        new Point(1210, 207),
            //        new Point(1275, 1720),
            //        new Point(568, 1688)
            //    } }, Scalar.All(255));
            //    AddImage(mat1);
            //    mat2.FillPoly(new[] { new[]
            //    {
            //        new Point(564, 268),
            //        new Point(1208, 208),
            //        new Point(1272, 1716),
            //        new Point(572, 1688)
            //    } }, Scalar.All(255));
            //    AddImage(mat2);
            //    Cv2.BitwiseAnd(mat1, mat2, intersection);
            //    int intersectionPixels = Cv2.CountNonZero(intersection);
            //    AddImage(intersection);
            //    Cv2.BitwiseOr(mat1, mat2, union);
            //    int unionPixels = Cv2.CountNonZero(union);
            //    AddImage(union);
            //    double iou = (double) intersectionPixels / unionPixels;
            //}
            //
            //return;

            try
            {
                using (Mat image = new Mat(filePath))
                    using (Mat resized = image.Resize(GetTargetSize(image.Size()))) //Scale the image, so we are working with something consistent
                    {
                        AddImage(resized);

                        using (Mat gray = resized.CvtColor(ColorConversionCodes.BGRA2GRAY))                            //Convert to gray scale since we don't want the color data
                            using (Mat blur = gray.GaussianBlur(new Size(5, 5), 0, borderType: BorderTypes.Replicate)) //Smooth the image to eliminate noise
                                using (Mat autoCanny = blur.AutoCanny(0.75))                                           //Apply canny edge filter to find edges
                                {
                                    AddImage(blur);
                                    AddImage(autoCanny);

                                    Point[][] contours = autoCanny.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxSimple);

                                    //Just get the external hull of the contours
                                    for (int i = 0; i < contours.Length; i++)
                                    {
                                        contours[i] = Cv2.ConvexHull(contours[i]);
                                    }

                                    //Draw all of the found polygons. This is just for reference
                                    using (Mat allFound = resized.Clone())
                                    {
                                        for (int i = 0; i < contours.Length; i++)
                                        {
                                            Cv2.DrawContours(allFound, contours, i, Scalar.RandomColor(), 2);
                                        }
                                        AddImage(allFound);
                                    }

                                    //Find the largest polygons that four corners
                                    var found = (from contour in contours
                                                 let permimiter = Cv2.ArcLength(contour, true)
                                                                  let approx = Cv2.ApproxPolyDP(contour, 0.02 * permimiter, true)
                                                                               where IsValidRectangle(approx, 0.2)
                                                                               let area = Cv2.ContourArea(contour)
                                                                                          orderby area descending            //We are looking for the biggest thing
                                                                                          select contour).Take(3).ToArray(); //Grabbing three just for comparison

                                    //Colors the found polygons Green->Yellow->Red to indicate best matches.
                                    for (int i = found.Length - 1; i >= 0; i--)
                                    {
                                        Scalar color;
                                        switch (i)
                                        {
                                        case 0:
                                            color = Scalar.Green;
                                            break;

                                        case 1:
                                            color = Scalar.Yellow;
                                            break;

                                        case 2:
                                            color = Scalar.Red;
                                            break;

                                        default:
                                            color = Scalar.RandomColor();
                                            break;
                                        }

                                        resized.DrawContours(found, i, color, 3);
                                    }
                                    AddImage(resized);
                                }
                    }
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
            }

            bool IsValidRectangle(Point[] contour, double minimum)
            {
                if (contour.Length != 4)
                {
                    return(false);
                }
                double side1 = GetLength(contour[0], contour[1]);
                double side2 = GetLength(contour[1], contour[2]);
                double side3 = GetLength(contour[2], contour[3]);
                double side4 = GetLength(contour[3], contour[0]);

                if (Math.Abs(side1 - side3) / Math.Max(side1, side3) > minimum)
                {
                    return(false);
                }
                if (Math.Abs(side2 - side4) / Math.Max(side2, side4) > minimum)
                {
                    return(false);
                }

                return(true);

                double GetLength(Point p1, Point p2) => Math.Abs(p1.X - p2.X) + Math.Abs(p1.Y - p2.Y);
            }

            Size GetTargetSize(Size size, int longSize = 512)
            {
                if (size.Width > size.Height)
                {
                    return(new Size(longSize, (int)(longSize * (double)size.Height / size.Width)));
                }
                return(new Size((int)(longSize * (double)size.Width / size.Height), longSize));
            }
        }