public void CheckShapeTypeTest( ) { Assert.AreEqual(ShapeType.Circle, shapeChecker.CheckShapeType(idealCicle)); Assert.AreEqual(ShapeType.Circle, shapeChecker.CheckShapeType(distorredCircle)); Assert.AreEqual(ShapeType.Quadrilateral, shapeChecker.CheckShapeType(square1)); Assert.AreEqual(ShapeType.Quadrilateral, shapeChecker.CheckShapeType(square2)); Assert.AreEqual(ShapeType.Quadrilateral, shapeChecker.CheckShapeType(square3)); Assert.AreEqual(ShapeType.Quadrilateral, shapeChecker.CheckShapeType(rectangle)); Assert.AreEqual(ShapeType.Triangle, shapeChecker.CheckShapeType(triangle1)); Assert.AreEqual(ShapeType.Triangle, shapeChecker.CheckShapeType(equilateralTriangle)); Assert.AreEqual(ShapeType.Triangle, shapeChecker.CheckShapeType(isoscelesTriangle)); Assert.AreEqual(ShapeType.Triangle, shapeChecker.CheckShapeType(rectangledTriangle)); }
private Bitmap ProcessImage(Bitmap frame) { // convert the image to grayscale var grayConverter = new GrayscaleBT709(); var grayFrame = grayConverter.Apply(frame); // use a sobel edge detector to find color edges var edgeDetector = new SobelEdgeDetector(); var edgeFrame = edgeDetector.Apply(grayFrame); // threshold the edges var thresholdConverter = new Threshold(200); thresholdConverter.ApplyInPlace(edgeFrame); // use a blobcounter to find interesting shapes var detector = new BlobCounter() { FilterBlobs = true, MinWidth = 25, MinHeight = 25 }; detector.ProcessImage(edgeFrame); // find the circular shape var shapeDetector = new SimpleShapeChecker(); var blobs = detector.GetObjectsInformation(); var circles = from blob in blobs let edgePoints = detector.GetBlobsEdgePoints(blob) where shapeDetector.CheckShapeType(edgePoints) == ShapeType.Circle select blob; // show the traffic sign if (circles.Count() > 0) { var circleFrame = frame.Clone(circles.First().Rectangle, PixelFormat.DontCare); trafficSignBox.Image = circleFrame; } // highlight every circle in the image using (Graphics g = Graphics.FromImage(frame)) { var rects = detector.GetObjectsRectangles(); var pen = new Pen(Color.Blue, 4); foreach (var circle in circles) { g.DrawRectangle(pen, circle.Rectangle); } } // update picture boxes thresholdBox.Image = edgeFrame; return(frame); }
public Bitmap DetectCircle(Bitmap image) { SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); // locate objects using blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(image); Blob[] blobs = blobCounter.GetObjectsInformation(); // create Graphics object to draw on the image and a pen Graphics g = Graphics.FromImage(image); Pen redPen = new Pen(Color.Red, 2); // check each object and draw circle around objects, which // are recognized as circles for (int i = 0, n = blobs.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); try { shapeChecker.CheckShapeType(edgePoints); } catch (Exception) { continue; } List <IntPoint> corners; AForge.Point center; float radius; if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { g.DrawEllipse(redPen, (int)(center.X - radius), (int)(center.Y - radius), (int)(radius * 2), (int)(radius * 2)); } else if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { g.DrawPolygon(redPen, ToPointsArray(corners)); } } redPen.Dispose(); g.Dispose(); return(image); }
/// <summary> Blob Detection /// This method for color object detection by Blob counter algorithm. /// If you using this method, then you can detecting as follows: /// red circle, rectangle, triangle /// blue circle, rectangle, triangle /// green circle, rectangle, triangle /// the process of this method as follow: /// 1. color filtering by Euclidean filtering(R, G, B). /// 2. the grayscale filtering based on color filtered image. /// 3. In this step, you can choose the blur option. Applied blur option(or not), /// this method donging Sobel edge filtering based on grayscale(or grayscale + blur) image. /// 4. the binary filtering based on edge filter image. /// 5. Finally, detecting object, distance from the camera and degree are expreed on picturebox 1. /// </summary> private Bitmap BlobDetection(Bitmap _bitmapSourceImage) { #region Color filtering by Euclidean filtering switch (iColorMode) { case 1: //_colorFilter.CenterColor = new RGB(230, 30, 30); iRedValue = sbRedColor.Value; iBlueValue = sbBlueColor.Value; iGreenValue = sbGreenColor.Value; _colorFilter.CenterColor = new RGB((byte)iRedValue, (byte)iGreenValue, (byte)iBlueValue); _colorFilter.Radius = (short)iRadius; _colorFilterImage = _colorFilter.Apply(_bitmapSourceImage); break; case 2: iRedValue = sbRedColor.Value; iBlueValue = sbBlueColor.Value; iGreenValue = sbGreenColor.Value; _colorFilter.CenterColor = new RGB((byte)iRedValue, (byte)iGreenValue, (byte)iBlueValue); _colorFilter.Radius = (short)iRadius; _colorFilterImage = _colorFilter.Apply(_bitmapSourceImage); break; case 3: iRedValue = sbRedColor.Value; iBlueValue = sbBlueColor.Value; iGreenValue = sbGreenColor.Value; _colorFilter.CenterColor = new RGB((byte)iRedValue, (byte)iGreenValue, (byte)iBlueValue); _colorFilter.Radius = (short)iRadius; _colorFilterImage = _colorFilter.Apply(_bitmapSourceImage); break; } #endregion Grayscale _grayscale = new Grayscale(0.2125, 0.7154, 0.0721); _bitmapGreyImage = _grayscale.Apply(_colorFilterImage); #region blur option with Edge filter //create a edge detector instance if (_blurFlag == true) { //Blur _blurfilter = new Blur(); GaussianBlur _blurfilter = new GaussianBlur(1.5); _bitmapBlurImage = _blurfilter.Apply(_bitmapGreyImage); _bitmapEdgeImage = _edgeFilter.Apply(_bitmapBlurImage); } else if (_blurFlag == false) { _bitmapEdgeImage = _edgeFilter.Apply(_bitmapGreyImage); } #endregion Threshold _threshold = new Threshold(iThreshold); _bitmapBinaryImage = _threshold.Apply(_bitmapEdgeImage); /// /// blob counter algorithm initailze. /// BlobCounter.MinWidth and MinHeight -> for the defined minimum region /// BlobCounter _blobCounter = new BlobCounter(); //Configure Filter _blobCounter.MinWidth = 70; _blobCounter.MinHeight = 70; _blobCounter.FilterBlobs = true; _blobCounter.ProcessImage(_bitmapBinaryImage); Blob[] _blobPoints = _blobCounter.GetObjectsInformation(); Graphics _g = Graphics.FromImage(_bitmapSourceImage); SimpleShapeChecker _shapeChecker = new SimpleShapeChecker(); for (int i = 0; i < _blobPoints.Length; i++) { List <IntPoint> _edgePoint = _blobCounter.GetBlobsEdgePoints(_blobPoints[i]); List <IntPoint> _corners = null; AForge.Point _center; float _radius; //#region detecting Rectangle ///// ///// _corners: the corner of Quadrilateral ///// //if (_shapeChecker.IsQuadrilateral(_edgePoint, out _corners)) //{ // //Drawing the reference point of the picturebox // _g.DrawEllipse(_PictureboxPen, (float)(pictureBox1.Size.Width), // (float)(pictureBox1.Size.Height), // (float)10, (float)10); // // Drawing setting for outline of detected object // Rectangle[] _rects = _blobCounter.GetObjectsRectangles(); // System.Drawing.Point[] _coordinates = ToPointsArray(_corners); // Pen _pen = new Pen(Color.Blue, ipenWidth); // int _x = _coordinates[0].X; // int _y = _coordinates[0].Y; // // Drawing setting for centroid of detected object // int _centroid_X = (int)_blobPoints[0].CenterOfGravity.X; // int _centroid_Y = (int)_blobPoints[0].CenterOfGravity.Y; // //Drawing the centroid point of object // _g.DrawEllipse(_pen, (float)(_centroid_X), (float)(_centroid_Y), (float)10, (float)10); // //Degree calculation // int _deg_x = (int)_centroid_X - pictureBox1.Size.Width; // int _deg_y = pictureBox1.Size.Height - (int)_centroid_Y; // textBox1.Text = ("Degree: (" + _deg_x + ", " + _deg_y + ")"); // /// // /// Drawing outline of detected object // /// // if (_coordinates.Length == 4) // { // string _shapeString = "" + _shapeChecker.CheckShapeType(_edgePoint); // _g.DrawString(_shapeString, _font, _brush, _x, _y); // _g.DrawPolygon(_pen, ToPointsArray(_corners)); // } // //size of rectange // foreach (Rectangle rc in _rects) // { // ///for debug // //System.Diagnostics.Debug.WriteLine( // // string.Format("Rect size: ({0}, {1})", rc.Width, rc.Height)); // iFeatureWidth = rc.Width; // //check the FindDistance method. // double dis = FindDistance(iFeatureWidth); // _g.DrawString(dis.ToString("N2") + "cm", _font, _brush, _x, _y + 60); // } //} //#endregion #region detecting Circle /// /// _center: the center of circle /// _radius: the radius of circle /// if (_shapeChecker.IsCircle(_edgePoint, out _center, out _radius)) { //Drawing the reference point _g.DrawEllipse(_PictureboxPen, (float)(pictureBox1.Size.Width), (float)(pictureBox1.Size.Height), (float)10, (float)10); // Drawing setting for outline of detected object Rectangle[] _rects = _blobCounter.GetObjectsRectangles(); Pen _pen = new Pen(Color.Red, ipenWidth); string _shapeString = "" + _shapeChecker.CheckShapeType(_edgePoint); int _x = (int)_center.X; int _y = (int)_center.Y; /// /// Drawing outline of detected object /// _g.DrawString(_shapeString, _font, _brush, _x, _y); _g.DrawEllipse(_pen, (float)(_center.X - _radius), (float)(_center.Y - _radius), (float)(_radius * 2), (float)(_radius * 2)); //Drawing the centroid point of object int _centroid_X = (int)_blobPoints[0].CenterOfGravity.X; int _centroid_Y = (int)_blobPoints[0].CenterOfGravity.Y; _g.DrawEllipse(_pen, (float)(_centroid_X), (float)(_centroid_Y), (float)10, (float)10); //Degree calculation //int _deg_x = _centroid_X - pictureBox1.Size.Width; //int _deg_y = pictureBox1.Size.Height - _centroid_Y; float _deg_x = _center.X * 100 / pictureBox1.Image.Width; float _deg_y = _center.Y * 100 / pictureBox1.Image.Height; textBox2.Text = _deg_x + ""; textBox3.Text = _deg_y + ""; textBox1.Text = ("Degree: (" + _deg_x + ", " + _deg_y + ")"); //size of rectange foreach (Rectangle rc in _rects) { ///for debug //System.Diagnostics.Debug.WriteLine( // string.Format("Circle size: ({0}, {1})", rc.Width, rc.Height)); iFeatureWidth = rc.Width; double dis = FindDistance(iFeatureWidth); _g.DrawString(dis.ToString("N2") + "cm", _font, _brush, _x, _y + 60); } } #endregion //#region detecting Triangle ///// ///// _corners: the corner of Triangle ///// //if (_shapeChecker.IsTriangle(_edgePoint, out _corners)) //{ // //Drawing the reference point // _g.DrawEllipse(_PictureboxPen, (float)(pictureBox1.Size.Width), // (float)(pictureBox1.Size.Height), // (float)10, (float)10); // // Drawing setting for outline of detected object // Rectangle[] _rects = _blobCounter.GetObjectsRectangles(); // Pen _pen = new Pen(Color.Green, ipenWidth); // string _shapeString = "" + _shapeChecker.CheckShapeType(_edgePoint); // int _x = (int)_center.X; // int _y = (int)_center.Y; // // Drawing setting for centroid of detected object // int _centroid_X = (int)_blobPoints[0].CenterOfGravity.X; // int _centroid_Y = (int)_blobPoints[0].CenterOfGravity.Y; // /// // /// Drawing outline of detected object // /// // _g.DrawString(_shapeString, _font, _brush, _x, _y); // _g.DrawPolygon(_pen, ToPointsArray(_corners)); // //Drawing the centroid point of object // _g.DrawEllipse(_pen, (float)(_centroid_X), (float)(_centroid_Y), (float)10, (float)10); // //Degree calculation // int _deg_x = (int)_centroid_X - pictureBox1.Size.Width; // int _deg_y = pictureBox1.Size.Height - (int)_centroid_Y; // textBox1.Text = ("Degree: (" + _deg_x + ", " + _deg_y + ")"); // //size of rectange // foreach (Rectangle rc in _rects) // { // ///for debug // //System.Diagnostics.Debug.WriteLine( // // string.Format("Triangle Size: ({0}, {1})", rc.Width, rc.Height)); // iFeatureWidth = rc.Width; // double dis = FindDistance(iFeatureWidth); // _g.DrawString(dis.ToString("N2") + "cm", _font, _brush, _x, _y + 60); // } //} //#endregion } return(_bitmapSourceImage); }
//Blob Detection private Bitmap BlobDetection(Bitmap _bitmapSourceImage) { switch (iColorMode) { case 1: //_colorFilter.CenterColor = new RGB(230, 30, 30); iRedValue = sbRedColor.Value; iBlueValue = sbBlueColor.Value; iGreenValue = sbGreenColor.Value; _colorFilter.CenterColor = new RGB((byte)iRedValue, (byte)iGreenValue, (byte)iBlueValue); _colorFilter.Radius = (short)iRadius; _colorFilterImage = _colorFilter.Apply(_bitmapSourceImage); break; case 2: iRedValue = sbRedColor.Value; iBlueValue = sbBlueColor.Value; iGreenValue = sbGreenColor.Value; _colorFilter.CenterColor = new RGB((byte)iRedValue, (byte)iGreenValue, (byte)iBlueValue); _colorFilter.Radius = (short)iRadius; _colorFilterImage = _colorFilter.Apply(_bitmapSourceImage); break; case 3: iRedValue = sbRedColor.Value; iBlueValue = sbBlueColor.Value; iGreenValue = sbGreenColor.Value; _colorFilter.CenterColor = new RGB((byte)iRedValue, (byte)iGreenValue, (byte)iBlueValue); _colorFilter.Radius = (short)iRadius; _colorFilterImage = _colorFilter.Apply(_bitmapSourceImage); break; } Grayscale _grayscale = new Grayscale(0.2125, 0.7154, 0.0721); _bitmapGreyImage = _grayscale.Apply(_colorFilterImage); //create a edge detector instance if (_blurFlag == true) { //Blur _blurfilter = new Blur(); GaussianBlur _blurfilter = new GaussianBlur(); _bitmapBlurImage = _blurfilter.Apply(_bitmapGreyImage); _bitmapEdgeImage = _edgeFilter.Apply(_bitmapBlurImage); } else if (_blurFlag == false) { _bitmapEdgeImage = _edgeFilter.Apply(_bitmapGreyImage); } Threshold _threshold = new Threshold(iThreshold); _bitmapBinaryImage = _threshold.Apply(_bitmapEdgeImage); //Create a instance of blob counter algorithm BlobCounter _blobCounter = new BlobCounter(); //Configure Filter _blobCounter.MinWidth = 70; _blobCounter.MinHeight = 70; _blobCounter.FilterBlobs = true; _blobCounter.ProcessImage(_bitmapBinaryImage); Blob[] _blobPoints = _blobCounter.GetObjectsInformation(); Graphics _g = Graphics.FromImage(_bitmapSourceImage); SimpleShapeChecker _shapeChecker = new SimpleShapeChecker(); for (int i = 0; i < _blobPoints.Length; i++) { List <IntPoint> _edgePoint = _blobCounter.GetBlobsEdgePoints(_blobPoints[i]); List <IntPoint> _corners = null; AForge.Point _center; float _radius; if (_shapeChecker.IsQuadrilateral(_edgePoint, out _corners)) { Rectangle[] _rects = _blobCounter.GetObjectsRectangles(); System.Drawing.Point[] _coordinates = ToPointsArray(_corners); int _x = _coordinates[0].X; int _y = _coordinates[0].Y; Pen _pen = new Pen(Color.Blue, ipenWidth); if (_coordinates.Length == 4) { string _shapeString = "" + _shapeChecker.CheckShapeType(_edgePoint); _g.DrawString(_shapeString, _font, _brush, _x, _y); _g.DrawPolygon(_pen, ToPointsArray(_corners)); } //size of rectange foreach (Rectangle rc in _rects) { ///for debug //System.Diagnostics.Debug.WriteLine( // string.Format("Rect size: ({0}, {1})", rc.Width, rc.Height)); iFeatureWidth = rc.Width; double dis = FindDistance(iFeatureWidth); _g.DrawString(dis.ToString("N2"), _font, _brush, _x, _y + 60); } } if (_shapeChecker.IsCircle(_edgePoint, out _center, out _radius)) { Rectangle[] _rects = _blobCounter.GetObjectsRectangles(); string _shapeString = "" + _shapeChecker.CheckShapeType(_edgePoint); Pen _pen = new Pen(Color.Red, ipenWidth); int _x = (int)_center.X; int _y = (int)_center.Y; _g.DrawString(_shapeString, _font, _brush, _x, _y); _g.DrawEllipse(_pen, (float)(_center.X - _radius), (float)(_center.Y - _radius), (float)(_radius * 2), (float)(_radius * 2)); //size of rectange foreach (Rectangle rc in _rects) { ///for debug //System.Diagnostics.Debug.WriteLine( // string.Format("Circle size: ({0}, {1})", rc.Width, rc.Height)); iFeatureWidth = rc.Width; double dis = FindDistance(iFeatureWidth); //textBox1.Text = dis.ToString("N2"); _g.DrawString(dis.ToString("N2"), _font, _brush, _x, _y + 60); } } if (_shapeChecker.IsTriangle(_edgePoint, out _corners)) { Rectangle[] _rects = _blobCounter.GetObjectsRectangles(); string _shapeString = "" + _shapeChecker.CheckShapeType(_edgePoint); Pen _pen = new Pen(Color.Green, ipenWidth); int _x = (int)_center.X; int _y = (int)_center.Y; _g.DrawString(_shapeString, _font, _brush, _x, _y); _g.DrawPolygon(_pen, ToPointsArray(_corners)); //size of rectange foreach (Rectangle rc in _rects) { ///for debug //System.Diagnostics.Debug.WriteLine( // string.Format("Triangle Size: ({0}, {1})", rc.Width, rc.Height)); iFeatureWidth = rc.Width; double dis = FindDistance(iFeatureWidth); //textBox1.Text = dis.ToString("N2"); _g.DrawString(dis.ToString("N2"), _font, _brush, _x, _y + 60); } } } return(_bitmapSourceImage); }
public static void Run(string path) { // check shape, see http://www.aforgenet.com/articles/shape_checker/ SimpleShapeChecker shapeChecker = new SimpleShapeChecker() { }; float zoom = 20; var pinkPen = new Pen(Color.HotPink, zoom * 0.4f); var greenPen = new Pen(Color.GreenYellow, zoom * 0.7f); var aquaPen = new Pen(Color.Aqua, zoom * 0.7f); var redPen = new Pen(Color.Red, zoom * 0.4f); var bluePen = new Pen(Color.Blue, zoom * 0.4f); var blackPen = new Pen(Color.Black, zoom * 0.7f); using (var converter = new PdfImageConverter(path)) using (PdfDocument document = PdfDocument.Open(path)) { for (var i = 0; i < document.NumberOfPages; i++) { var page = document.GetPage(i + 1); var paths = page.ExperimentalAccess.Paths; using (var bitmap = converter.GetPage(i + 1, zoom)) using (var graphics = Graphics.FromImage(bitmap)) { var imageHeight = bitmap.Height; foreach (var letter in page.Letters) { var rect = new Rectangle( (int)(letter.GlyphRectangle.Left * (decimal)zoom), imageHeight - (int)(letter.GlyphRectangle.Top * (decimal)zoom), (int)(letter.GlyphRectangle.Width * (decimal)zoom), (int)(letter.GlyphRectangle.Height * (decimal)zoom)); graphics.DrawRectangle(pinkPen, rect); } foreach (var p in paths) { if (p == null) { continue; } var commands = p.Commands; var points = ToPoints(commands); //Scatterplot plot = new Scatterplot(); //plot.Compute(points.Select(po => (double)po.X).ToArray(), points.Select(po => (double)po.Y).ToArray()); //ScatterplotBox.Show(plot); var shape = shapeChecker.CheckShapeType(points); var subType = shapeChecker.CheckPolygonSubType(points); var bboxF = GetBoundingRectangle(commands); if (bboxF.HasValue) { var rect = new Rectangle( (int)(bboxF.Value.Left * (decimal)zoom), imageHeight - (int)(bboxF.Value.Top * (decimal)zoom), (int)(bboxF.Value.Width == 0 ? 1 : bboxF.Value.Width * (decimal)zoom), (int)(bboxF.Value.Height == 0 ? 1 : bboxF.Value.Height * (decimal)zoom)); var pen = shape == ShapeType.Quadrilateral ? greenPen : (shape == ShapeType.Circle ? aquaPen : blackPen); graphics.DrawRectangle(pen, rect); } foreach (var command in commands) { if (command is PdfPath.Line line) { var bbox = line.GetBoundingRectangle(); if (bbox.HasValue) { var rect = new Rectangle( (int)(bbox.Value.Left * (decimal)zoom), imageHeight - (int)(bbox.Value.Top * (decimal)zoom), (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); graphics.DrawRectangle(bluePen, rect); } } else if (command is BezierCurve curve) { var bbox = curve.GetBoundingRectangle(); if (bbox.HasValue) { var rect = new Rectangle( (int)(bbox.Value.Left * (decimal)zoom), imageHeight - (int)(bbox.Value.Top * (decimal)zoom), (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); graphics.DrawRectangle(redPen, rect); } } else if (command is Close close) { var bbox = close.GetBoundingRectangle(); if (bbox.HasValue) { var rect = new Rectangle( (int)(bbox.Value.Left * (decimal)zoom), imageHeight - (int)(bbox.Value.Top * (decimal)zoom), (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); graphics.DrawRectangle(greenPen, rect); } } else if (command is Move move) { var bbox = move.GetBoundingRectangle(); if (bbox.HasValue) { var rect = new Rectangle( (int)(bbox.Value.Left * (decimal)zoom), imageHeight - (int)(bbox.Value.Top * (decimal)zoom), (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); graphics.DrawRectangle(greenPen, rect); } } else { throw new NotImplementedException(command.GetType().ToString()); } } } var rectsPaths = RecursiveXYCutPath.Instance.GetBlocks(paths, 0, 10, 10); foreach (var rectPath in rectsPaths) { var rect = new Rectangle( (int)(rectPath.Left * (decimal)zoom), imageHeight - (int)(rectPath.Top * (decimal)zoom), (int)(rectPath.Width * (decimal)zoom), (int)(rectPath.Height * (decimal)zoom)); graphics.DrawRectangle(aquaPen, rect); } bitmap.Save(Path.ChangeExtension(path, (i + 1) + "_pathsTest.png")); } } } }
private static Blob[] Blobs(Bitmap image) { const float baseArea = 921600.0f; // stores the base area of the answer sheet BlobCounter blobCounter = new BlobCounter { FilterBlobs = true, MinHeight = 1280, MinWidth = 720 }; blobCounter.ProcessImage(PreProcess(image)); // prepares and processes the image for the blob scanning Blob[] blobs = blobCounter.GetObjectsInformation(); // gets all the objects SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = Graphics.FromImage(image); Pen redPen = new Pen(Color.Red, 2); float k = 1.0f; foreach (var blob in blobs) // finds the answer sheet in the scanned image (largest scanned rectangle) and calculates the multiplier (k) for finding the answers { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); if (shapeChecker.IsQuadrilateral(edgePoints, out List <IntPoint> cornerPoints)) { if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle) { List <System.Drawing.Point> points = new List <System.Drawing.Point>(); foreach (var point in cornerPoints) { points.Add(new System.Drawing.Point(point.X, point.Y)); } System.Drawing.Point min = new System.Drawing.Point(image.Width, image.Height); System.Drawing.Point max = new System.Drawing.Point(0, 0); List <System.Drawing.Point> pl = new List <System.Drawing.Point>(); pl = points.OrderBy(p => p.X).ToList(); if (pl[0].Y <= pl[1].Y) { min = pl[0]; } else if (pl[0].Y >= pl[1].Y) { min = pl[1]; } if (pl[2].Y >= pl[3].Y) { max = pl[2]; } else if (pl[2].Y <= pl[3].Y) { max = pl[3]; } pl.Remove(min); pl.Remove(max); double width = Math.Sqrt(Math.Pow(pl[1].X - max.X, 2) + Math.Pow(pl[1].Y - max.Y, 2)); double height = Math.Sqrt(Math.Pow(pl[0].X - max.X, 2) + Math.Pow(pl[0].Y - max.Y, 2)); k = (float)(width * height) / baseArea; } } } k = (float)Math.Round(Math.Sqrt(k)); shapeChecker.RelativeDistortionLimit = 0.05f; blobCounter.FilterBlobs = true; blobCounter.MinHeight = 21 * (int)k; blobCounter.MinWidth = 21 * (int)k; blobCounter.ProcessImage(PreProcess(image)); blobs = blobCounter.GetObjectsInformation(); List <Blob> circleBlobs = new List <Blob>(); int i = 0; foreach (var blob in blobs) // finds the answers using the aforementioned multiplier (k) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); if (shapeChecker.IsCircle(edgePoints, out AForge.Point center, out float radius) || (shapeChecker.CheckShapeType(edgePoints) == ShapeType.Circle)) { g.DrawEllipse(new Pen(Color.FromArgb(255, i, i, i), 2.0f), (int)(center.X - radius), (int)(center.Y - radius), (int)(radius * 2), (int)(radius * 2)); circleBlobs.Add(blob); } if (i + 10 > 255) { i = 0; } i += 10; } redPen.Dispose(); g.Dispose(); return(circleBlobs.ToArray()); }
public static void Run(string path) { // check shape, see http://www.aforgenet.com/articles/shape_checker/ SimpleShapeChecker shapeChecker = new SimpleShapeChecker() { }; float zoom = 20; var pinkPen = new Pen(Color.HotPink, zoom * 0.4f); var greenPen = new Pen(Color.GreenYellow, zoom * 0.7f); var aquaPen = new Pen(Color.Aqua, zoom * 0.7f); var redPen = new Pen(Color.Red, zoom * 0.4f); var bluePen = new Pen(Color.Blue, zoom * 0.4f); var blackPen = new Pen(Color.Black, zoom * 0.7f); using (var converter = new PdfImageConverter(path)) using (PdfDocument document = PdfDocument.Open(path)) { for (var i = 0; i < document.NumberOfPages; i++) { var page = document.GetPage(i + 1); var paths = page.ExperimentalAccess.Paths; var geometries = paths.Select(p => new PdfGeometry(p)).ToList(); var verticals = geometries.Where(g => g.IsVerticalLine()).ToList(); var horizontals = geometries.Where(g => g.IsHorizontalLine()).ToList(); using (var bitmap = converter.GetPage(i + 1, zoom)) using (var graphics = Graphics.FromImage(bitmap)) { var imageHeight = bitmap.Height; foreach (var letter in page.Letters) { var rect = new Rectangle( (int)(letter.GlyphRectangle.Left * (decimal)zoom), imageHeight - (int)(letter.GlyphRectangle.Top * (decimal)zoom), (int)(letter.GlyphRectangle.Width * (decimal)zoom), (int)(letter.GlyphRectangle.Height * (decimal)zoom)); graphics.DrawRectangle(pinkPen, rect); } foreach (var p in paths) { if (p == null) { continue; } PdfGeometry geometry = new PdfGeometry(p); var isClosed = geometry.IsClosed; var isClockwise = geometry.IsClockwise; var commands = p.Commands; var points = ToOrderedPoints(commands); if (isClosed) //.SubGeometries.Count > 1) { //Scatterplot scatterplot = new Scatterplot(); //scatterplot.Compute( // points.Select(po => (double)po.X).Take(31).ToArray(), // points.Select(po => (double)po.Y).Take(31).ToArray(), // Enumerable.Range(0, points.Count).Take(31).ToArray()); //ScatterplotBox.Show(scatterplot); ScatterplotView view = new ScatterplotView(); view.Dock = System.Windows.Forms.DockStyle.Fill; view.LinesVisible = true; view.Graph.GraphPane.Title.Text = isClockwise ? "CW" : "CCW"; foreach (var command in commands) { if (command is PdfPath.Line line) { view.Graph.GraphPane.GraphObjList.Add(new ZedGraph.ArrowObj( Color.Blue, 10.0f, (double)line.From.X, (double)line.From.Y, (double)line.To.X, (double)line.To.Y)); view.Graph.GraphPane.AddCurve("", new[] { (double)line.From.X, (double)line.To.X }, new[] { (double)line.From.Y, (double)line.To.Y }, Color.Red); } else if (command is BezierCurve curve) { foreach (var lineB in BezierCurveToPaths(curve)) { view.Graph.GraphPane.GraphObjList.Add(new ZedGraph.ArrowObj( Color.Blue, 10.0f, (double)lineB.From.X, (double)lineB.From.Y, (double)lineB.To.X, (double)lineB.To.Y)); view.Graph.GraphPane.AddCurve("", new[] { (double)lineB.From.X, (double)lineB.To.X }, new[] { (double)lineB.From.Y, (double)lineB.To.Y }, Color.Red); } } } //view.Graph.GraphPane.AddCurve("curve", // points.Select(po => (double)po.X).ToArray(), // points.Select(po => (double)po.Y).ToArray(), // Color.Blue, // ZedGraph.SymbolType.Circle); view.Graph.GraphPane.AxisChange(); var f1 = new System.Windows.Forms.Form(); f1.Width = 1000; f1.Height = 1000; f1.Controls.Add(view); f1.ShowDialog(); } var shape = shapeChecker.CheckShapeType(points); var subType = shapeChecker.CheckPolygonSubType(points); var bboxF = GetBoundingRectangle(commands); if (bboxF.HasValue) { var rect = new Rectangle( (int)(bboxF.Value.Left * (decimal)zoom), imageHeight - (int)(bboxF.Value.Top * (decimal)zoom), (int)(bboxF.Value.Width == 0 ? 1 : bboxF.Value.Width * (decimal)zoom), (int)(bboxF.Value.Height == 0 ? 1 : bboxF.Value.Height * (decimal)zoom)); graphics.DrawRectangle(greenPen, rect); } /*foreach (var command in commands) * { * if (command is PdfPath.Line line) * { * var bbox = line.GetBoundingRectangle(); * if (bbox.HasValue) * { * var rect = new Rectangle( * (int)(bbox.Value.Left * (decimal)zoom), * imageHeight - (int)(bbox.Value.Top * (decimal)zoom), * (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), * (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); * graphics.DrawRectangle(bluePen, rect); * } * } * else if (command is BezierCurve curve) * { * var bbox = curve.GetBoundingRectangle(); * if (bbox.HasValue) * { * var rect = new Rectangle( * (int)(bbox.Value.Left * (decimal)zoom), * imageHeight - (int)(bbox.Value.Top * (decimal)zoom), * (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), * (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); * graphics.DrawRectangle(redPen, rect); * } * } * else if (command is Close close) * { * var bbox = close.GetBoundingRectangle(); * if (bbox.HasValue) * { * var rect = new Rectangle( * (int)(bbox.Value.Left * (decimal)zoom), * imageHeight - (int)(bbox.Value.Top * (decimal)zoom), * (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), * (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); * graphics.DrawRectangle(greenPen, rect); * } * } * else if (command is Move move) * { * var bbox = move.GetBoundingRectangle(); * if (bbox.HasValue) * { * var rect = new Rectangle( * (int)(bbox.Value.Left * (decimal)zoom), * imageHeight - (int)(bbox.Value.Top * (decimal)zoom), * (int)(bbox.Value.Width == 0 ? 1 : bbox.Value.Width * (decimal)zoom), * (int)(bbox.Value.Height == 0 ? 1 : bbox.Value.Height * (decimal)zoom)); * graphics.DrawRectangle(greenPen, rect); * } * } * else * { * throw new NotImplementedException(command.GetType().ToString()); * } * }*/ } var rectsPaths = RecursiveXYCutPath.Instance.GetBlocks(paths, 0, 10, 10); foreach (var rectPath in rectsPaths) { var rect = new Rectangle( (int)(rectPath.Left * (decimal)zoom), imageHeight - (int)(rectPath.Top * (decimal)zoom), (int)(rectPath.Width * (decimal)zoom), (int)(rectPath.Height * (decimal)zoom)); graphics.DrawRectangle(aquaPen, rect); } bitmap.Save(Path.ChangeExtension(path, (i + 1) + "_pathsTest.png")); } } } }