public override void calcDescriptorInfo(Bitmap inImage) { shapeCount = new int[6]; originalImage = image; image = imgProcessor.preProcessImage(inImage); g = Graphics.FromImage(originalImage); BlobCounter bCounter = new BlobCounter(); bCounter.ProcessImage(image); Blob[] blobs = bCounter.GetObjectsInformation(); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); for (int i = 0; i < blobs.Length; i++) { if (blobs[i].Area < 100) { continue; } List<IntPoint> edgePts = bCounter.GetBlobsEdgePoints(blobs[i]); checkShape(shapeChecker, edgePts); } g.Dispose(); }
/// <summary> /// Méthode qui analyse les images envoyées par le client /// Repère les formes présentes, les découpe et les enregistre en ficiers distincts /// </summary> public void ProcessImage() { using (CamCapturer.CamCapturer cam = new CamCapturer.CamCapturer()) { Picture = cam.GetCapture(); Copy = cam.GetCapture(); } ShapeChecker = new SimpleShapeChecker(); ShapeAnalyser = new BlobCounter(); string date = DateTime.Now.Date.ToString("dMyyyy"); FolderName = string.Format("Kuhlschrank-{0}", date); ShapeAnalyser.FilterBlobs = true; ShapeAnalyser.MinHeight = 200; ShapeAnalyser.MinWidth = 500; Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), FolderName)); BitmapData bitData = Picture.LockBits(new Rectangle(0, 0, Picture.Width, Picture.Height), ImageLockMode.ReadWrite, Picture.PixelFormat); ColorFiltering filter = new ColorFiltering(); filter.Red = new IntRange(0, 64); filter.Green = new IntRange(0, 64); filter.Blue = new IntRange(0, 64); filter.FillOutsideRange = false; filter.ApplyInPlace(bitData); ShapeAnalyser.ProcessImage(bitData); Blob[] blobs = ShapeAnalyser.GetObjectsInformation(); Picture.UnlockBits(bitData); for (int i = 0; i < blobs.Length; i++) { List<IntPoint> edgePoints = ShapeAnalyser.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; ShapeChecker.IsConvexPolygon(edgePoints, out corners); IntPoint pt0 = corners[0]; IntPoint pt1 = corners[1]; IntPoint pt2 = corners[2]; double width = Math.Sqrt(Math.Pow(pt1.X - pt0.X, 2) + Math.Pow(pt1.Y - pt0.Y, 2)); double height = Math.Sqrt(Math.Pow(pt2.X - pt1.X, 2) + Math.Pow(pt2.Y - pt1.Y, 2)); Rectangle crop = new Rectangle(corners[0].X, corners[1].Y, (int)width + 50, (int)height + 50); Bitmap target = new Bitmap(crop.Width, crop.Height); using (Graphics gr = Graphics.FromImage(target)) gr.DrawImage(Copy, new Rectangle(0, 0, target.Width, target.Height), crop, GraphicsUnit.Pixel); target.Save(string.Format(@"{0}\{1}\crop{2}.jpg", Path.GetTempPath(), FolderName, i)); } }
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 })); } } } }
public ImageProcessor() { shapeChecker = new SimpleShapeChecker(); hullFinder = new GrahamConvexHull(); blobCounter = new BlobCounter(); HotGoal = 0; greenPen = new Pen(Color.FromArgb(0, 255, 0), 1); yellowPen = new Pen(Color.FromArgb(255, 255, 0), 1); redPen = new Pen(Color.FromArgb(255, 0, 0), 2); orangePen = new Pen(Color.FromArgb(255, 127, 0), 1); purplePen = new Pen(Color.FromArgb(102, 51, 153), 1); redBrush = new SolidBrush(Color.FromArgb(255, 0, 0)); blueBrush = new SolidBrush(Color.FromArgb(0, 0, 255)); }
public static List<List<IntPoint>> Quadrilaterals(Bitmap img, int minWidth, int minHeight) { Bitmap thresholdedImg = FilterCombinations.AdaptiveThreshold(img); //Use blob recognition on the image to find all blobs meeting the specified minimum width & height BlobCounter blobCounter = new BlobCounter(); //Filter out small blobs blobCounter.MinWidth = minWidth; blobCounter.MinHeight = minHeight; blobCounter.FilterBlobs = true; //Order the blobs by size (desc), as since we're looking for quads of a minimum size, it's likely we'll be more interested in the laregr ones blobCounter.ObjectsOrder = ObjectsOrder.Size; //Check if each blob is approximately a quadriateral, and if so store the 4 corners List<List<IntPoint>> foundQuads = new List<List<IntPoint>>(); //Shape checker to be used to test if a blob is a quadrilateral SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); //Find the blobs blobCounter.ProcessImage(thresholdedImg); Blob[] blobs = blobCounter.GetObjectsInformation(); foreach(Blob b in blobs) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(b); List<IntPoint> corners = null; //Is this blob approximately a quadrilateral? if(shapeChecker.IsQuadrilateral(edgePoints, out corners)) { //Store the Quad's corners foundQuads.Add(corners); } } return foundQuads; }
private void detectQuads(Bitmap bitmap) { // Greyscale filteredBitmap = Grayscale.CommonAlgorithms.BT709.Apply(bitmap); // edge filter SobelEdgeDetector edgeFilter = new SobelEdgeDetector(); edgeFilter.ApplyInPlace(filteredBitmap); // Threshhold filter Threshold threshholdFilter = new Threshold(190); threshholdFilter.ApplyInPlace(filteredBitmap); BitmapData bitmapData = filteredBitmap.LockBits( new Rectangle(0, 0, filteredBitmap.Width, filteredBitmap.Height), ImageLockMode.ReadWrite, filteredBitmap.PixelFormat); BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 125; blobCounter.MinWidth = 125; blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); filteredBitmap.UnlockBits(bitmapData); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Bitmap bm = new Bitmap(filteredBitmap.Width, filteredBitmap.Height, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(bm); g.DrawImage(filteredBitmap, 0, 0); Pen pen = new Pen(Color.Red, 5); List<IntPoint> cardPositions = new List<IntPoint>(); // Loop through detected shapes for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; bool sameCard = false; // is triangle or quadrilateral if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { // get sub-type PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); // Only return 4 corner rectanges if ((subType == PolygonSubType.Parallelogram || subType == PolygonSubType.Rectangle) && corners.Count == 4) { // Check if its sideways, if so rearrange the corners so it's veritcal rearrangeCorners(corners); // Prevent it from detecting the same card twice foreach (IntPoint point in cardPositions) { if (corners[0].DistanceTo(point) < 40) sameCard = true; } if (sameCard) continue; // Hack to prevent it from detecting smaller sections of the card instead of the whole card if (GetArea(corners) < 20000) continue; cardPositions.Add(corners[0]); g.DrawPolygon(pen, ToPointsArray(corners)); // Extract the card bitmap QuadrilateralTransformation transformFilter = new QuadrilateralTransformation(corners, 211, 298); cardBitmap = transformFilter.Apply(cameraBitmap); List<IntPoint> artCorners = new List<IntPoint>(); artCorners.Add(new IntPoint(14, 35)); artCorners.Add(new IntPoint(193, 35)); artCorners.Add(new IntPoint(193, 168)); artCorners.Add(new IntPoint(14, 168)); // Extract the art bitmap QuadrilateralTransformation cartArtFilter = new QuadrilateralTransformation(artCorners, 183, 133); cardArtBitmap = cartArtFilter.Apply(cardBitmap); MagicCard card = new MagicCard(); card.corners = corners; card.cardBitmap = cardBitmap; card.cardArtBitmap = cardArtBitmap; magicCards.Add(card); } } } pen.Dispose(); g.Dispose(); filteredBitmap = bm; }
private void checkShape(SimpleShapeChecker shapeChecker, List<IntPoint> edgePts) { AForge.Point center; float radius; List<IntPoint> corners; if(edgePts.Count>4 && shapeChecker.IsCircle(edgePts,out center,out radius)){ //shape is a circle drawEllipse(center, radius); shapeCount[0]++; } else if(edgePts.Count>3 && shapeChecker.IsConvexPolygon(edgePts,out corners)){ PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if (subType == PolygonSubType.Unknown) { shapeCount[4]++; } else if (subType == PolygonSubType.Square) { shapeCount[2]++; } else if (subType == PolygonSubType.Rectangle) { shapeCount[3]++; } else if (subType == PolygonSubType.Trapezoid) { shapeCount[5]++; } else if (subType == PolygonSubType.EquilateralTriangle) { shapeCount[1]++; } else if (subType == PolygonSubType.IsoscelesTriangle) { shapeCount[1]++; } drawPolygon(corners); } else if(shapeChecker.IsTriangle(edgePts)){ //triangle shapeCount[1]++; } }
public void DetectQuads() { // Greyscale FilteredBitmap = Grayscale.CommonAlgorithms.BT709.Apply(CameraBitmap); // edge filter var edgeFilter = new SobelEdgeDetector(); edgeFilter.ApplyInPlace(FilteredBitmap); // Threshhold filter var threshholdFilter = new Threshold(190); threshholdFilter.ApplyInPlace(FilteredBitmap); var bitmapData = FilteredBitmap.LockBits( new Rectangle(0, 0, FilteredBitmap.Width, FilteredBitmap.Height), ImageLockMode.ReadWrite, FilteredBitmap.PixelFormat); var blobCounter = new BlobCounter { FilterBlobs = true, MinHeight = 125, MinWidth = 125 }; blobCounter.ProcessImage(bitmapData); var blobs = blobCounter.GetObjectsInformation(); FilteredBitmap.UnlockBits(bitmapData); var shapeChecker = new SimpleShapeChecker(); var bm = new Bitmap(FilteredBitmap.Width, FilteredBitmap.Height, PixelFormat.Format24bppRgb); var g = Graphics.FromImage(bm); g.DrawImage(FilteredBitmap, 0, 0); var pen = new Pen((Color)new ColorConverter().ConvertFromString(Application.Current.Resources["AccentColor"].ToString()), 5); var cardPositions = new List<IntPoint>(); // Loop through detected shapes for (int i = 0, n = blobs.Length; i < n; i++) { var edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; var sameCard = false; // is triangle or quadrilateral if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { if (!corners.Any()) return; // get sub-type var subType = shapeChecker.CheckPolygonSubType(corners); // Only return 4 corner rectanges if ((subType != PolygonSubType.Parallelogram && subType != PolygonSubType.Rectangle) || corners.Count != 4) continue; // Check if its sideways, if so rearrange the corners so it's veritcal RearrangeCorners(corners); // Prevent it from detecting the same card twice foreach (var point in cardPositions) { var distance = corners[0].DistanceTo(point); if (corners[0].DistanceTo(point) < 40) sameCard = true; } if (sameCard) continue; // Hack to prevent it from detecting smaller sections of the card instead of the whole card var area = GetArea(corners); if (area < 20000)// || area > 35000) continue; cardPositions.Add(corners[0]); g.DrawPolygon(pen, ToPointsArray(corners)); // Extract the card bitmap var transformFilter = new QuadrilateralTransformation(corners, 225, 325); CardBitmap = transformFilter.Apply(CameraBitmap); TmpCard = new MagicCard { Corners = corners, CardBitmap = CardBitmap }; } } pen.Dispose(); g.Dispose(); FilteredBitmap = bm; }
/// <summary> /// Get rectangle contain glyphs in current frame /// </summary> /// <param name="image">Frame source</param> /// <param name="lists">Rectangles contain glyphs</param> public static void GlyphsPotentialsTracking(ref UnmanagedImage image, ref List<Rectangle> lists) { // 1 - grayscaling UnmanagedImage grayImage = null; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { grayImage = image; } else { grayImage = UnmanagedImage.Create(image.Width, image.Height, PixelFormat.Format8bppIndexed); Grayscale.CommonAlgorithms.BT709.Apply(image, grayImage); } // 2 - Edge detection DifferenceEdgeDetector edgeDetector = new DifferenceEdgeDetector(); UnmanagedImage edgesImage = edgeDetector.Apply(grayImage); // 3 - Threshold edges Threshold thresholdFilter = new Threshold(80); thresholdFilter.ApplyInPlace(edgesImage); //// ---------------- MILESTONE //image = edgesImage; //return; // create and configure blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 32; blobCounter.MinWidth = 32; blobCounter.FilterBlobs = true; blobCounter.ObjectsOrder = ObjectsOrder.Size; // 4 - find all stand alone blobs blobCounter.ProcessImage(edgesImage); Blob[] blobs = blobCounter.GetObjectsInformation(); List<IntPoint> edgePoints = null; List<IntPoint> corners = null; SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); // 5 - check each blob for (int i = 0, n = blobs.Length; i < n; i++) { edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); corners = null; // does it look like a quadrilateral ? if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { // get edge points on the left and on the right side List<IntPoint> leftEdgePoints, rightEdgePoints; blobCounter.GetBlobsLeftAndRightEdges(blobs[i], out leftEdgePoints, out rightEdgePoints); // calculate average difference between pixel values from outside of the // shape and from inside float diff = CalculateAverageEdgesBrightnessDifference( leftEdgePoints, rightEdgePoints, grayImage); // check average difference, which tells how much outside is lighter than // inside on the average if (diff > 20) { lists.Add(blobs[i].Rectangle); } } } }
public List<string> DetectLicensePlate(Bitmap bitmap) { Bitmap original = (Bitmap)bitmap.Clone(); // threshold obrazku - s timto lze experimentovat a zlepsit detekci znacek v nekterych obraycich bitmap = Grayscale.CommonAlgorithms.BT709.Apply(bitmap); OtsuThreshold threshold = new OtsuThreshold(); bitmap = threshold.Apply(bitmap); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); // vyhledani objektu BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 10; blobCounter.MinWidth = 60; blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); // detekce objektu a jeho tvaru SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); //shapeChecker.AngleError = 15; //shapeChecker.MinAcceptableDistortion = 1; //shapeChecker.RelativeDistortionLimit = 0.05f; List<string> results = new List<string>(); int a = 0; string text; for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { // zjisteni typu (obdelnik, ...) PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if (corners.Count() == 4) { Bitmap rectangle = this.Transform(corners, original); text = this.Detect(rectangle); if (text.Length > 6) { results.Add(text); rectangle.Save("temp/" + text + ".jpg"); } } } } return results; }
private Bitmap ProcessImage(Bitmap bitmap) { ///CROP SYSTEM //if (cropx1 != 0 && cropy1 != 0 && cropx2 != 0 && cropy2 != 0 && Worker.selected_square != 0) //{ // Crop crop_filter = new Crop(new Rectangle(cropx1, cropy1, cropx2, cropy2)); // bitmap= crop_filter.Apply(bitmap); // Console.WriteLine(">Crop Cutter:> Cropped\n({0},{1}),({2},{3})", cropx1, cropy1, cropx2, cropy2); //} //if (Worker.selected_square == 0) //{ // Crop crop_filter = new Crop(new Rectangle(0, 0, bitmap.Width,bitmap.Height)); // bitmap = crop_filter.Apply(bitmap); // //Console.WriteLine(">Crop Cutter:> RESET"); //} //// step 2 - locating objects if (cropx1 == 0 && cropy1 == 0 && cropx2 == 0 && cropy2 == 0) { cropx1 = 0; cropy1 = 0; cropx2 = bitmap.Width; cropy2 = bitmap.Height; } Bitmap old = bitmap; Crop crop_filter = new Crop(new Rectangle(cropx1, cropy1, cropx2, cropy2)); bitmap = crop_filter.Apply(bitmap); // lock image BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); // ////invert // Invert inv = new Invert(); // // //apply the filter //inv.ApplyInPlace(bitmapData); //// create filter //HSLFiltering filter = new HSLFiltering(); //// set color ranges to keep //filter.Hue = new IntRange(90, 300); //filter.Saturation = new Range(0.0f, .5f); //filter.Luminance = new Range(0f, 1); //// apply the filter //filter.ApplyInPlace(bitmapData); //EuclideanColorFiltering filter = new EuclideanColorFiltering(); //// set center colol and radius //filter.CenterColor = new RGB(209, 206, 196); //filter.Radius = 150; //// apply the filter //filter.ApplyInPlace(bitmapData); //// create filter ChannelFiltering filter = new ChannelFiltering(); //// set channels' ranges to keep Invert inv = new Invert(); //// //apply the filter inv.ApplyInPlace(bitmapData); if (red_max > 255) { red_max = 255; Console.WriteLine("1THRESHOLD OVERIDE"); } if (blue_max > 255) { blue_max = 255; Console.WriteLine("2THRESHOLD OVERIDE"); } if (green_max > 255) { green_max = 255; Console.WriteLine("3THRESHOLD OVERIDE"); } if (red > 255) { red = 254; Console.WriteLine("4THRESHOLD OVERIDE"); } if (blue > 255) { blue = 254; Console.WriteLine("5THRESHOLD OVERIDE"); } if (green > 255) { green = 254; Console.WriteLine("6THRESHOLD OVERIDE"); } if (red < 0) { red = 1; Console.WriteLine("7THRESHOLD UNDERIDE"); } if (blue < 0) { blue = 1; Console.WriteLine("8THRESHOLD UNDERIDE"); } if (green < 0) { green = 1; Console.WriteLine("9THRESHOLD UNDERIDE"); } if (red_max < 0) { red_max = 255; Console.WriteLine("10THRESHOLD UNDERIDE"); } if (blue_max < 0) { blue_max = 255; Console.WriteLine("11THRESHOLD UNDERIDE"); } if (green_max < 0) { green_max = 255; Console.WriteLine("13THRESHOLD UNDERIDE"); } if (red_max < red) { Console.WriteLine("14THRESHOLD UNION ERROR"); red = 0; red_max = 255; } if (blue_max < blue) { blue = 0; Console.WriteLine("15THRESHOLD UNION ERROR"); blue_max = 255; } if (green_max < green) { green = 0; green_max = 255; Console.WriteLine("16THRESHOLD UNION ERROR"); } file.WriteLine("R: " + red + " R_M: " + red_max); file.WriteLine("G: " + green + " G_M: " + green_max); file.WriteLine("B: " + blue + " B_M: " + blue_max); file.WriteLine("EOE"); //file.Close(); filter.Red = new IntRange(red, red_max); filter.Green = new IntRange(green, green_max); filter.Blue = new IntRange(blue, blue_max); //// apply the filter filter.ApplyInPlace(bitmapData); ////invert //edge //CannyEdgeDetector edge_filter = new CannyEdgeDetector(); //// apply the filter //edge_filter.ApplyInPlace(bitmapData); BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = blob_size * 3; blobCounter.MinWidth = blob_size * 4; blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); // step 3 - check objects' type and highlight SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = Graphics.FromImage(bitmap); Pen yellowPen = new Pen(Color.Yellow, 2); // circles Pen redPen = new Pen(Color.Red, 2); // quadrilateral Pen brownPen = new Pen(Color.Brown, 2); // quadrilateral with known sub-type Pen greenPen = new Pen(Color.Green, 2); // known triangle Pen bluePen = new Pen(Color.Blue, 2); // triangle double curdist = 0; double leastdist = 100; //List<IntPoint> bestcorn;//promoted to super for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; // the list of x,y coordinates. corners(list)->corner(intpoint)->[x,y] // is triangle or quadrilateral if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { cornide = corners; // get sub-type PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); Pen pen; if (subType == PolygonSubType.Rectangle || subType == PolygonSubType.Trapezoid || subType == PolygonSubType.Parallelogram || subType == PolygonSubType.Rhombus || subType == PolygonSubType.Square || subType == PolygonSubType.Unknown) { if (corners.Count == 4) { pen = redPen; IntPoint[] array_of_corners = corners.ToArray();//array_of_corners is now an array of corners if (((732 / avdisty(array_of_corners)) + .222) < ((989 / avdistx(array_of_corners)) + 3.37)) { curdist = ((732 / avdisty(array_of_corners)) + .222);//from our graph } else { curdist = ((989 / avdistx(array_of_corners)) + 3.37);//from our graph } //if (Worker.selected_square == 1) //{ // Console.WriteLine("called\n"); // IntPoint one = array_of_corners[0]; // IntPoint two = array_of_corners[3]; // cropx1 = one.X - 5; // cropy1 = one.Y - 5; // cropx2 = two.X + 5; // cropy2 = two.Y + 5; //} //else if (i == Worker.selected_square - 1 && Worker.selected_square != 1) //{ // Console.WriteLine("called\n"); // IntPoint one = array_of_corners[0]; // IntPoint two = array_of_corners[3]; // cropx1 = one.X - 5; // cropy1 = one.Y - 5; // cropx2 = two.X + 5; // cropy2 = two.Y + 5; //} //if (Worker.selected_square == 0) //{ // cropx1 = 0; // cropy1 = 0; // cropx2 = 0; // cropy2 = 0; //} if (Worker.selected_square == 0)//PREDATOR VISION { if (curdist < leastdist) { // Console.WriteLine((abs(array_of_corners[0].Y - array_of_corners[1].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X))); //if ((abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) < 1.25 && (abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) > .5) if (true) { leastdist = curdist; if (leastdist < 55 && leastdist > 2) { double angle = (array_of_corners[0].X + array_of_corners[3].X) / 2; Console.WriteLine("0: " + array_of_corners[0].X + " 1: " + array_of_corners[1].X + " 2: " + array_of_corners[2].X + " 3: " + array_of_corners[3].X); Server.SetData(((array_of_corners[0].X + array_of_corners[1].X) / 2), 1); Console.WriteLine("PREDATOR: " + Server.GetData(1)); Console.WriteLine(leastdist); Server.SetData(leastdist, 0); bestcorn = corners;//superify? //g.DrawPolygon(pen, ToPointsArray(bestcorn));//leave here as a comment IntPoint ones = array_of_corners[0]; PointF string_draw = new PointF(ones.X, ones.Y); SolidBrush tbrush = new SolidBrush(Color.Red); try { if (string_draw.X != 0 && string_draw.Y != 0) { g.DrawString(n.ToString(), this.Font, tbrush, string_draw); } } catch (Exception e) { Console.WriteLine("{0} in {1} ({2},{3})", e.Message, e.StackTrace, string_draw.X, string_draw.Y); } } } } try { Graphics global_graphics_predator = Graphics.FromImage(bitmap); Pen penc = new Pen(Color.YellowGreen, 2); //g.DrawPolygon(penc, ToPointsArray(bestcorn)); global_graphics_predator.DrawPolygon(penc, ToPointsArray(bestcorn)); global_graphics_predator.DrawLine(penc, new System.Drawing.Point(320, 1), new System.Drawing.Point(320, 479)); //bitmap = global_bitmap; } catch (Exception e) { } yellowPen.Dispose(); redPen.Dispose(); greenPen.Dispose(); bluePen.Dispose(); brownPen.Dispose(); g.Dispose(); return bitmap; } else { int sel_least_dist = Worker.selected_square; sel_least_dist *= 3;//threefeet sel_least_dist -= 1; int sel_max_dist = sel_least_dist + 5; Console.WriteLine(sel_least_dist); Console.WriteLine(sel_max_dist); //Console.WriteLine(sel_least_dist + " " + sel_max_dist); if (curdist < leastdist && curdist > sel_least_dist && curdist < sel_max_dist) { // Console.WriteLine((abs(array_of_corners[0].Y - array_of_corners[1].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X))); //if ((abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) < 1.25 && (abs(array_of_corners[0].Y - array_of_corners[3].Y)) / (abs(array_of_corners[0].X - array_of_corners[1].X)) > .5) if (true)//todo { leastdist = curdist; if (leastdist < 55 && leastdist > 2) { // Console.WriteLine("0: " + array_of_corners[0].X + " 1: " + array_of_corners[1].X + " 2: " + array_of_corners[2].X + " 3: " + array_of_corners[3].X); Server.SetData(((array_of_corners[0].X + array_of_corners[1].X) / 2), 1); Console.WriteLine(Server.GetData(1)); //Console.WriteLine(leastdist); Server.SetData(leastdist, 0); bestcorn = corners;//superify? //g.DrawPolygon(pen, ToPointsArray(bestcorn));//leave here as a comment IntPoint ones = array_of_corners[0]; PointF string_draw = new PointF(ones.X, ones.Y); SolidBrush tbrush = new SolidBrush(Color.Red); try { if (string_draw.X != 0 && string_draw.Y != 0) { g.DrawString(n.ToString(), this.Font, tbrush, string_draw); // glob.DrawLine(penc, new System.Drawing.Point(10, 10), new System.Drawing.Point(20, 20)); //g.DrawLine(pen, new System.Drawing.Point(10, 10), new System.Drawing.Point(20, 20)); } } catch (Exception e) { Console.WriteLine("{0} in {1} ({2},{3})", e.Message, e.StackTrace, string_draw.X, string_draw.Y); } } } } } //pen = (corners.Count == 4) ? redPen : bluePen; }//TODO get rid of anything that ISNT drawn, eg corner } //else //{ // pen = (corners.Count == 4) ? brownPen : greenPen; //} } } //Console.WriteLine(leastdist); how dod oyo //double leastdist = 0; //for (int i = 0, n = blobs.Length; i < n; i++) //{ // try // { // List<IntPoint> filterlist; // filterlist = cornide; // IntPoint[] filter_corners = filterlist.ToArray(); // double currentdist = 0; // for (int corner_count = 0; corner_count < filter_corners.Length; corner_count++) // { // IntPoint one_f = filter_corners[corner_count]; // corner_count++; // IntPoint two_f = filter_corners[corner_count]; // corner_count++; // IntPoint three_f = filter_corners[corner_count]; // corner_count++; // IntPoint four_f = filter_corners[corner_count]; // double y_average_a = ((double)one_f.Y + (double)two_f.Y) / 2; // double y_average_b = ((double)three_f.Y + (double)four_f.Y) / 2; // double averaged_dist = y_average_b - y_average_a; // currentdist = ((732 / averaged_dist) + .222);//from our graph // if (currentdist <= leastdist) // { // leastdist = currentdist; // Pen pencil = redPen; // g.DrawPolygon(pencil, ToPointsArray(filterlist)); // } // } // } // catch // { // //do nothING // } //} //Console.WriteLine(leastdist); try { Graphics global_graphics = Graphics.FromImage(global_bitmap); Pen penc = new Pen(Color.YellowGreen, 2); { //g.DrawPolygon(penc, ToPointsArray(bestcorn)); global_graphics.DrawPolygon(penc, ToPointsArray(bestcorn)); global_graphics.DrawLine(penc, new System.Drawing.Point(320, 1), new System.Drawing.Point(320, 479)); bitmap = global_bitmap; } } catch (Exception e) { } try { g.DrawLine(redPen, 220, 1, 220, 100); } catch (Exception e) { Console.WriteLine(e.StackTrace); Console.WriteLine(e.InnerException); } yellowPen.Dispose(); redPen.Dispose(); greenPen.Dispose(); bluePen.Dispose(); brownPen.Dispose(); g.Dispose(); return bitmap; }
/// <summary> /// Gets the squares in the image /// </summary> /// <param name="cubeFace">Image to get the squares</param> /// <param name="minWidth">Minimum square width</param> /// <param name="minHeight">Minimum square height</param> /// <returns>Returns the list with the squares.</returns> public List<Rectangle> GetSquares(System.Drawing.Image cubeFace, int minWidth, int minHeight) { Squares = new List<Rectangle>(); Bitmap bitmap = new Bitmap(cubeFace); // lock image System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat); // step 1 - turn background to black ColorFiltering colorFilter = new ColorFiltering(); colorFilter.Red = new AForge.IntRange(0, 64); colorFilter.Green = new AForge.IntRange(0, 64); colorFilter.Blue = new AForge.IntRange(0, 64); colorFilter.FillOutsideRange = false; colorFilter.ApplyInPlace(bitmapData); // step 2 - locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = minHeight; blobCounter.MinWidth = minWidth; blobCounter.ProcessImage(bitmapData); AForge.Imaging.Blob[] blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); // step 3 - check objects' type and highlight SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; // is triangle or quadrilateral if (shapeChecker.IsConvexPolygon(edgePoints, out corners) && corners.Count == 4) { Squares.Add(blobs[i].Rectangle); } } return Squares; }
/// <summary> /// Initialize the needed components for this class. /// </summary> public void Initialize() { this.shapeChecker = new SimpleShapeChecker(); this.CellList = new List<ColonyModel>(); this.blobList = new List<Blob>(); // SET COLOR RANGE FOR BACKGROUND RangeRed = new IntRange(255,255); RangeGreen = new IntRange(255, 255); RangeBlue = new IntRange(255, 255); }
private void ParseImage(int imageId) { DateTime startTime = DateTime.Now; Console.WriteLine(string.Format("Start parsing {0}", startTime)); string difImagePath = ""; if (imageId >= 0) difImagePath = DifBoardImages[imageId]; Bitmap orig; Bitmap dif; try { Console.WriteLine("Load files"); orig = (Bitmap)Bitmap.FromFile(OriginalBoardImage); if (imageId >= 0) dif = (Bitmap)Bitmap.FromFile(difImagePath); else dif = (Bitmap)internalImageContainer; } catch (Exception ex) { Console.WriteLine("ERR: " + ex.Message); Console.WriteLine(ex.StackTrace); // kill any exception due to missing files return; } Difference filter = new Difference(orig); dif = filter.Apply(dif); Console.WriteLine("Apply difference filter"); BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(dif); Console.WriteLine("Blob counting"); Blob[] blobs = blobCounter.GetObjectsInformation(); // create Graphics object to draw on the image and a pen Graphics g = Graphics.FromImage(dif); Pen redPen = new Pen(Color.Red, 3); Pen bluePen = new Pen(Color.Blue, 1); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); // 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]); Console.Write(string.Format("Detected {0} points", edgePoints.Count)); if (edgePoints.Count <= 1) continue; List<IntPoint> points = new List<IntPoint>(); if (shapeChecker.IsQuadrilateral(edgePoints)) Console.Write(", quadrilateral"); else if (shapeChecker.IsConvexPolygon(edgePoints, out points)) Console.Write(", convex poligon"); else if (shapeChecker.IsTriangle(edgePoints, out points)) Console.Write(", triangle"); Pen usePen = shapeChecker.IsQuadrilateral(edgePoints) ? redPen : bluePen; int centerX = edgePoints[0].X; int centerY = edgePoints[0].Y; for (int j = 0; j < edgePoints.Count - 1; j++) { centerX += edgePoints[j + 1].X; centerY += edgePoints[j + 1].Y; g.DrawLine(usePen, edgePoints[j].X, edgePoints[j].Y, edgePoints[j + 1].X, edgePoints[j + 1].Y); } // add last point centerX += edgePoints[edgePoints.Count - 1].X; centerY += edgePoints[edgePoints.Count - 1].Y; g.DrawLine(usePen , edgePoints[0].X, edgePoints[0].Y , edgePoints[edgePoints.Count - 1].X, edgePoints[edgePoints.Count - 1].Y); Console.WriteLine(string.Format("\nOriginal (x, y): {0}, {1}" , new object[] { (centerX / edgePoints.Count), (centerY / edgePoints.Count) })); Console.WriteLine(string.Format("Detected (x, y): {0}, {1}" , (centerX / edgePoints.Count) , (centerY / edgePoints.Count) )); } redPen.Dispose(); bluePen.Dispose(); g.Dispose(); //DifI = dif; dif.Save(dirPath + "processed-dif.jpg"); Console.WriteLine(string.Format("Duration: {0} sec", (DateTime.Now - startTime))); }
private void Button_Click_1(object sender, RoutedEventArgs e) { // Open your image string path = file.FullName; Bitmap image = (Bitmap)Bitmap.FromFile(path); // locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 1; blobCounter.MinWidth = 1; 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<System.Drawing.Point> Points = new List<System.Drawing.Point>(); bool flag = false; foreach (var point in cornerPoints) { if (point.X == 0 && point.Y == 0) flag = true; Points.Add(new System.Drawing.Point(point.X, point.Y)); } if (flag) continue; Graphics g = Graphics.FromImage(image); g.DrawPolygon(new Pen(Color.Red, 5.0f), Points.ToArray()); _rect++; image.Save("result.png"); } } else if (shapeChecker.IsTriangle(edgePoints, out cornerPoints)) { 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)); } Graphics g = Graphics.FromImage(image); g.DrawPolygon(new Pen(Color.Red, 5.0f), Points.ToArray()); _tri++; image.Save("result.png"); } } BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.UriSource = new Uri(file.Directory + @"\result.png"); bi.EndInit(); IMG_AFTER.Source = bi; TB_OUT.Text = "На картинке " + _rect-- + " прямоугольника \r\nИ " + _tri + " треугольника"; }
//returns corners of found rectangle public List<IntPoint> getCorners(Bitmap toEdit) { Bitmap bitmap = new Bitmap(toEdit); List<IntPoint> corners = new List<IntPoint>(); List<IntPoint> oneBlob = new List<IntPoint>(); // lock image BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); //black background ColorFiltering colorFilter = new ColorFiltering(); colorFilter.Red = new IntRange(0, 64); colorFilter.Green = new IntRange(0, 64); colorFilter.Blue = new IntRange(0, 64); colorFilter.FillOutsideRange = false; colorFilter.ApplyInPlace(bitmapData); //locate figurres BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 8; blobCounter.MinWidth = 8; blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); //check object type SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = Graphics.FromImage(bitmap); for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); // check if trainge of rectangle if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { // get subtype (is rectangle?) PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if (subType == PolygonSubType.Rectangle) { for (int j = 0; j < 4; j++) { for (int k = 0; k < 3; k++) { IntPoint temp = new IntPoint(); if (j < 3) { if (corners[k].Y > corners[k + 1].Y) { temp = corners[k]; corners[k] = corners[k + 1]; corners[k + 1] = temp; } } } } //sort list of corners if (corners[0].X > corners[1].X) { IntPoint temp = new IntPoint(); temp = corners[0]; corners[0] = corners[1]; corners[1] = temp; } if (corners[3].X > corners[2].X) { IntPoint temp = new IntPoint(); temp = corners[2]; corners[2] = corners[3]; corners[3] = temp; } int blobHeigth = Math.Abs(corners[3].Y - corners[0].Y); int blobWidth = Math.Abs(corners[1].X - corners[0].X); if (blobHeigth < blobWidth) { // float ratio = blobWidth / blobHeigth; // if(ratio > 1) oneBlob = corners; } } } } g.Dispose(); // put new image to clipboard Clipboard.SetDataObject(bitmap); // and to picture box // pictureBox.Image = bitmap; return oneBlob; // UpdatePictureBoxPosition(); }
// Process image public Bitmap ProcessImage(Bitmap toEdit) { Bitmap bitmap = new Bitmap(toEdit); List<IntPoint> corners = new List<IntPoint>(); // lock image BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); //black background ColorFiltering colorFilter = new ColorFiltering(); colorFilter.Red = new IntRange(0, 64); colorFilter.Green = new IntRange(0, 64); colorFilter.Blue = new IntRange(0, 64); colorFilter.FillOutsideRange = false; colorFilter.ApplyInPlace(bitmapData); //locating figures BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); //check type of figure SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = Graphics.FromImage(bitmap); Pen redPen = new Pen(Color.Red, 2); // pen to colour egdes for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); // is triangle or rectangle if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { // get subtype (is rectangle?) PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); Pen pen; /* if (subType == PolygonSubType.Unknown) { pen = (corners.Count == 4) ? redPen : bluePen; } else { pen = (corners.Count == 4) ? brownPen : greenPen; } */ if (subType == PolygonSubType.Rectangle) { int blobHeigth = Math.Abs(corners[3].Y - corners[0].Y); int blobWidth = Math.Abs(corners[1].X - corners[0].X); if (blobHeigth < blobWidth) { pen = redPen; g.DrawPolygon(pen, ToPointsArray(corners)); } } } } redPen.Dispose(); g.Dispose(); Clipboard.SetDataObject(bitmap); // and to picture box // pictureBox.Image = bitmap; return bitmap; // UpdatePictureBoxPosition(); }
// Process image private void ProcessImage( Bitmap bitmap ) { // lock image BitmapData bitmapData = bitmap.LockBits( new Rectangle( 0, 0, bitmap.Width, bitmap.Height ), ImageLockMode.ReadWrite, bitmap.PixelFormat ); // step 1 - turn background to black ColorFiltering colorFilter = new ColorFiltering( ); colorFilter.Red = new IntRange( 0, 64 ); colorFilter.Green = new IntRange( 0, 64 ); colorFilter.Blue = new IntRange( 0, 64 ); colorFilter.FillOutsideRange = false; colorFilter.ApplyInPlace( bitmapData ); // step 2 - locating objects BlobCounter blobCounter = new BlobCounter( ); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.ProcessImage( bitmapData ); Blob[] blobs = blobCounter.GetObjectsInformation( ); bitmap.UnlockBits( bitmapData ); // step 3 - check objects' type and highlight SimpleShapeChecker shapeChecker = new SimpleShapeChecker( ); Graphics g = Graphics.FromImage( bitmap ); Pen yellowPen = new Pen( Color.Yellow, 2 ); // circles Pen redPen = new Pen( Color.Red, 2 ); // quadrilateral Pen brownPen = new Pen( Color.Brown, 2 ); // quadrilateral with known sub-type Pen greenPen = new Pen( Color.Green, 2 ); // known triangle Pen bluePen = new Pen( Color.Blue, 2 ); // triangle for ( int i = 0, n = blobs.Length; i < n; i++ ) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints( blobs[i] ); AForge.Point center; float radius; // is circle ? if ( shapeChecker.IsCircle( edgePoints, out center, out radius ) ) { g.DrawEllipse( yellowPen, (float) ( center.X - radius ), (float) ( center.Y - radius ), (float) ( radius * 2 ), (float) ( radius * 2 ) ); } else { List<IntPoint> corners; // is triangle or quadrilateral if ( shapeChecker.IsConvexPolygon( edgePoints, out corners ) ) { // get sub-type PolygonSubType subType = shapeChecker.CheckPolygonSubType( corners ); Pen pen; if ( subType == PolygonSubType.Unknown ) { pen = ( corners.Count == 4 ) ? redPen : bluePen; } else { pen = ( corners.Count == 4 ) ? brownPen : greenPen; } g.DrawPolygon( pen, ToPointsArray( corners ) ); } } } yellowPen.Dispose( ); redPen.Dispose( ); greenPen.Dispose( ); bluePen.Dispose( ); brownPen.Dispose( ); g.Dispose( ); // put new image to clipboard Clipboard.SetDataObject( bitmap ); // and to picture box pictureBox.Image = bitmap; UpdatePictureBoxPosition( ); }
// Summary - Gets the exterior rectangles. /*************** * It uses a different JPEG altogether due to bpp issue (only 24 or 32 is acceptable). * Selects the rectangles on the basis of area (around 350 to 400). * Sends the quadrilaterals (4 of them) with their 4 coordinates (each) to DecideCorners for trimming. */ public void PreProcess() { Bitmap bitmap = this.scanned_image; List<List<IntPoint>> QuadCorners = new List<List<IntPoint>>(4); BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); // step 1 - turn background to black ColorFiltering colorFilter = new ColorFiltering(); colorFilter.Red = new IntRange(0, 64); colorFilter.Green = new IntRange(0, 64); colorFilter.Blue = new IntRange(0, 64); colorFilter.FillOutsideRange = false; //MessageBox.Show(bitmapData.PixelFormat.ToString()); colorFilter.ApplyInPlace(bitmapData); // step 2 - locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); // step 3 - check objects' type and highlight SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); //int count = 0; Pen redPen = new Pen(Color.Red, 2); Graphics g = Graphics.FromImage(bitmap); // Threshold area values for rectangles. It doesnt have a specific equation for the value based on threshold. // Values have been tested and set accordingly. int area_upper = 0, area_lower = 0; if (Scanner_DPI.dpi_value == 200) { area_lower = 2000; area_upper = 3000; } else if (Scanner_DPI.dpi_value == 300) { area_lower = 5000; area_upper = 6000; } for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; // is quadrilateral if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { // get sub-type PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if (subType == PolygonSubType.Rectangle && blobs[i].Area > area_lower && blobs[i].Area < area_upper) { //g.DrawPolygon(redPen, ToPointsArray(corners)); QuadCorners.Add(corners); } } } this.scanned_image = DecideCorners(QuadCorners); }
private void ParseImage(int imageId) { DateTime startTime = DateTime.Now; labelDetection.Text = ""; string difImagePath = ""; if(imageId >= 0) difImagePath = DifBoardImages[imageId]; Bitmap orig; Bitmap dif; try { orig = (Bitmap)Bitmap.FromFile(OriginalBoardImage); if (imageId >= 0) dif = (Bitmap)Bitmap.FromFile(difImagePath); else dif = (Bitmap)pictureBoxGenerated.Image; } catch { // kill any exception due to missing files return; } pictureBoxOrig.Image = dif; Difference filter = new Difference(orig); dif = filter.Apply(dif); BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(dif); Blob[] blobs = blobCounter.GetObjectsInformation(); // create Graphics object to draw on the image and a pen Graphics g = Graphics.FromImage(dif); Pen redPen = new Pen(Color.Red, 3); Pen bluePen = new Pen(Color.Blue, 1); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); // 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]); labelDetection.Text = string.Format("{0} points", edgePoints.Count); if (edgePoints.Count <= 1) continue; List<IntPoint> points = new List<IntPoint>(); if (shapeChecker.IsQuadrilateral(edgePoints)) labelDetection.Text += ", quadrilateral"; else if (shapeChecker.IsConvexPolygon(edgePoints, out points)) labelDetection.Text += ", convex poligon"; else if (shapeChecker.IsTriangle(edgePoints, out points)) labelDetection.Text += ", triangle"; Pen usePen = shapeChecker.IsQuadrilateral(edgePoints) ? redPen : bluePen; int centerX = edgePoints[0].X; int centerY = edgePoints[0].Y; int minX = centerX; int minY = centerY; int maxX = centerX; int maxY = centerY; for (int j = 0; j < edgePoints.Count - 1; j++) { centerX += edgePoints[j + 1].X; centerY += edgePoints[j + 1].Y; if (edgePoints[j + 1].X < minX) minX = edgePoints[j + 1].X; if (edgePoints[j + 1].Y < minY) minY = edgePoints[j + 1].Y; if (edgePoints[j + 1].X > maxX) maxX = edgePoints[j + 1].X; if (edgePoints[j + 1].Y > maxX) maxX = edgePoints[j + 1].Y; g.DrawLine(usePen, edgePoints[j].X, edgePoints[j].Y, edgePoints[j + 1].X, edgePoints[j + 1].Y); } g.DrawLine(usePen , edgePoints[0].X, edgePoints[0].Y , edgePoints[edgePoints.Count - 1].X, edgePoints[edgePoints.Count - 1].Y); labelDetectedPosition.Text = string.Format("{0}, {1}" , new object[] { (centerX / edgePoints.Count), (centerY / edgePoints.Count) //, maxX - minX, maxY - minY }); labelDetectionOffset.Text = string.Format("{0}, {1}" , Grigore.Position.X - (centerX / edgePoints.Count) , Grigore.Position.Y - (centerY / edgePoints.Count) ); } redPen.Dispose(); bluePen.Dispose(); g.Dispose(); pictureBoxRoboBoard.Image = dif; labelDetection.Text = string.Format("{1}, {0} sec", (DateTime.Now - startTime), labelDetection.Text); }
public void blob_detect () { Bitmap image = this.scanned_image; BlobCounter blob = new BlobCounter(); blob.FilterBlobs = false; int blob_ht_width = 30; blob.MinHeight = blob_ht_width; blob.MinWidth = blob_ht_width; blob.ProcessImage(image); Blob[] b = blob.GetObjectsInformation(); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); /*blob_counter.Text = b.Length.ToString(); Graphics g = Graphics.FromImage(image2); Pen yellowPen = new Pen(Color.Yellow, 5); Pen redPen = new Pen(Color.Red, 5); Pen greenPen = new Pen(Color.Green, 5); int b_counter = 0; */ for (int i = 0, n = b.Length; i < n; i++) { List<IntPoint> edgePoints = blob.GetBlobsEdgePoints(b[i]); List<IntPoint> edges = new List<IntPoint>(); AForge.Point center; float radius; if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { if (b[i].Fullness * 100 >= 40 && b[i].Fullness * 100 < 100 && radius > 10) { Coordinate coor = new Coordinate(center.X, center.Y); BLOB blb = new BLOB(coor, radius); useful.Add(blb); } } } }
public ActionResult Index(string Data, int Smallest = 3, int Largest = 6, HttpPostedFileBase file = null) { string base64Image = null; if (file != null) { //try to determine data from posted file var bitmap = new Bitmap(file.InputStream); // lock image BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); // step 1 - turn background to black var filter = new Invert(); filter.ApplyInPlace(bitmapData); ColorFiltering colorFilter = new ColorFiltering(); colorFilter.Red = new IntRange(0, 64); colorFilter.Green = new IntRange(0, 64); colorFilter.Blue = new IntRange(0, 64); colorFilter.FillOutsideRange = false; colorFilter.ApplyInPlace(bitmapData); // step 2 - locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.ProcessImage(bitmapData); var blobs = blobCounter.GetObjectsInformation(); bitmap.UnlockBits(bitmapData); base64Image = bitmap.ToBase64(); // get information about detected objects var shapeChecker = new SimpleShapeChecker(); var letters = new List<Letter>(); int circleCount = 0; foreach ( var blob in blobs.ToArray() .OrderBy(b => b.Rectangle.Top) .ThenBy(b => b.Rectangle.Left) .ThenByDescending(b => b.Area)) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); AForge.Point center; float radius; if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { //Todo: filter on the largest radius * 90% to deal with resolutions if (radius < 40) continue; blobCounter.ExtractBlobsImage(bitmap, blob, false); var letter = blob.Image.ToManagedImage(true); var resizeFilter = new ResizeBilinear(150, 150); letter = resizeFilter.Apply(letter); var bwBitmap = new Bitmap(75, 75, PixelFormat.Format32bppArgb); for (int y = 40; y < 115; y++) { for (int x = 40; x < 115; x++) { var color = letter.GetPixel(x, y); if (color.Name == "ff000000") { bwBitmap.SetPixel(x - 40, y - 40, Color.Black); } else { bwBitmap.SetPixel(x - 40, y - 40, Color.White); } } } letters.Add(new Letter { L = TrainingData.GetBestGuess(bwBitmap), X = center.X, Y = center.Y, Radius = radius }); } } var minX = letters.Min(c => c.X); var maxX = letters.Max(c => c.X); var minY = letters.Min(c => c.Y); var maxY = letters.Max(c => c.Y); var smallestRadius = letters.Min(c => c.Radius); var numberOfItemsPerRow = (int)((maxX - minX)/ smallestRadius / 2); var numberOfItemsPerCol = (int)((maxY - minY) / smallestRadius / 2); var spaceBetweenPointsX = (maxX - minX)/numberOfItemsPerRow; var spaceBetweenPointsY = (maxY - minY) / numberOfItemsPerCol; var varianceDelta = smallestRadius*.05f; //allow 5% pixel float var puzzle = new StringBuilder(); for (var y = minY; y <= maxY; y += spaceBetweenPointsY) { for (var x = minX; x <= maxX; x += spaceBetweenPointsX) { var item = letters.FirstOrDefault(c => c.X > x - varianceDelta && c.X < x + varianceDelta && c.Y > y - varianceDelta && c.Y < y + varianceDelta); if (item != null) puzzle.Append(item.L); else puzzle.Append("_"); } puzzle.AppendLine(); } Data = puzzle.ToString(); } var solutions = SolvePuzzle(Data, Smallest, Largest); return View(new PuzzleModel { Data = Data, Largest = Largest, Smallest = Smallest, Solutions = solutions, Base64Image = base64Image }); }
public Form1() { InitializeComponent(); Bitmap image = new Bitmap(@"C:\Images\bitmap.bmp"); Invert filter = new Invert(); // apply the filter filter.ApplyInPlace(image); var shapeChecker = new SimpleShapeChecker(); BlobCounter blobCounter = new BlobCounter(); // process input image blobCounter.ProcessImage(image); // get information about detected objects Blob[] blobs = blobCounter.GetObjectsInformation(); var squares = 0; Graphics g = Graphics.FromImage(image); Pen bluePen = new Pen(Color.Yellow, 2); Pen redpen = new Pen(Color.Red, 2); var quads = blobs.Where(x => shapeChecker.IsQuadrilateral(blobCounter.GetBlobsEdgePoints(x))); var largest = quads.OrderByDescending(x => x.Area).First(); List<IntPoint> largestedgePoints = blobCounter.GetBlobsEdgePoints(largest); List<IntPoint> largestcorners; shapeChecker.IsQuadrilateral(largestedgePoints, out largestcorners); var largestpoints = largestcorners.Select(x => new PointF(x.X, x.Y)).ToArray(); //g.DrawPolygon(redpen, largestpoints); for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners; Point center; float radius; if(blobs[i].Area < 150) continue; if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { var a = corners.Select(x => new IntPoint(x.X, x.Y)).ToList(); var shape = shapeChecker.CheckPolygonSubType(a); if (shape == PolygonSubType.Square || shape == PolygonSubType.Rectangle) { if (corners.Min(x => x.Y) < largestcorners.Min(x => x.Y) || corners.Min(x => x.Y) > largestcorners.Max(x => x.Y)) { var points = corners.Select(x => new PointF(x.X, x.Y)).ToArray(); g.DrawPolygon(bluePen, points); } } } else if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { //g.DrawEllipse(bluePen, // (int)(center.X - radius), // (int)(center.Y - radius), // (int)(radius * 2), // (int)(radius * 2)); } } pictureBox1.Image = image; bluePen.Dispose(); g.Dispose(); }
public bool markKnownForms() { if (currentImage != null) { try { Bitmap image = new Bitmap(this.currentImage); // lock image BitmapData bmData = image.LockBits( new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat); // turn background to black ColorFiltering cFilter = new ColorFiltering(); cFilter.Red = new IntRange(0, 64); cFilter.Green = new IntRange(0, 64); cFilter.Blue = new IntRange(0, 64); cFilter.FillOutsideRange = false; cFilter.ApplyInPlace(bmData); // locate objects BlobCounter bCounter = new BlobCounter(); bCounter.FilterBlobs = true; bCounter.MinHeight = 5; bCounter.MinWidth = 5; bCounter.ProcessImage(bmData); numberOfShellsDetected = bCounter.ObjectsCount; Blob[] baBlobs = bCounter.GetObjectsInformation(); image.UnlockBits(bmData); // coloring objects SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = Graphics.FromImage(image); Pen yellowPen = new Pen(Color.Yellow, 2); // circles Pen redPen = new Pen(Color.Red, 2); // quadrilateral Pen brownPen = new Pen(Color.Brown, 2); // quadrilateral with known sub-type Pen greenPen = new Pen(Color.Green, 2); // known triangle Pen bluePen = new Pen(Color.Blue, 2); // triangle for (int i = 0, n = baBlobs.Length; i < n; i++) { List<IntPoint> edgePoints = bCounter.GetBlobsEdgePoints(baBlobs[i]); foreach (IntPoint point in edgePoints) g.DrawEllipse(redPen, point.X, point.Y, 2, 2); /*AForge.Point center; float radius; // is circle ? if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { numberOfShellsDetected++; g.DrawEllipse(redPen, (float)(center.X - radius), (float)(center.Y - radius), (float)(radius * 2), (float)(radius * 2)); }*/ /*else { List<IntPoint> corners; // is triangle or quadrilateral if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); Pen pen; if (subType == PolygonSubType.Unknown) { pen = (corners.Count == 4) ? redPen : bluePen; } else { pen = (corners.Count == 4) ? brownPen : greenPen; } g.DrawPolygon(pen, ToPointsArray(corners)); } }*/ } yellowPen.Dispose(); redPen.Dispose(); greenPen.Dispose(); bluePen.Dispose(); brownPen.Dispose(); g.Dispose(); this.currentImage = image; return true; } catch (Exception e) { } } return false; }
// todo: implement this //public IBlobsFilter BlobsFilter /// <summary> /// uses AForge to detect square (or rectangular, if tile is obscured) tiles in the image /// </summary> /// <param name="img"></param> public void DetectBlobsInImage(Bitmap img) { BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(img); Blob[] blobs = blobCounter.GetObjectsInformation(); Graphics g = Graphics.FromImage(img); System.Drawing.Pen bluePen = new System.Drawing.Pen(System.Drawing.Color.Blue, 10); for (int i = 0, n = blobs.Length; i < n; i++) { try { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if (subType == PolygonSubType.Square) { g.DrawPolygon(bluePen, PointsListToArray(corners)); } } catch (Exception) { } } bluePen.Dispose(); g.Dispose(); }
public static IEnumerable<MagicCard> DetectCardArt(Bitmap cameraBitmap) { var ret = new List<MagicCard>(); var filteredBitmap = Grayscale.CommonAlgorithms.BT709.Apply(cameraBitmap); // edge filter var edgeFilter = new SobelEdgeDetector(); edgeFilter.ApplyInPlace(filteredBitmap); // Threshhold filter var threshholdFilter = new Threshold(190); threshholdFilter.ApplyInPlace(filteredBitmap); var bitmapData = filteredBitmap.LockBits( new Rectangle(0, 0, filteredBitmap.Width, filteredBitmap.Height), ImageLockMode.ReadWrite, filteredBitmap.PixelFormat); var blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 125; blobCounter.MinWidth = 125; blobCounter.ProcessImage(bitmapData); var blobs = blobCounter.GetObjectsInformation(); filteredBitmap.UnlockBits(bitmapData); var shapeChecker = new SimpleShapeChecker(); var bm = new Bitmap(filteredBitmap.Width, filteredBitmap.Height, PixelFormat.Format24bppRgb); var cardPositions = new List<IntPoint>(); foreach (var blob in blobs) { var edgePoints = blobCounter.GetBlobsEdgePoints(blob); List<IntPoint> corners; // only operate on 4 sided polygons if (shapeChecker.IsConvexPolygon(edgePoints, out corners)) { var subtype = shapeChecker.CheckPolygonSubType(corners); if (corners.Count() != 4) continue; if (subtype != PolygonSubType.Parallelogram && subtype != PolygonSubType.Rectangle) continue; // if the image is sideways, rotate it so it'll match the DB card art corners = Utilities.RotateCorners(corners).ToList(); if (Utilities.GetArea(corners) < 20000) continue; ret.Add( new MagicCard(cameraBitmap, corners)); } } return ret; }
// ========================================================= private Bitmap DrawRectanglesFunct(Bitmap image) { // step 1 - turn background to black (done) // step 2 - locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 3; blobCounter.MinWidth = 3; blobCounter.ProcessImage(image); Blob[] blobs = blobCounter.GetObjectsInformation(); // step 3 - check objects' type and do what you do: Graphics g = Graphics.FromImage(image); Pen pen = new Pen(Color.DarkOrange, 2); for (int i = 0, n = blobs.Length; i < n; i++) { SimpleShapeChecker ShapeChecker = new SimpleShapeChecker(); List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List<IntPoint> cornerPoints; // fine tune ShapeChecker ShapeChecker.AngleError = 15; // default 7 ShapeChecker.LengthError = 0.3F; // default 0.1 (10%) ShapeChecker.MinAcceptableDistortion = 0.9F; // in pixels, default 0.5 ShapeChecker.RelativeDistortionLimit = 0.2F; // default 0.03 (3%) // use the Outline 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) { List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); g.DrawPolygon(pen, ToPointsArray(corners)); } } } return (image); }
// ========================================================================================================== // Circles: // ========================================================================================================== private List<Shapes.Circle> FindCirclesFunct(Bitmap bitmap) { // locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.ProcessImage(bitmap); Blob[] blobs = blobCounter.GetObjectsInformation(); List<Shapes.Circle> Circles = new List<Shapes.Circle>(); for (int i = 0, n = blobs.Length; i < n; i++) { SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); AForge.Point center; float radius; // is circle ? if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { if (radius > 3) // MirrFilter out some noise { Circles.Add(new Shapes.Circle(center.X, center.Y, radius)); } } } return (Circles); }
private async Task<IList<Rect>> GetPlateRectanglesAsync(Bitmap image) { var rectanglePoints = await Task.Factory.StartNew(() => { var blobCounter = new BlobCounter { FilterBlobs = true, MinHeight = 5, MinWidth = 5 }; blobCounter.ProcessImage(image); var blobs = blobCounter.GetObjectsInformation(); var shapeChecker = new SimpleShapeChecker(); var rectPoints = new List<List<AForgePoint>>(); foreach (var blob in blobs) { List<IntPoint> cornerPoints; var edgePoints = blobCounter.GetBlobsEdgePoints(blob); var points = new List<AForgePoint>(); if (shapeChecker.IsQuadrilateral(edgePoints, out cornerPoints)) { var polygonType = shapeChecker.CheckPolygonSubType(cornerPoints); if (polygonType == PolygonSubType.Rectangle || polygonType == PolygonSubType.Parallelogram) { foreach (var point in cornerPoints) { points.Add(new AForgePoint(point.X, point.Y)); } rectPoints.Add(points); } } } return rectPoints; }); var rects = rectanglePoints.Select(points => GetRect(points)).ToList(); var images = new List<WriteableBitmap>(); var cadidatesRects = new List<Rect>(); foreach (var rect in rects) { var ratio = rect.Height / rect.Width; if (ratio >= MinPlateRatio && ratio <= MaxPlateRatio) { cadidatesRects.Add(rect); } } return cadidatesRects; }
// Process specified image trying to recognize counter's image public void Process( Bitmap image, IImageProcessingLog log ) { log.AddMessage( "Image size: " + image.Width + " x " + image.Height ); // 1- grayscale image Bitmap grayImage = Grayscale.CommonAlgorithms.BT709.Apply( image ); log.AddImage( "Grayscale", grayImage ); // 2 - Otsu thresholding OtsuThreshold threshold = new OtsuThreshold( ); Bitmap binaryImage = threshold.Apply( grayImage ); log.AddImage( "Binary", binaryImage ); log.AddMessage( "Otsu threshold: " + threshold.ThresholdValue ); // 3 - Blob counting BlobCounter blobCounter = new BlobCounter( ); blobCounter.FilterBlobs = true; blobCounter.MinWidth = 24; blobCounter.MinWidth = 24; blobCounter.ProcessImage( binaryImage ); Blob[] blobs = blobCounter.GetObjectsInformation( ); log.AddMessage( "Found blobs (min width/height = 24): " + blobs.Length ); // 4 - check shape of each blob SimpleShapeChecker shapeChecker = new SimpleShapeChecker( ); log.AddMessage( "Found coins: " ); int count = 0; // create graphics object for drawing on image Graphics g = Graphics.FromImage( image ); Pen pen = new Pen( Color.Red, 3 ); foreach ( Blob blob in blobs ) { List<IntPoint> edgePoint = blobCounter.GetBlobsEdgePoints( blob ); // check if shape looks like a circle DoublePoint center; double radius; if ( shapeChecker.IsCircle( edgePoint, out center, out radius ) ) { count++; log.AddMessage( string.Format( " {0}: center = ({1}, {2}), radius = {3}", count, center.X, center.Y, radius ) ); // highlight coin g.DrawEllipse( pen, (int) ( center.X - radius ), (int) ( center.Y - radius ), (int) ( radius * 2 ), (int) ( radius * 2 ) ); } } g.Dispose( ); pen.Dispose( ); log.AddMessage( "Total coins: " + count); log.AddImage( "Coins", image ); }