Graham scan algorithm for finding convex hull.

The class implements Graham scan algorithm for finding convex hull of a given set of points.

Sample usage:

// generate some random points Random rand = new Random( ); List<IntPoint> points = new List<IntPoint>( ); for ( int i = 0; i < 10; i++ ) { points.Add( new IntPoint( rand.Next( 200 ) - 100, rand.Next( 200 ) - 100 ) ); } // find the convex hull IConvexHullAlgorithm hullFinder = new GrahamConvexHull( ); List<IntPoint> hull = hullFinder.FindHull( points );
Inheritance: IConvexHullAlgorithm
        public void FindTest()
        {
            List<IntPoint> contour = new List<IntPoint>();

            int max = 100;

            for (int i = 0; i < max; i++)
                add(contour, i, max);

            for (int i = 0; i < max; i++)
                add(contour, max, i);

            for (int i = 0; i < max; i++)
                add(contour, 0, i);

            for (int i = 0; i < max / 2; i++)
                add(contour, i, i);

            for (int i = 0; i < max / 2; i++)
                add(contour, i + max / 2, max / 2 - i);

            PointsMarker marker = new PointsMarker(contour);
            var bitmap = Accord.Imaging.Image.CreateGrayscaleImage(max + 1, max + 1);
            bitmap = marker.Apply(bitmap);
            // Accord.Controls.ImageBox.Show(bitmap);

            GrahamConvexHull graham = new GrahamConvexHull();
            List<IntPoint> hull = graham.FindHull(contour);
            ConvexHullDefects hullDefects = new ConvexHullDefects(10);
            List<ConvexityDefect> defects = hullDefects.FindDefects(contour, hull);

            Assert.AreEqual(1, defects.Count);
            Assert.AreEqual(99, defects[0].Depth);
        }
        public void FindDefectsTest()
        {
            Bitmap bmp = Accord.Imaging.Image.Clone(Properties.Resources.hand);

            Bitmap gray = Accord.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(bmp);

            BlobCounter bc = new BlobCounter(gray);
            bc.ObjectsOrder = ObjectsOrder.Size;
            Blob[] blobs = bc.GetObjectsInformation();
            bc.ExtractBlobsImage(bmp, blobs[0], true);

            Bitmap blob = blobs[0].Image.ToManagedImage();

            BorderFollowing bf = new BorderFollowing();
            List<IntPoint> contour = bf.FindContour(blob);

            GrahamConvexHull graham = new GrahamConvexHull();
            List<IntPoint> hull = graham.FindHull(contour);

            ConvexHullDefects hullDefects = new ConvexHullDefects(10);
            List<ConvexityDefect> defects = hullDefects.FindDefects(contour, hull);

          /*  PointsMarker marker = new PointsMarker(hull, Color.Green, 10);
            marker.ApplyInPlace(blob);
            ImageBox.Show(blob);
            */

            Assert.AreEqual(2, defects.Count);
            Assert.AreEqual(new IntPoint(130, 10), contour[defects[0].Start]);
            Assert.AreEqual(new IntPoint(93, 109), contour[defects[0].Point]);
            Assert.AreEqual(new IntPoint(64, 9), contour[defects[0].End]);
            Assert.AreEqual(99.549179077148438, defects[0].Depth, 1e-5);
            Assert.IsFalse(double.IsNaN(defects[0].Depth));
            //    Assert.AreEqual(9912.9531239366424, defects[0].Area);

            Assert.AreEqual(new IntPoint(49, 18), contour[defects[1].Start]);
            Assert.AreEqual(new IntPoint(61, 106), contour[defects[1].Point]);
            Assert.AreEqual(new IntPoint(18, 127), contour[defects[1].End]);
            Assert.AreEqual(35.615153852366504, defects[1].Depth, 1e-5);
            Assert.IsFalse(double.IsNaN(defects[1].Depth));
            //    Assert.AreEqual(2293.7535682510002, defects[1].Area);

        }
Exemple #3
0
        // Set image to display by the control
        public int SetImage(Bitmap image)
        {
            leftEdges.Clear();
            rightEdges.Clear();
            topEdges.Clear();
            bottomEdges.Clear();
            hulls.Clear();
            quadrilaterals.Clear();

            selectedBlobID = 0;

            this.image = Accord.Imaging.Image.Clone(image, PixelFormat.Format24bppRgb);
            imageWidth = this.image.Width;
            imageHeight = this.image.Height;

            blobCounter.ProcessImage(this.image);
            blobs = blobCounter.GetObjectsInformation();

            GrahamConvexHull grahamScan = new GrahamConvexHull();

            foreach (Blob blob in blobs)
            {
                List<IntPoint> leftEdge = new List<IntPoint>();
                List<IntPoint> rightEdge = new List<IntPoint>();
                List<IntPoint> topEdge = new List<IntPoint>();
                List<IntPoint> bottomEdge = new List<IntPoint>();

                // collect edge points
                blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge);
                blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge);

                leftEdges.Add(blob.ID, leftEdge);
                rightEdges.Add(blob.ID, rightEdge);
                topEdges.Add(blob.ID, topEdge);
                bottomEdges.Add(blob.ID, bottomEdge);

                // find convex hull
                List<IntPoint> edgePoints = new List<IntPoint>();
                edgePoints.AddRange(leftEdge);
                edgePoints.AddRange(rightEdge);

                List<IntPoint> hull = grahamScan.FindHull(edgePoints);
                hulls.Add(blob.ID, hull);

                List<IntPoint> quadrilateral = null;

                // find quadrilateral
                if (hull.Count < 4)
                {
                    quadrilateral = new List<IntPoint>(hull);
                }
                else
                {
                    quadrilateral = PointsCloud.FindQuadrilateralCorners(hull);
                }
                quadrilaterals.Add(blob.ID, quadrilateral);

                // shift all points for vizualization
                IntPoint shift = new IntPoint(1, 1);

                PointsCloud.Shift(leftEdge, shift);
                PointsCloud.Shift(rightEdge, shift);
                PointsCloud.Shift(topEdge, shift);
                PointsCloud.Shift(bottomEdge, shift);
                PointsCloud.Shift(hull, shift);
                PointsCloud.Shift(quadrilateral, shift);
            }

            UpdatePosition();
            Invalidate();

            return blobs.Length;
        }
        public void FindHullTest( )
        {
            GrahamConvexHull grahamHull = new GrahamConvexHull( );

            for ( int i = 0, n = pointsLists.Count; i < n; i++ )
            {
                ComparePointsLists( grahamHull.FindHull( pointsLists[i] ), expectedHulls[i] );
            }
        }