예제 #1
0
        public static List <Point[]> SelectMarkers(List <Point[]> candidateCorners, Bitmap undistoredImage)
        {
            return(candidateCorners.Where(corners =>
            {
                int minX = int.MaxValue;
                int maxX = int.MinValue;
                int minY = int.MaxValue;
                int maxY = int.MinValue;
                double perimeter = 0;
                for (int i = 0; i < corners.Length; i++)
                {
                    perimeter += Math.Sqrt(Math.Pow(corners[i].X - corners[(i + 1) % corners.Length].X, 2) +
                                           Math.Pow(corners[i].Y - corners[(i + 1) % corners.Length].Y, 2));
                    minX = Math.Min(minX, corners[i].X);
                    maxX = Math.Max(maxX, corners[i].X);
                    minY = Math.Min(minY, corners[i].Y);
                    maxY = Math.Max(maxY, corners[i].Y);
                }

                var side = perimeter / 4;

                var total_cnt = 0;
                var border_cnt = 0;
                double border_sum = 0;
                for (int x = minX; x <= maxX; x++)
                {
                    for (int y = minY; y <= maxY; y++)
                    {
                        if (CornerDetector.checkPointInPolygon(new Point(x, y), corners.ToList()))
                        {
                            total_cnt++;
                            var dist = Douglas_Peucker.CalcDistFromPointToPolygon(new Point(x, y), corners);
                            var pixel = undistoredImage.GetPixel(x, y);
                            var res = 0.21 * pixel.R + 0.72 * pixel.G + 0.07 * pixel.B;
                            if (dist < side * borderRate)
                            {
                                border_cnt++;
                                border_sum += res;
                            }
                        }
                    }
                }

                var average = border_sum / border_cnt;

                return average <= blackThreshold;
            }).ToList());
        }
예제 #2
0
        public static List <Point[]> FindCorners(MyImage source)
        {
            var dx = new int[] { 1, -1, 0, 0 };
            var dy = new int[] { 0, 0, 1, -1 };

            var minMarkerPerimeterRate = 0.05;
            var minDimension           = Math.Min(source.Height, source.Width);
            var minPerimeter           = minDimension * minMarkerPerimeterRate;

            Console.WriteLine("MinPerimeter = " + minPerimeter);

            var candidateCorners = new List <List <Point> >();
            var visited          = new bool[source.Height, source.Width];

            for (int x = 1; x < source.Height - 1; x++)
            {
                for (int y = 1; y < source.Width - 1; y++)
                {
                    if (!visited[x, y] && source.red[x, y] >= whiteThreshold)
                    {
                        var points = new List <Point>();

                        var queue      = new Queue <Point>();
                        var startPixel = new Point(x, y);

                        queue.Enqueue(startPixel);
                        visited[x, y] = true;

                        while (queue.Count > 0)
                        {
                            var currentPixel = queue.Dequeue();

                            points.Add(currentPixel);

                            for (int direction = 0; direction < dx.Length; direction++)
                            {
                                var nextPoint = new Point(currentPixel.X + dx[direction], currentPixel.Y + dy[direction]);
                                if (!visited[nextPoint.X, nextPoint.Y] && source.red[nextPoint.X, nextPoint.Y] >= whiteThreshold)
                                {
                                    queue.Enqueue(nextPoint);
                                    visited[nextPoint.X, nextPoint.Y] = true;
                                }
                            }
                        }

                        points = SortPoints(points);
                        var corners = new List <Point>();
                        Douglas_Peucker.DouglasPeucker(points, 0, points.Count - 1, ref corners, true);

                        double perimeter = 0;
                        var    minSide   = double.MaxValue;
                        var    maxSide   = double.MinValue;
                        for (int i = 0; i < corners.Count; i++)
                        {
                            var side = Math.Sqrt(Math.Pow(corners[i].X - corners[(i + 1) % corners.Count].X, 2) +
                                                 Math.Pow(corners[i].Y - corners[(i + 1) % corners.Count].Y, 2));

                            perimeter += side;
                            minSide    = Math.Min(minSide, side);
                            maxSide    = Math.Max(maxSide, side);
                        }

                        if (corners.Count == 4 &&
                            minSide / maxSide > 0.6 &&
                            perimeter >= minPerimeter)
                        {
                            Console.WriteLine("corner 1: " + corners[0]);
                            Console.WriteLine(minSide + " " + maxSide + " " + minSide / maxSide + " " + perimeter);

                            candidateCorners.Add(corners);
                        }
                    }
                    ;
                }
            }
            ;

            return(candidateCorners.Select(c => c.Select(p => new Point(p.Y, p.X)).ToArray()).ToList());
        }