AForge.Math.Geometry.SimpleShapeChecker.CheckPolygonSubType C# (CSharp) Method

CheckPolygonSubType() public method

Check sub type of a convex polygon.

The method check corners of a convex polygon detecting its subtype. Polygon's corners are usually retrieved using IsConvexPolygon method, but can be any list of 3-4 points (only sub types of triangles and quadrilateral are checked).

See AngleError and LengthError properties, which set acceptable errors for polygon sub type checking.

public CheckPolygonSubType ( List corners ) : PolygonSubType
corners List Corners of the convex polygon to check.
return PolygonSubType
        public PolygonSubType CheckPolygonSubType( List<IntPoint> corners )
        {
            PolygonSubType subType = PolygonSubType.Unknown;

            // get bounding rectangle of the points list
            IntPoint minXY, maxXY;
            PointsCloud.GetBoundingRectangle( corners, out minXY, out maxXY );
            // get cloud's size
            IntPoint cloudSize = maxXY - minXY;

            float maxLengthDiff = lengthError * ( cloudSize.X + cloudSize.Y ) / 2;

            if ( corners.Count == 3 )
            {
                // get angles of the triangle
                float angle1 = GeometryTools.GetAngleBetweenVectors( corners[0], corners[1], corners[2] );
                float angle2 = GeometryTools.GetAngleBetweenVectors( corners[1], corners[2], corners[0] );
                float angle3 = GeometryTools.GetAngleBetweenVectors( corners[2], corners[0], corners[1] );

                // check for equilateral triangle
                if ( ( Math.Abs( angle1 - 60 ) <= angleError ) &&
                     ( Math.Abs( angle2 - 60 ) <= angleError ) &&
                     ( Math.Abs( angle3 - 60 ) <= angleError ) )
                {
                    subType = PolygonSubType.EquilateralTriangle;
                }
                else
                {
                    // check for isosceles triangle
                    if ( ( Math.Abs( angle1 - angle2 ) <= angleError ) ||
                         ( Math.Abs( angle2 - angle3 ) <= angleError ) ||
                         ( Math.Abs( angle3 - angle1 ) <= angleError ) )
                    {
                        subType = PolygonSubType.IsoscelesTriangle;
                    }

                    // check for rectangled triangle
                    if ( ( Math.Abs( angle1 - 90 ) <= angleError ) ||
                         ( Math.Abs( angle2 - 90 ) <= angleError ) ||
                         ( Math.Abs( angle3 - 90 ) <= angleError ) )
                    {
                        subType = ( subType == PolygonSubType.IsoscelesTriangle ) ?
                            PolygonSubType.RectangledIsoscelesTriangle : PolygonSubType.RectangledTriangle;
                    }
                }
            }
            else if ( corners.Count == 4 )
            {
                // get angles between 2 pairs of opposite sides
                float angleBetween1stPair = GeometryTools.GetAngleBetweenLines( corners[0], corners[1], corners[2], corners[3] );
                float angleBetween2ndPair = GeometryTools.GetAngleBetweenLines( corners[1], corners[2], corners[3], corners[0] );

                // check 1st pair for parallelism
                if ( angleBetween1stPair <= angleError )
                {
                    subType = PolygonSubType.Trapezoid;

                    // check 2nd pair for parallelism
                    if ( angleBetween2ndPair <= angleError )
                    {
                        subType = PolygonSubType.Parallelogram;

                        // check angle between adjacent sides
                        if ( Math.Abs( GeometryTools.GetAngleBetweenVectors( corners[1], corners[0], corners[2] ) - 90 ) <= angleError )
                        {
                            subType = PolygonSubType.Rectangle;
                        }

                        // get length of 2 adjacent sides
                        float side1Length = (float) corners[0].DistanceTo( corners[1] );
                        float side2Length = (float) corners[0].DistanceTo( corners[3] );

                        if ( Math.Abs( side1Length - side2Length ) <= maxLengthDiff )
                        {
                            subType = ( subType == PolygonSubType.Parallelogram ) ?
                                PolygonSubType.Rhombus : PolygonSubType.Square;
                        }
                    }
                }
                else
                {
                    // check 2nd pair for parallelism - last chence to detect trapezoid
                    if ( angleBetween2ndPair <= angleError )
                    {
                        subType = PolygonSubType.Trapezoid;
                    }
                }
            }

            return subType;
        }

Usage Example

Example #1
0
        public static void Rectangle(WriteableBitmap bitmap, DrawingContext dc)
        {
            // locating objects
            BlobCounter blobCounter = new BlobCounter();
            blobCounter.FilterBlobs = true;
            blobCounter.MaxHeight = 375;
            blobCounter.MaxWidth = 375;
            System.Drawing.Bitmap image;
            using (var stream = new MemoryStream())
            {
                var encoder = new JpegBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bitmap));
                encoder.Save(stream);
                image = new System.Drawing.Bitmap(stream);
            }
            blobCounter.ProcessImage(image);
            Blob[] blobs = blobCounter.GetObjectsInformation();

            // check for rectangles
            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();

            foreach (var blob in blobs)
            {
                List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob);
                List<IntPoint> cornerPoints;

                // use the shape checker to extract the corner points
                if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints))
                {
                    // only do things if the corners form a rectangle
                    if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle)
                    {
                        // here i use the graphics class to draw an overlay, but you
                        // could also just use the cornerPoints list to calculate your
                        // x, y, width, height values.
                        List<AForge.Point> Points = new List<AForge.Point>();
                        foreach (var point in cornerPoints)
                        {
                            Points.Add(new AForge.Point(point.X, point.Y));
                        }
                        var path = new PathFigure(new System.Windows.Point(Points.First().X, Points.First().Y), Points.Select(row => new System.Windows.Media.LineSegment(new System.Windows.Point(row.X, row.Y), false)), true);

                        dc.DrawGeometry(Brushes.Red, null, new PathGeometry(new PathFigure[] { path }));
                    }
                }
            }
        }
All Usage Examples Of AForge.Math.Geometry.SimpleShapeChecker::CheckPolygonSubType