private bool FindNewCornersAndCheckAspectRatio(List <IntPoint> corners)
        {
            Point    g = PointsCloud.GetCenterOfGravity(corners);
            IntPoint p1 = corners[0], p2 = corners[1], p3 = corners[2], p4 = corners[3];

            List <IntPoint> leftPoints  = new List <IntPoint>();
            List <IntPoint> rightPoints = new List <IntPoint>();

            foreach (IntPoint p in corners)
            {
                if (p.X < g.X)
                {
                    leftPoints.Add(p);
                }
                else
                {
                    rightPoints.Add(p);
                }
            }

            if (leftPoints.Count - rightPoints.Count != 0)
            {
                return(false);
            }
            // korekcija
            if (leftPoints[0].Y < leftPoints[1].Y)
            {
                p4 = leftPoints[0];
                p1 = leftPoints[1];
            }
            else
            {
                p4 = leftPoints[1];
                p1 = leftPoints[0];
            }

            if (rightPoints[0].Y < rightPoints[1].Y)
            {
                p3 = rightPoints[0];
                p2 = rightPoints[1];
            }
            else
            {
                p3 = rightPoints[1];
                p2 = rightPoints[0];
            }

            corners[0] = p4;
            corners[1] = p3;
            corners[2] = p2;
            corners[3] = p1;

            float topSideWidth          = p1.DistanceTo(p2);
            float rightSideHeight       = p3.DistanceTo(p2);
            float ar = topSideWidth / rightSideHeight;

            return(2 <= ar && ar <= 10);
        }
Example #2
0
        private void FindNewCorners(List<IntPoint> corners) {
            // Centar gravitacije unutar kvadrata
            Accord.Point g = PointsCloud.GetCenterOfGravity(corners);
            // Pošto se radi o kvadratu to je 
            IntPoint p1 = corners[0], p2 = corners[1], p3 = corners[2], p4 = corners[3];
            // gdje je: p1 - top left, p2 - top right, p3 - bottom right, p4 - bottom left

            foreach (IntPoint p in corners) {
                if (p.X <= g.X && p.Y >= g.Y)
                    p1 = p;
                else if (p.X >= g.X && p.Y >= g.Y)
                    p2 = p;
                else if (p.X >= g.X && p.Y <= g.Y)
                    p3 = p;
                else if (p.X <= g.X && p.Y <= g.Y)
                    p4 = p;
            }

            corners[0] = p4;
            corners[1] = p3;
            corners[2] = p2;
            corners[3] = p1;
        }
Example #3
0
        // Get ID of the specified glyph
        // Note (todo?): glyph tracking needs to be improved since current implementation
        // is not reliable enough for the case when several glyphs of the same type are
        // found and those do not move smoothely.
        private int GetGlyphID(ExtractedGlyphData glyph)
        {
            int glyphID = -1;

            // get CoG of the provided glyph
            Point glyphCog = PointsCloud.GetCenterOfGravity(glyph.Quadrilateral);
            // distance to the closest simlar glyph kept in history
            float minDistance = float.MaxValue;

            // name of the passed specifed glyph
            string glyphName = (glyph.RecognizedGlyph != null) ?
                               glyph.RecognizedGlyph.Name : string.Empty;

            // check all currently tracked glyphs
            foreach (TrackedGlyph trackedGlyph in trackedGlyphs.Values)
            {
                if (trackedGlyph.Age == 0)
                {
                    // skip glyph whichs were already taken or just added
                    continue;
                }

                if (
                    // recognized case - compare names
                    ((trackedGlyph.Glyph.RecognizedGlyph != null) &&
                     (trackedGlyph.Glyph.RecognizedGlyph.Name == glyphName)) ||
                    // unrecognized case - compare raw data
                    (Glyph.CheckForMatching(glyph.RawData, trackedGlyph.Glyph.RawData) != -1))
                {
                    float distance = glyphCog.DistanceTo(trackedGlyph.Position);

                    if (distance < minDistance)
                    {
                        // get ID of the closest glyph with the same name
                        minDistance = distance;
                        glyphID     = trackedGlyph.ID;
                    }
                }
            }

            // if the glyph is further away than the maximum specified limit,
            // then it is no way can be treated as smooth motion, so reset ID
            // (TODO: should probably depend on glyph size ...)
            if ((glyphID != -1) && (minDistance > MaxAllowedDistance))
            {
                glyphID = -1;
            }

            // if glyph was not found within tracked glyphs, then add new
            // glyph to tracker
            if (glyphID == -1)
            {
                glyphID = counter++;
                trackedGlyphs.Add(glyphID, new TrackedGlyph(glyphID,
                                                            (ExtractedGlyphData)glyph.Clone( ), glyphCog));
            }
            else
            {
                TrackedGlyph trackedGlyph = trackedGlyphs[glyphID];

                if ((glyph.RecognizedGlyph != null) &&
                    (!IsCoordinatesDifferenceSignificant(glyph.RecognizedQuadrilateral,
                                                         trackedGlyphs[glyphID].Glyph.RecognizedQuadrilateral)))
                {
                    // correct coordinates of recognized glyphs to eliminate small noisy shaking
                    glyph.RecognizedQuadrilateral = trackedGlyph.Glyph.RecognizedQuadrilateral;
                    glyphCog = trackedGlyph.Position;
                }
                else
                {
                    // update glyph with the latest CoG and recognized info
                    trackedGlyph.Position = glyphCog;
                    trackedGlyph.Glyph    = (ExtractedGlyphData)glyph.Clone( );
                }

                // reset age of the tracked glyph
                trackedGlyph.Age = 0;

                // add glyph's position to history
                trackedGlyph.AddMotionHistory(glyphCog);
            }

            return(glyphID);
        }
