/// <summary> /// Applies the blob extraction feature of Aforge /// </summary> /// <param name="Mask">Mask from the flood-fill step</param> /// <param name="Source">Source image (full image)</param> /// <returns>A list of tuples(blob from mask, rectangle from source)</returns> private static List<Tuple<Bitmap, Bitmap>> ApplyBlobExtractor(Bitmap Mask, Bitmap Source) { List<Tuple<Bitmap, Bitmap>> BlobSrcblock = new List<Tuple<Bitmap, Bitmap>>(); log.Info("Using AForge Blob Counter to Process Mask"); AForge.Imaging.BlobCounter blobCounter = new AForge.Imaging.BlobCounter(); // Sort order blobCounter.ObjectsOrder = AForge.Imaging.ObjectsOrder.XY; blobCounter.ProcessImage(Mask); AForge.Imaging.Blob[] blobs = blobCounter.GetObjects(Mask, false); log.Info("Use the Blob Extraction Results to reverse extract blobs from images"); // Adding images into the image list AForge.Imaging.UnmanagedImage currentImg; foreach (AForge.Imaging.Blob blob in blobs) { Rectangle myRect = blob.Rectangle; currentImg = blob.Image; Bitmap exBlob = currentImg.ToManagedImage(); AForge.Imaging.Filters.Crop filter = new AForge.Imaging.Filters.Crop(myRect); Bitmap exSrc = filter.Apply(Source); BlobSrcblock.Add(new Tuple<Bitmap, Bitmap>(exBlob, exSrc)); } log.Info("Extraction Complete: returning List of ( blob bitmap, src bitmap)"); return BlobSrcblock; }
/// <summary> /// Applies the blob extraction feature of Aforge /// </summary> /// <param name="Mask">Mask from the flood-fill step</param> /// <param name="Source">Source image (full image)</param> /// <returns>A list of tuples(blob from mask, rectangle from source)</returns> private static List <Tuple <Bitmap, Bitmap> > ApplyBlobExtractor(Bitmap Mask, Bitmap Source) { List <Tuple <Bitmap, Bitmap> > BlobSrcblock = new List <Tuple <Bitmap, Bitmap> >(); log.Debug("Using AForge Blob Counter to Process Mask"); AForge.Imaging.BlobCounter blobCounter = new AForge.Imaging.BlobCounter(); // Sort order blobCounter.ObjectsOrder = AForge.Imaging.ObjectsOrder.XY; blobCounter.ProcessImage(Mask); AForge.Imaging.Blob[] blobs = blobCounter.GetObjects(Mask, false); log.Info("Use the Blob Extraction Results to reverse extract blobs from images"); // Adding images into the image list AForge.Imaging.UnmanagedImage currentImg; foreach (AForge.Imaging.Blob blob in blobs) { Rectangle myRect = blob.Rectangle; currentImg = blob.Image; Bitmap exBlob = currentImg.ToManagedImage(); AForge.Imaging.Filters.Crop filter = new AForge.Imaging.Filters.Crop(myRect); Bitmap exSrc = filter.Apply(Source); BlobSrcblock.Add(new Tuple <Bitmap, Bitmap>(exBlob, exSrc)); } log.Info("Extraction Complete: returning List of ( blob bitmap, src bitmap)"); return(BlobSrcblock); }
public override void Execute(Bitmap Image) { BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 75; blobCounter.MinWidth = 75; blobCounter.CoupledSizeFiltering = true; blobCounter.ProcessImage(Image); Blob[] blobs = blobCounter.GetObjects(Image); int maxSize = 0; Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0)); // find biggest blob if (blobs != null) { foreach (Blob blob in blobs) { int blobSize = blob.Rectangle.Width * blob.Rectangle.Height; if (blobSize > maxSize) { maxSize = blobSize; maxObject = blob; } } if (maxSize > 100) { if (Validity == ValidLocation.TRUE) { if (System.Math.Sqrt((CurrY - maxObject.Rectangle.Top) * (CurrY - maxObject.Rectangle.Top) + (CurrX - (maxObject.Rectangle.Left + maxObject.Rectangle.Right) / 2) * (CurrX - (maxObject.Rectangle.Left + maxObject.Rectangle.Right) / 2)) > 20) { Validity = ValidLocation.FALSE; TargetFoundCycle = 0; return; } else { TargetFoundCycle++; } } CurrX = (maxObject.Rectangle.Left + maxObject.Rectangle.Right) / 2; CurrY = maxObject.Rectangle.Top; Validity = ValidLocation.TRUE; } else { Validity = ValidLocation.FALSE; TargetFoundCycle = 0; } } else { TargetFoundCycle = 0; Validity = ValidLocation.FALSE; return; } }
public void CountBlobs(string parsFileName) { Bitmap loBitmap; prsFileName = parsFileName; // Load the binary bitmap from the file loBitmap = (Bitmap)System.Drawing.Bitmap.FromFile(parsFileName); // Format the image according to AForge.NET needs to apply the filter AForge.Imaging.Image.FormatImage(ref loBitmap); // Create an instance of the blob counter algorithm AForge.Imaging.BlobCounter loBlobCounter = new AForge.Imaging.BlobCounter(); // Process the binary image (find the blobs) loBlobCounter.ProcessImage(loBitmap); // Retrieve the array of found blobs and convert it to a List of Blob instances praoBlobs = loBlobCounter.GetObjects(loBitmap).ToList <Blob>(); // Create a new image with a 24 bpp pixel format // We use System.Drawing.Image because there is also an AForge.Imaging.Image System.Drawing.Image loNewBitmap = new Bitmap(loBitmap.Width, loBitmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); // Create the graphics from the new image Graphics g = Graphics.FromImage((System.Drawing.Image)loNewBitmap); // Draw the image g.DrawImage(loBitmap, 0, 0); // Create the a new potential nebula list praoNebulaBlobs = new List <Blob>(); using (Pen loPen = new Pen(Color.CornflowerBlue, 2)) { // Process the blobs found in the image foreach (Blob loBlob in praoBlobs) { if ((loBlob.Rectangle.Size.Width * loBlob.Rectangle.Size.Height) > 150) { // If the area is greater than 150 pixels, it is a potential nebula praoNebulaBlobs.Add(loBlob); // Draw a rectangle using the pen in the resulting image g.DrawRectangle(loPen, loBlob.Rectangle); } } } // Assign the generated bitmap to proBitmap proBitmap = (Bitmap)loNewBitmap; g.Dispose(); //proBitmap.Save(prsFileName + "_OUT"); }
public static FoundBlobs FindAny(FoundColorSpaces colorSpaces) { FoundBlobs foundBlobs = new FoundBlobs(); SobelEdgeDetector edge = new SobelEdgeDetector(); Bitmap edges = edge.Apply(colorSpaces.GrayColorSpace); Threshold threshold = new Threshold(50); threshold.ApplyInPlace(edges); BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(edges); foundBlobs.Blobs = blobCounter.GetObjects(colorSpaces.GrayColorSpace, false).ToArray(); foundBlobs.BlobCounter = blobCounter; return foundBlobs; }
// Extract separate blobs private void blobExtractorFiltersItem_Click( object sender, System.EventArgs e ) { if ( image.PixelFormat != PixelFormat.Format8bppIndexed ) { MessageBox.Show( "Blob extractor can be applied to binary images only", "Message", MessageBoxButtons.OK, MessageBoxIcon.Exclamation ); return; } BlobCounter blobCounter = new BlobCounter( image ); Blob[] blobs = blobCounter.GetObjects( image ); foreach ( Blob blob in blobs ) { host.NewDocument( blob.Image ); } }
/// <summary> /// Finds the blobs in an image. /// </summary> /// <param name="image">The image to analyze.</param> /// <returns>A list of blobs in the image.</returns> public AForge.Imaging.Blob[] FindBlobs(UnmanagedImage image) { // The BlobCounter object, which does all the heavy lifting BlobCounter bc = new BlobCounter(); // Sets up the blob counter to filter blobs if the size filters are set is set if (_minBlobWidth > 1 || _minBlobHeight > 1 || _maxBlobWidth > 1 || _maxBlobHeight > 1) { bc.FilterBlobs = true; if (_minBlobWidth > 1) { bc.MinHeight = _minBlobWidth; } if (_minBlobHeight > 1) { bc.MinHeight = _minBlobHeight; } if (_maxBlobWidth > 1) { bc.MaxHeight = _maxBlobWidth; } if (_maxBlobHeight > 1) { bc.MaxHeight = _maxBlobHeight; } } // Scans the image for blobs, prepping the BlobCounter for future operations bc.ProcessImage(image); return bc.GetObjects(image, true); }
// Extract separate blobs private void blobExtractorFiltersItem_Click( object sender, System.EventArgs e ) { if ( CheckIfBinary( "Blob extractor" ) ) { BlobCounter blobCounter = new BlobCounter( image ); Blob[] blobs = blobCounter.GetObjects( image, false ); foreach ( Blob blob in blobs ) { host.NewDocument( blob.Image ); } } }
public bool findBlobs() { 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 = 20; bCounter.MinWidth = 20; bCounter.ProcessImage(bmData); //unlock the image before doing anything with it. image.UnlockBits(bmData); Blob[] baBlobs = bCounter.GetObjects(image, true); // blobs is an array of the object gathered foreach (Blob b in baBlobs) { // some test code to shwo the new images using (Form form = new Form()) { // this line is used to convert the blob to a new bitmap img Bitmap img = b.Image.ToManagedImage(); form.StartPosition = FormStartPosition.CenterScreen; form.Size = img.Size; PictureBox pb = new PictureBox(); pb.Dock = DockStyle.Fill; pb.Image = img; form.Controls.Add(pb); form.ShowDialog(); } } return true; } catch (Exception e) { Console.WriteLine(e.StackTrace); } } // // locate objects // BlobCounter bCounter = new BlobCounter(); // bCounter.FilterBlobs = true; // bCounter.MinHeight = 30; // bCounter.MinWidth = 30; // bCounter.ProcessImage(bmData); // 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]); // 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)) // { // 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; }
// Extract separate blobs private void blobExtractorFiltersItem_Click( object sender, System.EventArgs e ) { BlobCounter blobCounter = new BlobCounter( image ); Blob[] blobs = blobCounter.GetObjects( image, false ); foreach ( Blob blob in blobs ) { host.NewDocument( blob.Image.ToManagedImage( ) ); } }
public void CountBlobs(int minWidth, int minHeight, int maxWidth, int maxHeight, bool coupled) { BlobCounter blobs = new BlobCounter(); blobs.FilterBlobs = true; blobs.MinWidth = minWidth; blobs.MinHeight = minHeight; blobs.MaxWidth = maxWidth; blobs.MaxHeight = maxHeight; blobs.ProcessImage(image.DisplayImage); Blob[] objs = blobs.GetObjects(image.DisplayImage, false); for (int i = 0; i < objs.Length; i++) { SkyObject o = new SkyObject(objs[i]); objects.Add(o); } overlay = new Overlay(objects.ToArray(), image.Width, image.Height, image.PixelFormat); AddFilter(new Add(overlay.image.display)); }
private Bitmap ExtractImage(Bitmap bitmap, Bitmap originalImg, int fillint, int contint) { int bmpWidth = bitmap.Width; int bmpHeight = bitmap.Height; // lock image, Bitmap itself takes much time to be processed BitmapData bitmapData = bitmap.LockBits( new Rectangle(0, 0, bmpWidth, bmpHeight), ImageLockMode.ReadWrite, bitmap.PixelFormat); // Store sheet corner locations (if anyone is detected) List<IntPoint> quad = new List<IntPoint>(); try { // step 2 - locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 25; // both these variables have to be given when calling the blobCounter.MinWidth = 25; // method, the can also be queried from the XML reader using OMREnums UnmanagedImage unmanagedImage = new UnmanagedImage(bitmapData); blobCounter.ProcessImage(unmanagedImage); AForge.Imaging.Blob[] blobs = blobCounter.GetObjects(unmanagedImage, false); // this helps filtering out much smaller and much larger blobs depending upon the size of image. double minbr = 0.0001; double maxbr = 0.005; // Detect left edge. foreach (AForge.Imaging.Blob blob in blobs) { // filters out very small or very larg blobs if (((double)blob.Area) / ((double)bmpWidth * bmpHeight) > minbr && ((double)blob.Area) / ((double)bmpWidth * bmpHeight) < maxbr && blob.Rectangle.X < (bmpWidth) / 4) { // filters out blobs having insanely wrong aspect ratio if ((double)blob.Rectangle.Width / blob.Rectangle.Height < 1.4 && (double)blob.Rectangle.Width / blob.Rectangle.Height > 0.6) { using (Bitmap leftBoundingResized = ResizeImage(this.leftBoundingImg, blob.Rectangle.Width, blob.Rectangle.Height)) { if (isSame(blob.Image, leftBoundingResized)) { quad.Add(new IntPoint((int)blob.CenterOfGravity.X, (int)blob.CenterOfGravity.Y)); } } } } } // Sort out the list in right sequence, UpperLeft, LowerLeft, LowerRight, UpperRight if (quad.Count >= 2) { if (quad[0].Y > quad[1].Y) { IntPoint tp = quad[0]; quad[0] = quad[1]; quad[1] = tp; } } // Detect right edge. foreach (AForge.Imaging.Blob blob in blobs) { if ( ((double)blob.Area) / ((double)bmpWidth * bmpHeight) > minbr && ((double)blob.Area) / ((double)bmpWidth * bmpHeight) < maxbr && blob.Rectangle.X > (bmpWidth * 3) / 4) { if ((double)blob.Rectangle.Width / blob.Rectangle.Height < 1.4 && (double)blob.Rectangle.Width / blob.Rectangle.Height > 0.6) { using (Bitmap rightBoundingResized = ResizeImage(this.rightBoundingImg, blob.Rectangle.Width, blob.Rectangle.Height)) { if (isSame(blob.Image, rightBoundingResized)) { quad.Add(new IntPoint((int)blob.CenterOfGravity.X, (int)blob.CenterOfGravity.Y)); } } } } } if (quad.Count >= 4) { if (quad[2].Y < quad[3].Y) { IntPoint tp = quad[2]; quad[2] = quad[3]; quad[3] = tp; } } } finally { bitmap.UnlockBits(bitmapData); } //Again, filter out if wrong blobs pretended to our blobs. if (quad.Count == 4) { // clear if, both edges have insanely wrong lengths if (((double)quad[1].Y - (double)quad[0].Y) / ((double)quad[2].Y - (double)quad[3].Y) < 0.75 || ((double)quad[1].Y - (double)quad[0].Y) / ((double)quad[2].Y - (double)quad[3].Y) > 1.25) { quad.Clear(); } // clear if, sides appear to be "wrong sided" else if (quad[0].X > bmpWidth / 2 || quad[1].X > bmpWidth / 2 || quad[2].X < bmpWidth / 2 || quad[3].X < bmpWidth / 2) { quad.Clear(); } } // sheet found if (quad.Count == 4) { IntPoint tp2 = quad[3]; quad[3] = quad[1]; quad[1] = tp2; //sort the edges for wrap operation QuadrilateralTransformation wrap = new QuadrilateralTransformation(quad); wrap.UseInterpolation = false; //perspective wrap only, no binary. wrap.AutomaticSizeCalculaton = false; wrap.NewWidth = this.ОMRConfig.ImageWidth; wrap.NewHeight = this.ОMRConfig.ImageHeight; return wrap.Apply(originalImg); } else { return null; } }
/// <summary> /// Merges blobs that are close to each other. /// </summary> /// <param name="value">The blobs found after running connected componenets algorithm.</param> /// <returns></returns> // private ArrayList<ExtendedBlob> mergeBlobs(ArrayList<ExtendedBlob> value) // { // /* // * Using a very simple methology of merging. // * Search all blobs that in close proximity of x pixels. // */ // ICollection<ExtendedBlob> intermediateValues = // new ArrayList<ExtendedBlob>(value.Count); // int x = 10; // ExtendedBlob closeToMe = value.RemoveAt(0); // while(!value.IsEmpty) // { // for (int i = 0; i < value.Count; i++) // { // Rectangle mergeRectangle = closeToMe.Rectangle; // mergeRectangle.Width += x; // mergeRectangle.Height += x; // if (mergeRectangle.IntersectsWith(value[i].Rectangle)) // { // // closeToMe // intermediateValues.Add(value[i]); // } // } // } // // } /// <summary> /// Runs the conected components algorithm. /// </summary> /// <param name="image">The image on which to run the algorithms.</param> /// <returns></returns> private List<ExtendedBlob> runConectedComponentsAlgorithm(Bitmap image) { blobCounter = new BlobCounter(image); Blob[] blobs = blobCounter.GetObjects(image); Rectangle[] rects = blobCounter.GetObjectRectangles(); List<ExtendedBlob> returnValue = new List<ExtendedBlob>(blobs.Length); for (int i = 0; i < blobs.Length; i++ ) { // Use adapter method and convert blobs to extended blobs. returnValue.Add(new ExtendedBlob(blobs[i], null, Unknown.GetInstance(), rects[i])); } return returnValue; }
public override void Execute(Bitmap Image) { BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 75; blobCounter.MinWidth = 75; blobCounter.CoupledSizeFiltering = true; blobCounter.ProcessImage(Image); Blob[] blobs = blobCounter.GetObjects(Image); int maxSize = 0; int TmpX = -100, TmpY = -100; Blob maxObject = new Blob(0, new Rectangle(0, 0, 0, 0)); // find biggest blob if (blobs != null) { foreach (Blob blob in blobs) { int blobSize = blob.Rectangle.Width * blob.Rectangle.Height; if (blobSize > maxSize) { maxSize = blobSize; maxObject = blob; } } if (maxSize > 70) { TmpX = (maxObject.Rectangle.Left + maxObject.Rectangle.Right) / 2; TmpY = maxObject.Rectangle.Top; } } AForge.Imaging.VerticalIntensityStatistics VIS = new VerticalIntensityStatistics(Image); int[] HistVer = VIS.Gray.Values; AForge.Imaging.HorizontalIntensityStatistics HIS = new HorizontalIntensityStatistics(Image); int[] HistHor = HIS.Gray.Values; bool Found = false; for (int i = System.Math.Max(CurrY - GateLengthY / 2, 0); i <= System.Math.Min(CurrY + GateLengthY / 2, HistVer.Length - 2); i++) { if (((double)HistVer[i]) / 255 > 0) { Found = true; CurrY = i; break; } } if (!Found) { Validity = ValidLocation.FALSE; return; } Found = false; for (int i = System.Math.Max(0, CurrX - GateLengthX / 2); i <= System.Math.Min(HistHor.Length - 1, CurrX + GateLengthX / 2); i++) { if (Image.GetPixel(i, CurrY).Name != "ff000000") { Found = true; CurrX = i; break; } } if (!Found) { Validity = ValidLocation.FALSE; return; } /*if (System.Math.Sqrt((CurrX - TmpX) * (CurrX - TmpX) + (CurrY - TmpY) * (CurrY - TmpY)) > 80) { Validity = ValidLocation.FALSE; return; } else Validity = ValidLocation.TRUE; CurrX = TmpX; CurrY = TmpY;*/ Validity = ValidLocation.TRUE; }