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(); }
private void colorOfPlayer(Bitmap bitmap) { HSLFiltering GreenFilter = new HSLFiltering(); GreenFilter.Hue = new IntRange(200, 250); GreenFilter.Saturation = new Range(0.5f, 1); GreenFilter.Luminance = new Range(0.2f, 0.6f); GreenFilter.ApplyInPlace(bitmap); wbt = (WriteableBitmap)bitmap; img2.Source = wbt; img2.Visibility = Visibility.Visible; // this.PictureBox.Source = (ImageSource)concatenate.Apply(this.img2); BlobCounter blobCounter = new AForge.Imaging.BlobCounter(); blobCounter.ObjectsOrder = ObjectsOrder.Area; blobCounter.FilterBlobs = true; blobCounter.MinHeight = 10; blobCounter.MinWidth = 10; blobCounter.ProcessImage(bitmap); Blob[] blobs = blobCounter.GetObjectsInformation(); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); try { 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)) { if ((blobs[i].Area < 17000) && (blobs[i].Area > 3000)) { score = score + 2; } else if ((blobs[i].Area < 3000) && (blobs[i].Area > 1300)) { score = score + 4; } else if (blobs[i].Area < 1300) { score = score + 6; } } } }catch (Exception eeeee) { } text_score.Text = "" + score; }
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 Bitmap ProcessFrame(Bitmap inputBitmap, int x, int y) { // Create an image for AForge to process Bitmap workingImage = new Bitmap(inputBitmap.Width, inputBitmap.Height); workingImage = AForge.Imaging.Image.Clone(inputBitmap, PixelFormat.Format24bppRgb); // Create a mask for ROI selection Rectangle roi = new Rectangle(x - 30, y-30, 80, 80); Crop roicrop = new Crop(roi); Bitmap outimage = roicrop.Apply(workingImage); BlobCounter blobCounter = new BlobCounter(); blobCounter.ObjectsOrder = ObjectsOrder.Area; Blob[] blobs; // Find the blobs blobCounter.ProcessImage(outimage); blobs = blobCounter.GetObjectsInformation(); List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[0]); GrahamConvexHull grahamScan = new GrahamConvexHull(); List<IntPoint> hullPoints = grahamScan.FindHull(edgePoints); Graphics g = Graphics.FromImage(outimage); Pen redPen = new Pen(Color.Red, 2); g.DrawPolygon(redPen, ToPointsArray(hullPoints)); //g.Clear(Color.Black); //g.DrawImage(handImage, x, y); //g.DrawRectangle(redPen, roi); //g.DrawEllipse(redPen, x, y, 20, 20); ResizeNearestNeighbor resizeFilter = new ResizeNearestNeighbor(160, 160); Bitmap resizedImage = resizeFilter.Apply(outimage); return resizedImage; }
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 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); }
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; }
public BitmapSource detectSpaceBlobs(short[] depthArray, int dist, int width, int height) { BlobCounter bc = new BlobCounter(); using (Bitmap arg = RenderSpaceDetectorMap(depthArray, dist, width, height)) { BitmapData bmpd = arg.LockBits(new System.Drawing.Rectangle(0, 0, arg.Width, arg.Height), ImageLockMode.ReadWrite, arg.PixelFormat); bc.FilterBlobs = true; bc.MinHeight = 5; bc.MinWidth = 5; bc.ProcessImage(bmpd); arg.UnlockBits(bmpd); } Blob[] blobs = bc.GetObjectsInformation(); Bitmap blank = new Bitmap(width, height); Graphics g = Graphics.FromImage(blank); System.Drawing.Pen bluePen = new System.Drawing.Pen(System.Drawing.Color.Blue); foreach (Blob b in blobs) { List<IntPoint> edgepoints = bc.GetBlobsEdgePoints(b); PointF[] renderpoints = new PointF[edgepoints.Count]; // List<PointF> renderpoints = new List<PointF>(); if (b.Area > 200) { foreach (IntPoint p in edgepoints) { g.DrawEllipse(bluePen, p.X, p.Y, 1, 1); } } } bluePen.Dispose(); g.Dispose(); return this.noise_remover.BitmapSourceFromBitmap(blank); }
//returns a bitmapsource object that can be layered to display where people are public BitmapSource detectPersonBlob(short[] depthArray, int dist, int width, int height) { BlobCounter bc = new BlobCounter(); using (Bitmap arg = RenderPersonBlobMap(depthArray, dist, width, height)) { BitmapData bmpd = arg.LockBits(new System.Drawing.Rectangle(0, 0, arg.Width, arg.Height), ImageLockMode.ReadWrite, arg.PixelFormat); bc.FilterBlobs = true; bc.MinHeight = 5; bc.MinWidth = 5; bc.ProcessImage(bmpd); arg.UnlockBits(bmpd); } this.t++; Blob[] blobs = bc.GetObjectsInformation(); Frame fb = new Frame(t); foreach (Blob b in blobs) { List<IntPoint> edgepoints = bc.GetBlobsEdgePoints(b); if (b.Area > 4000) { this.positions.Enqueue(new PointF(b.CenterOfGravity.X, b.CenterOfGravity.Y)); fb.addBlob(new personBlob(b.CenterOfGravity.X, b.CenterOfGravity.Y, b.Area)); } } if (blobs.Length != 0) { using (Bitmap blobPositions = new Bitmap(640, 480)) { using (Graphics g = Graphics.FromImage(blobPositions)) { List<PointF> points = this.positions.getList(); //foreach (personBlob b in fb.blobs) foreach (PointF b in points) { g.DrawEllipse(new System.Drawing.Pen(System.Drawing.Color.Blue), b.X, b.Y, 5, 5); } } this.blobFrames.Add(fb); return this.noise_remover.BitmapSourceFromBitmap(blobPositions); } } else { using (Bitmap blank = new Bitmap(640, 480)) { return this.noise_remover.BitmapSourceFromBitmap(blank); } } }
// 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( ); }
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; }
// 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 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 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 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 }); }
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; }
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; }
/// <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; }
// ========================================================= 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); }
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 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; }
// ========================================================================================================== // 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); }
/// <summary> /// Scans dominant color on image and returns it. /// Crops rank part on image and analyzes suit part on image /// </summary> /// <param name="bmp">Bitmap to be scanned</param> /// <returns>Returns 'B' for black , 'R' for red</returns> private char ScanColor(Bitmap bmp) { char color = 'B'; //Crop rank part Crop crop = new Crop(new Rectangle(0, bmp.Height / 2, bmp.Width, bmp.Height / 2)); bmp = crop.Apply(bmp); Bitmap temp = commonSeq.Apply(bmp); //Apply filters //Find suit blob on image BlobCounter counter = new BlobCounter(); counter.ProcessImage(temp); Blob[] blobs = counter.GetObjectsInformation(); if (blobs.Length > 0) //If blobs found { Blob max = blobs[0]; //Find blob whose size is biggest foreach (Blob blob in blobs) { if (blob.Rectangle.Height > max.Rectangle.Height) max = blob; else if (blob.Rectangle.Height == max.Rectangle.Height) max = blob.Rectangle.Width > max.Rectangle.Width ? blob : max; } QuadrilateralTransformation trans = new QuadrilateralTransformation(); trans.SourceQuadrilateral = PointsCloud.FindQuadrilateralCorners(counter.GetBlobsEdgePoints(max)); bmp = trans.Apply(bmp); //Extract suit } //Lock Bits for processing BitmapData imageData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, bmp.PixelFormat); int totalRed = 0; int totalBlack = 0; unsafe { //Count red and black pixels try { UnmanagedImage img = new UnmanagedImage(imageData); int height = img.Height; int width = img.Width; int pixelSize = (img.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; byte* p = (byte*)img.ImageData.ToPointer(); // for each line for (int y = 0; y < height; y++) { // for each pixel for (int x = 0; x < width; x++, p += pixelSize) { int r = (int)p[RGB.R]; //Red pixel value int g = (int)p[RGB.G]; //Green pixel value int b = (int)p[RGB.B]; //Blue pixel value if (r > g + b) //If red component is bigger then total of green and blue component totalRed++; //then its red if (r <= g + b && r < 50 && g < 50 && b < 50) //If all components less 50 totalBlack++; //then its black } } } finally { bmp.UnlockBits(imageData); //Unlock } } if (totalRed > totalBlack) //If red is dominant color = 'R'; //Set color as Red return color; }
/// <summary> /// Detects and recognizes cards from source image /// </summary> /// <param name="source">Source image to be scanned</param> /// <returns>Recognized Cards</returns> public CardCollection Recognize(Bitmap source) { CardCollection collection = new CardCollection(); //Collection that will hold cards Bitmap temp = source.Clone() as Bitmap; //Clone image to keep original image FiltersSequence seq = new FiltersSequence(); seq.Add(Grayscale.CommonAlgorithms.BT709); //First add grayScaling filter seq.Add(new OtsuThreshold()); //Then add binarization(thresholding) filter temp = seq.Apply(source); // Apply filters on source image //Extract blobs from image whose size width and height larger than 150 BlobCounter extractor = new BlobCounter(); extractor.FilterBlobs = true; extractor.MinWidth = extractor.MinHeight = 150; extractor.MaxWidth = extractor.MaxHeight = 350; extractor.ProcessImage(temp); //Will be used transform(extract) cards on source image QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation(); //Will be used resize(scaling) cards ResizeBilinear resizer = new ResizeBilinear(CardWidth, CardHeight); foreach (Blob blob in extractor.GetObjectsInformation()) { //Get Edge points of card List<IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob); //Calculate/Find corners of card on source image from edge points List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); quadTransformer.SourceQuadrilateral = corners; //Set corners for transforming card quadTransformer.AutomaticSizeCalculaton = true; Bitmap cardImg = quadTransformer.Apply(source); //Extract(transform) card image if (cardImg.Width > cardImg.Height) //If card is positioned horizontally cardImg.RotateFlip(RotateFlipType.Rotate90FlipNone); //Rotate cardImg = resizer.Apply(cardImg); //Normalize card size Card card = new Card(cardImg, corners.ToArray()); //Create Card Object bool faceCard = IsFaceCard(cardImg); //Determine type of card(face or not) ResizeBicubic res; seq.Clear(); seq.Add(Grayscale.CommonAlgorithms.BT709); seq.Add(new OtsuThreshold()); Bitmap topLeftSuit = card.GetTopLeftSuitPart(); Bitmap bmp = seq.Apply(topLeftSuit); bmp = CutWhiteSpaces(bmp); res = new ResizeBicubic(32, 40); bmp = res.Apply(bmp); Bitmap topLeftRank = card.GetTopLeftRankPart(); Bitmap bmp2 = seq.Apply(topLeftRank); bmp2 = CutWhiteSpaces(bmp2); seq.Clear(); seq.Add(new OtsuThreshold()); bmp = seq.Apply(bmp); card.Suit = ScanSuit(bmp); if (!faceCard) { res = new ResizeBicubic(26, 40); bmp2 = res.Apply(bmp2); seq.Clear(); seq.Add(new OtsuThreshold()); bmp2 = seq.Apply(bmp2); card.Rank = ScanRank(bmp2); } else { res = new ResizeBicubic(32, 40); bmp2 = res.Apply(bmp2); seq.Clear(); seq.Add(new OtsuThreshold()); bmp2 = seq.Apply(bmp2); card.Rank = ScanFaceRank(bmp2); } collection.Add(card); //Add card to collection } return collection; }
/// <summary> /// Detects and recognizes cards from source image /// </summary> /// <param name="source">Source image to be scanned</param> /// <returns>Recognized Cards</returns> public List<Card> Recognize(Bitmap source) { List<Card> collection = new List<Card>(); Bitmap temp = source.Clone(source.PixelFormat) as Bitmap; //Clone image to keep original image FiltersSequence seq = new FiltersSequence(); seq.Add(Grayscale.CommonAlgorithms.BT709); //First add grayScaling filter seq.Add(new OtsuThreshold()); //Then add binarization(thresholding) filter temp = seq.Apply(source); // Apply filters on source image //Extract blobs from image whose size width and height larger than 150 BlobCounter extractor = new BlobCounter(); extractor.FilterBlobs = true; extractor.MinWidth = extractor.MinHeight = 150; extractor.MaxWidth = extractor.MaxHeight = 350; extractor.ProcessImage(temp); //Will be used transform(extract) cards on source image QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation(); //Will be used resize(scaling) cards ResizeBilinear resizer = new ResizeBilinear(CardWidth, CardHeight); foreach (Blob blob in extractor.GetObjectsInformation()) { //Get Edge points of card List<IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob); //Calculate/Find corners of card on source image from edge points List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); quadTransformer.SourceQuadrilateral = corners; //Set corners for transforming card quadTransformer.AutomaticSizeCalculaton = true; Bitmap cardImg = quadTransformer.Apply(source); //Extract(transform) card image if (cardImg.Width > cardImg.Height) //If card is positioned horizontally { WriteableBitmap wbmp=(WriteableBitmap)cardImg; wbmp = wbmp.Rotate(90); cardImg = (Bitmap)wbmp; //Rotate } cardImg = resizer.Apply(cardImg); //Normalize card size Card card = new Card(cardImg, corners.ToArray()); //Create Card Object char color = ScanColor(card.GetTopLeftPart()); //Scan color bool faceCard = IsFaceCard(cardImg); //Determine type of card(face or not) if (!faceCard) { card.Suit = ScanSuit(cardImg, color); //Scan Suit of non-face card card.Rank = ScanRank(cardImg); //Scan Rank of non-face card } else { Bitmap topLeft = card.GetTopLeftPart(); seq = null; seq = new FiltersSequence(); seq.Add(Grayscale.CommonAlgorithms.BT709); seq.Add(new BradleyLocalThresholding()); topLeft = seq.Apply(topLeft); BlobsFiltering bFilter = new BlobsFiltering(5, 5, 150, 150); bFilter.ApplyInPlace(topLeft); //Filter blobs that can not be a suit //topLeft.Save("topleft.bmp", ImageFormat.Bmp); card.Suit = ScanFaceSuit(topLeft, color); //Scan suit of face card card.Rank = ScanFaceRank(topLeft); //Scan rank of face card } collection.Add(card); //Add card to collection } return collection; }
/// <summary> /// Scans dominant color on image and returns it. /// Crops rank part on image and analyzes suit part on image /// </summary> /// <param name="bmp">Bitmap to be scanned</param> /// <returns>Returns 'B' for black , 'R' for red</returns> private char ScanColor(Bitmap bmp) { //System.Diagnostics.Debug.Flush(); //System.Diagnostics.Debug.Print("I'm here"); char color = 'B'; //Crop rank part Crop crop = new Crop(new Rectangle(0, bmp.Height / 2, bmp.Width, bmp.Height / 2)); bmp = crop.Apply(bmp); Bitmap temp = commonSeq.Apply(bmp); //Apply filters //Find suit blob on image BlobCounter counter = new BlobCounter(); counter.ProcessImage(temp); Blob[] blobs = counter.GetObjectsInformation(); if (blobs.Length > 0) //If blobs found { Blob max = blobs[0]; //Find blob whose size is biggest foreach (Blob blob in blobs) { if (blob.Rectangle.Height > max.Rectangle.Height) max = blob; else if (blob.Rectangle.Height == max.Rectangle.Height) max = blob.Rectangle.Width > max.Rectangle.Width ? blob : max; } QuadrilateralTransformation trans = new QuadrilateralTransformation(); trans.SourceQuadrilateral = PointsCloud.FindQuadrilateralCorners(counter.GetBlobsEdgePoints(max)); bmp = trans.Apply(bmp); //Extract suit } //Lock Bits for processing //int bitsPerPixel = ((int)bmp.PixelFormat & 0xff00) >> 8; //int bytesPerPixel = (bitsPerPixel + 7) / 8; //int stride = 4 * ((bmp.Width * bytesPerPixel + 3) / 4); // BitmapData imageData=new BitmapData(bmp.Width, bmp.Height, bmp. ) // BitmapData imageData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),ImageLockMode.ReadOnly, bmp.PixelFormat); int totalRed = 0; int totalBlack = 0; WriteableBitmap wbmp = (WriteableBitmap)bmp; wbmp.ForEach((x, y, pcolor) => { int r=Convert.ToInt32(pcolor.R); int g=Convert.ToInt32(pcolor.G); int b=Convert.ToInt32(pcolor.B); if (r > g + b) totalRed++; else if (r <= g + b && (r < 50 && g < 50)) totalBlack++; return pcolor; }); if (totalRed > totalBlack) //If red is dominant color = 'R'; //Set color as Red return color; }
/// <summary> /// Detect hand on a given frame /// </summary> /// <param name="image">Image to detect the hand palm within</param> /// <param name="cycles">Number of snapshot cycles to check against</param> /// <param name="similarityRate">The threshold percent of pixels that have to match for a positive result</param> /// <param name="trainingPic">A reference to secondary frame field. Temporary.</param> /// <returns>IntPoint point at the centre of detected hand palm</returns> public IntPoint DetectHand(Bitmap image, int cycles, int similarityRate, PictureBox trainingPic) { IntPoint dimensions = new IntPoint(image.Width, image.Height); BlobCounterBase bc = new BlobCounter(); Crop cropFilter; bc.FilterBlobs = true; bc.MinWidth = (int)(avgSize.x * 0.6); bc.MinHeight = (int)(avgSize.y * 0.6); bc.ObjectsOrder = ObjectsOrder.Size; bc.ProcessImage(image); Blob[] blobs = bc.GetObjectsInformation(); int blobWidth = 0; int blobHeight = 0; float blobAspectRatio; double angle; RotateBilinear rotate; ResizeBilinear resize = new ResizeBilinear((int)avgSize.x, (int)avgSize.y); Bitmap bmp; List<IntPoint> edges = new List<IntPoint>(); for (int b = 0; b < blobs.Length; b++) { Rectangle br = blobs[b].Rectangle; cropFilter = new Crop(br); image = cropFilter.Apply(image); bmp = AForge.Imaging.Image.Clone(image); //bc.ExtractBlobsImage(image, blobs[b], false); //bmp = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); edges = bc.GetBlobsEdgePoints(blobs[b]); IntPoint circleCenter = FindLargestCircleCenter(edges, blobs[b].Rectangle); //bmp = ImageFilters.Draw(bmp, edges); //Highlight circle center //Graphics gfx = Graphics.FromImage(bmp); //gfx.DrawRectangle(new Pen(Color.Red, 3), circleCenter.X - 10, circleCenter.Y - 10, 20, 20); blobWidth = blobs[b].Rectangle.Width; blobHeight = blobs[b].Rectangle.Height; blobAspectRatio = (float)blobWidth / blobHeight; if((blobAspectRatio) > avgAspectRatio + 0.08) { float test3 = avgSize.y / avgSize.x; if ((blobAspectRatio - avgAspectRatio) <= 1) { angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90 + (1 - (blobAspectRatio - avgAspectRatio)) * 30; } else { angle = ((blobAspectRatio - avgAspectRatio) / (test3 - avgAspectRatio)) * 90; } rotate = new RotateBilinear(angle, false); image = rotate.Apply(image); //bmp = rotate.Apply(bmp); } image = resize.Apply(image); //bmp = resize.Apply(bmp); //image = cropFilter.Apply(image); //image = maxBlobFilter.Apply(image); int scannedPixels = 0; int matches = 0; float test = 0; float threshold = (float)similarityRate / 100; int imgHeight, imgWidth; for (int i = 0; i < cycles; i++) { for (int smpl = 0; smpl < 10; smpl++) { if (image.Size.Width < samples[i, smpl].Size.Width) imgWidth = image.Size.Width; else imgWidth = samples[i, smpl].Size.Width; if (image.Size.Height < samples[i, smpl].Size.Height) imgHeight = image.Size.Height; else imgHeight = samples[i, smpl].Size.Height; for (int y = 0; y < imgHeight; y += 3) for (int x = 0; x < imgWidth; x += 3) { scannedPixels++; lock (samples[i, smpl]) { lock (image) { if (image.GetPixel(x, y).Equals(samples[i, smpl].GetPixel(x, y))) { matches++; } } } } test = (float)matches / (float)scannedPixels; if (test >= threshold) { //bc.ExtractBlobsImage(image, blobs[b], false); //bmp.Save("detect" + detectedNum + "o.bmp"); //image.Save("detect" + detectedNum + "r.bmp"); detectedNum++; return new IntPoint(dimensions.X - circleCenter.X, circleCenter.Y); //return new IntPoint(image.Width - (int)blobs[b].CenterOfGravity.X, (int)blobs[b].CenterOfGravity.Y); } matches = 0; scannedPixels = 0; } } } return new IntPoint(); }
public List<IntPoint> GetEdgePoints(Blob blob) { BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(ImageBitmap); return blobCounter.GetBlobsEdgePoints(blob); }
// 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 ); }