Example #4
0
        private void altProcess(Bitmap bm, int level)
        {
            var img = new Image <Bgr, byte>(bm);

            if (level == 1)
            {
                var resImage = new Image <Bgr, byte>(img.Bitmap);
                CvInvoke.BilateralFilter(resImage, img, 30, 80, 80);
                CvInvoke.MedianBlur(img, img, 5);
                resImage = img;
            }
            else if (level == 2)
            {
                CvInvoke.MedianBlur(img, img, 5);
                var resImage = new Image <Bgr, byte>(img.Bitmap);
                CvInvoke.BilateralFilter(resImage, img, 25, 75, 75);
                CvInvoke.Blur(img, img, new Size(5, 5), new Point(0, 0));
            }

            var grayimage = new Image <Gray, byte>(bm);

            CvInvoke.CvtColor(img, grayimage, ColorConversion.Bgr2Gray);

            BlackBG(grayimage);

            Console.WriteLine("Filtering done");

            var cannyThreshold = GetKMeansThreshold(grayimage);

            label2.Text = cannyThreshold.ToString();

            Thresholding(grayimage, cannyThreshold);

            Console.WriteLine("Canny threshold using KMEANS found " + cannyThreshold);

            //Convert the image to grayscale and filter out the noise

            var cannyEdges = new UMat();

            Console.WriteLine("Canny threshold using KMEANS found " + cannyThreshold);

            var uimage = new UMat();

            CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray);

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

            BlobCounter blobCounter = new BlobCounter( );

            if (level == 1)
            {
                blobCounter.FilterBlobs = true;
                blobCounter.MinHeight   = 25;
                blobCounter.MinWidth    = 25;
                blobCounter.ProcessImage(cannyEdges.Bitmap);
            }
            else
            {
                blobCounter.ProcessImage(grayimage.ToBitmap());
            }
            //blobCounter.ProcessImage(grayimage.ToBitmap());

            Blob[] blobs = blobCounter.GetObjectsInformation( );

            SimpleShapeChecker shapeChecker = new SimpleShapeChecker();


            var      triangleList = new List <Triangle2DF>();
            var      boxList      = new List <RotatedRect>();
            var      circleList   = new List <CircleF>();
            Bitmap   newBM        = new Bitmap(img.Bitmap);
            Graphics g            = Graphics.FromImage(newBM);
            Pen      redPen       = new Pen(Color.Red, 2);


            Pen yellowPen = new Pen(Color.Yellow, 2);
            Pen greenPen  = new Pen(Color.Green, 2);
            Pen bluePen   = new Pen(Color.Blue, 2);

            for (int i = 0, n = blobs.Length; i < n; i++)
            {
                List <IntPoint> edgePoints =
                    blobCounter.GetBlobsEdgePoints(blobs[i]);

                AForge.Point center;
                float        radius;

                if (shapeChecker.IsCircle(edgePoints, out center, out radius))
                {
                    //g.DrawEllipse(bluePen,
                    //    (float)(center.X - radius), (float)(center.Y - radius),
                    //    (float)(radius * 2), (float)(radius * 2));
                    circleList.Add(new CircleF(new PointF(center.X, center.Y), radius));
                }
                else
                {
                    List <IntPoint> corners;
                    if (edgePoints.Count > 1)
                    {
                        if (shapeChecker.IsQuadrilateral(edgePoints, out corners))
                        {
                            System.Console.WriteLine(corners.Count);
                            if (shapeChecker.CheckPolygonSubType(corners) ==
                                PolygonSubType.Square || shapeChecker.CheckPolygonSubType(corners) ==
                                PolygonSubType.Rectangle)
                            {
                                IntPoint minXY, maxXY;

                                PointsCloud.GetBoundingRectangle(corners, out minXY, out maxXY);
                                AForge.Point c = PointsCloud.GetCenterOfGravity(corners);
                                //g.DrawPolygon(greenPen, ToPointsArray(corners));
                                boxList.Add(new RotatedRect(new PointF(c.X, c.Y), new SizeF(maxXY.X - minXY.X, maxXY.Y - minXY.Y), 0));
                            }
                        }
                        else
                        {
                            corners = PointsCloud.FindQuadrilateralCorners(edgePoints);
                            if (corners.Count == 3)
                            {
                                Triangle2DF tri = new Triangle2DF(new PointF(corners[0].X, corners[0].Y), new PointF(corners[1].X, corners[1].Y), new PointF(corners[2].X, corners[2].Y));
                                triangleList.Add(tri);
                                //g.DrawPolygon(yellowPen, ToPointsArray(corners));
                            }
                            //g.DrawPolygon(redPen, ToPointsArray(corners));
                        }
                    }
                }
            }
            Console.WriteLine("boxes " + boxList.Count);
            Console.WriteLine("triangles " + triangleList.Count);
            Console.WriteLine("circles " + circleList.Count);

            redPen.Dispose();
            greenPen.Dispose();
            bluePen.Dispose();
            yellowPen.Dispose();
            //g.Dispose();
            resPicBox.Image = newBM;
            CircleF[] circles = circleList.ToArray();
            var       cList   = circles.ToList();

            FilterSame(boxList, triangleList, cList, img.Width * img.Height);
            circles = cList.ToArray();
            var points = new List <PointF>();

            var Image = img.CopyBlank();

            foreach (var triangle in triangleList)
            {
                Image.Draw(triangle, new Bgr(Color.Red), 3);
                points.Add(triangle.Centeroid);
            }

            foreach (var box in boxList)
            {
                Image.Draw(box, new Bgr(Color.Blue), 3);
                points.Add(box.Center);
            }

            foreach (var circle in circles)
            {
                Image.Draw(circle, new Bgr(Color.DarkCyan), 3);
                points.Add(circle.Center);
            }

            var listPoints = SortPoints(points, img);

            for (var i = 0; i < listPoints.Length; i++)
            {
                Console.WriteLine(listPoints[i].X.ToString() + " " + listPoints[i].Y.ToString());
            }

            System.Console.WriteLine("Points sorted, num of objects " + listPoints.Length.ToString());
            resPicBox.Image = (Image + img).ToBitmap();
            if (listPoints.Length > 3)
            {
                var bezSegList = InterpolatePointWithBeizerCurves(listPoints.ToList <PointF>());
                var gr         = Graphics.FromImage(resPicBox.Image);
                var p          = new Pen(Color.Red);

                foreach (BeizerCurveSegment seg in bezSegList)
                {
                    var bezierList = GetBez(new PointF[]
                                            { seg.StartPoint, seg.FirstControlPoint, seg.SecondControlPoint, seg.EndPoint });
                    for (var i = 0; i < bezierList.Length - 1; i++)
                    {
                        gr.DrawLine(p, bezierList[i], bezierList[i + 1]);
                    }
                }
            }
            else
            {
                var gr = Graphics.FromImage(resPicBox.Image);
                var p  = new Pen(Color.Red);

                for (var i = 0; i < listPoints.Length - 1; i++)
                {
                    gr.DrawLine(p, listPoints[i], listPoints[i + 1]);
                }
            }

            //var bezierList = GetBezierCurve1(listPoints);
        }