private String ContainGreen(Bitmap bitmap) { HSLFiltering filter = new HSLFiltering(); // set color ranges to keep filter.Hue = new IntRange(80, 150); filter.Saturation = new Range(0.4f, 1); filter.Luminance = new Range(0.2f, 0.7f); filter.ApplyInPlace(bitmap); AForge.Imaging.BlobCounter blobCounterGreen = new AForge.Imaging.BlobCounter(); blobCounterGreen.FilterBlobs = true; blobCounterGreen.ObjectsOrder = ObjectsOrder.Area; blobCounterGreen.MinHeight = 10; blobCounterGreen.MinWidth = 10; blobCounterGreen.ProcessImage(bitmap); //capturedPhotoGreen.Source = (WriteableBitmap)bitmap; AForge.Imaging.Blob[] blobsGreen = blobCounterGreen.GetObjectsInformation(); for (int iBlob = 0; iBlob < blobsGreen.Length; iBlob++) { for (int jBlob = iBlob + 1; jBlob < blobsGreen.Length; jBlob++) { if ((Math.Abs(blobsGreen[iBlob].CenterOfGravity.X - blobsGreen[jBlob].CenterOfGravity.X) < blobsGreen[iBlob].Rectangle.Width / 2) && (Math.Abs(blobsGreen[iBlob].CenterOfGravity.Y - blobsGreen[jBlob].CenterOfGravity.Y) < 3 * blobsGreen[iBlob].Rectangle.Height) && (Math.Abs(blobsGreen[iBlob].Area - blobsGreen[jBlob].Area) < blobsGreen[iBlob].Area / 2)) { //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsGreen[iBlob].CenterOfGravity.X - blobsGreen[jBlob].CenterOfGravity.X) + "w" + blobsGreen[iBlob].Rectangle.Width / 2; } //catch (Exception ex) { text_log.Text = ex + ""; } return("Green"); } } } //text_log.Text += "nG"; return(""); }
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(); }
public void DetectShapes() { int count = 40; int minSize = 5; int maxSize = 80; var image = (Bitmap)Image.FromFile(@"C:\Users\marco\Downloads\PanoBeam\capture_pattern0.png"); Rectangle clippingRectangle = new Rectangle(new Point(563, 360), new Size(1156, 382)); var clippingRectangleCorners = new[] { new AForge.IntPoint(clippingRectangle.X, clippingRectangle.Y), new AForge.IntPoint(clippingRectangle.X + clippingRectangle.Width, clippingRectangle.Y), new AForge.IntPoint(clippingRectangle.X + clippingRectangle.Width, clippingRectangle.Y + clippingRectangle.Height), new AForge.IntPoint(clippingRectangle.X, clippingRectangle.Y + clippingRectangle.Height) }; Helpers.FillOutsideBlack(image, clippingRectangleCorners); var blobCounter = new AForge.Imaging.BlobCounter(); AForge.Imaging.Blob[] blobs; blobCounter.FilterBlobs = true; blobCounter.MaxHeight = maxSize; blobCounter.MaxWidth = maxSize; blobCounter.MinHeight = minSize; blobCounter.MinWidth = minSize; var threshold = Recognition.GetThreshold(image); blobCounter.BackgroundThreshold = Color.FromArgb(255, threshold, threshold, threshold); blobCounter.ProcessImage(image); blobs = blobCounter.GetObjectsInformation(); }
private String ContainBlue(Bitmap bitmap) { HSLFiltering blueFilter = new HSLFiltering(); blueFilter.Hue = new IntRange(150, 210); blueFilter.Saturation = new Range(0.3f, 1); blueFilter.Luminance = new Range(0.20f, 0.8f); blueFilter.ApplyInPlace(bitmap); AForge.Imaging.BlobCounter blobCounterBlue = new AForge.Imaging.BlobCounter(); blobCounterBlue.FilterBlobs = true; blobCounterBlue.ObjectsOrder = ObjectsOrder.Area; blobCounterBlue.MinHeight = 10; blobCounterBlue.MinWidth = 10; blobCounterBlue.ProcessImage(bitmap); //capturedPhotoBlue.Source = (WriteableBitmap)bitmap; AForge.Imaging.Blob[] blobsBlue = blobCounterBlue.GetObjectsInformation(); for (int iBlob = 0; iBlob < blobsBlue.Length; iBlob++) { for (int jBlob = iBlob + 1; jBlob < blobsBlue.Length; jBlob++) { if ((Math.Abs(blobsBlue[iBlob].CenterOfGravity.X - blobsBlue[jBlob].CenterOfGravity.X) < blobsBlue[iBlob].Rectangle.Width / 2) && (Math.Abs(blobsBlue[iBlob].CenterOfGravity.Y - blobsBlue[jBlob].CenterOfGravity.Y) < 3 * blobsBlue[iBlob].Rectangle.Height) && (Math.Abs(blobsBlue[iBlob].Area - blobsBlue[jBlob].Area) < blobsBlue[iBlob].Area / 2)) { //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsBlue[iBlob].CenterOfGravity.X - blobsBlue[jBlob].CenterOfGravity.X) + "w" + blobsBlue[iBlob].Rectangle.Width / 2; } //catch (Exception ex) { text_log.Text = ex + ""; } return("Blue"); } } } return(""); }
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; }
/// <summary> /// Celem metody jest przykadrowanie otrzymanego obrazka, tak aby widok zawierał jedynie kartkę papieru, oraz zwrócenie go do metody UploadFile /// </summary> /// <param name="img"></param> /// <returns></returns> public System.Drawing.Image CropImage(System.Drawing.Image img) { //DocumentSkewChecker skewChecker = new DocumentSkewChecker(); //double angle = skewChecker.GetSkewAngle(image); //RotateBilinear rotationFilter = new RotateBilinear(-angle); //rotationFilter.FillColor = Color.White; //Bitmap rotatedImage = rotationFilter.Apply(image); Bitmap image = new Bitmap(img); UnmanagedImage grayImage = null; if (image.PixelFormat == PixelFormat.Format8bppIndexed) { grayImage = UnmanagedImage.FromManagedImage(image); } else { grayImage = UnmanagedImage.Create(image.Width, image.Height, PixelFormat.Format8bppIndexed); Grayscale.CommonAlgorithms.BT709.Apply(UnmanagedImage.FromManagedImage(image), grayImage); } CannyEdgeDetector edgeDetector = new CannyEdgeDetector(); UnmanagedImage edgesImage = edgeDetector.Apply(grayImage); OtsuThreshold thresholdFilter = new OtsuThreshold(); thresholdFilter.ApplyInPlace(edgesImage); Dilatation DilatationFilter = new Dilatation(); DilatationFilter.Apply(edgesImage); Opening OpeningFilter = new Opening(); OpeningFilter.Apply(edgesImage); BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 32; blobCounter.MinWidth = 32; blobCounter.FilterBlobs = true; blobCounter.ObjectsOrder = ObjectsOrder.Size; blobCounter.ProcessImage(edgesImage); Blob[] blobs = blobCounter.GetObjectsInformation(); ExtractBiggestBlob BiggestBlob = new ExtractBiggestBlob(); Bitmap biggestBlobsImage = BiggestBlob.Apply(edgesImage.ToManagedImage()); AForge.IntPoint BiggestBlogCorners = BiggestBlob.BlobPosition; Crop cropFilter = new Crop(new Rectangle(BiggestBlogCorners.X, BiggestBlogCorners.Y, biggestBlobsImage.Width, biggestBlobsImage.Height)); Bitmap croppedImage = cropFilter.Apply(image); return croppedImage; }
private Boolean colorOfPlayer(Bitmap bitmap) { Boolean ok = false; HSLFiltering filterRed = new HSLFiltering(); filterRed.Hue = new IntRange(301, 9); //red at night (334, 40) filterRed.Saturation = new Range(0.4f, 1); //0.55 filterRed.Luminance = new Range(0.1f, 0.68f); //75 filterRed.ApplyInPlace(bitmap); AForge.Imaging.BlobCounter blobCounterRed = new AForge.Imaging.BlobCounter(); blobCounterRed.FilterBlobs = true; blobCounterRed.ObjectsOrder = ObjectsOrder.Area; blobCounterRed.MinHeight = 10; blobCounterRed.MinWidth = 10; try { blobCounterRed.ProcessImage(bitmap); } catch (Exception es) { gameUpdate.Text = "filter"; } AForge.Imaging.Blob[] blobsRed = blobCounterRed.GetObjectsInformation(); //Mean filter = new Mean(); //// apply the filter //filter.ApplyInPlace(bitmap); bool fin = false; try { for (int iBlob = 0; iBlob < blobsRed.Length; iBlob++) { for (int jBlob = iBlob + 1; jBlob < blobsRed.Length; jBlob++) { if ((Math.Abs(blobsRed[iBlob].CenterOfGravity.X - blobsRed[jBlob].CenterOfGravity.X) < blobsRed[iBlob].Rectangle.Width / 2) && (Math.Abs(blobsRed[iBlob].CenterOfGravity.Y - blobsRed[jBlob].CenterOfGravity.Y) < 3 * blobsRed[iBlob].Rectangle.Height) && (Math.Abs(blobsRed[iBlob].Area - blobsRed[jBlob].Area) < blobsRed[iBlob].Area / 2)) { // gameUpdate.Text = "OK" + SharedInformation.myNumber + getPlayerNumberByColor("Red"); ortcExample.DoSendMessage(SharedInformation.myNumber + getPlayerNumberByColor("Red")); fin = true; return(true); } } if (fin) { break; } } } catch (Exception es) { gameUpdate.Text = "erreur"; } return(ok); }
private void colorOfPlayer2(Bitmap bitmap2) { Bitmap bit2 = null; bit2 = bitmap2; bool fin = false; HSLFiltering filter = new HSLFiltering(); // set color ranges to keep filter.Hue = new IntRange(150, 210); filter.Saturation = new Range(0.3f, 1); filter.Luminance = new Range(0.20f, 0.8f); filter.ApplyInPlace(bit2); AForge.Imaging.BlobCounter blobCounterGreen = new AForge.Imaging.BlobCounter(); blobCounterGreen.FilterBlobs = true; blobCounterGreen.ObjectsOrder = ObjectsOrder.Area; blobCounterGreen.MinHeight = 10; blobCounterGreen.MinWidth = 10; blobCounterGreen.ProcessImage(bit2); AForge.Imaging.Blob[] blobsGreen = blobCounterGreen.GetObjectsInformation(); try { for (int iBlob = 0; iBlob < blobsGreen.Length; iBlob++) { for (int jBlob = iBlob + 1; jBlob < blobsGreen.Length; jBlob++) { if ((Math.Abs(blobsGreen[iBlob].CenterOfGravity.X - blobsGreen[jBlob].CenterOfGravity.X) < blobsGreen[iBlob].Rectangle.Width / 2) && (Math.Abs(blobsGreen[iBlob].CenterOfGravity.Y - blobsGreen[jBlob].CenterOfGravity.Y) < 3 * blobsGreen[iBlob].Rectangle.Height) && (Math.Abs(blobsGreen[iBlob].Area - blobsGreen[jBlob].Area) < blobsGreen[iBlob].Area / 2)) { //gameUpdate.Text = "OK" + SharedInformation.myNumber + getPlayerNumberByColor("Blue"); ortcExample.DoSendMessage(SharedInformation.myNumber + getPlayerNumberByColor("Blue")); fin = true; break; } } if (fin) { break; } } } catch (Exception es) { gameUpdate.Text = "erreur22"; } }
// 如果活动返回值,则从 CodeActivity<TResult> // 派生并从 Execute 方法返回该值。 protected override void Execute(CodeActivityContext context) { // create an instance of blob counter algorithm BlobCounterBase bc = new BlobCounter(); // set filtering options bc.FilterBlobs = true; bc.MinWidth = context.GetValue(最小宽度); bc.MinHeight = context.GetValue(最小高度); // set ordering options bc.ObjectsOrder = ObjectsOrder.Size; // process binary image bc.ProcessImage(context.GetValue(处理目标)); var blobs = bc.GetObjectsInformation(); context.SetValue(输出目标, blobs); }
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 IEnumerable<Bitmap> Apply(Bitmap bitmap) { // assuming scanned background is white we need to invert for the algo to work var copy = new Invert().Apply(bitmap); copy = EnsureGrayscale(copy); new Threshold { ThresholdValue = 25 }.ApplyInPlace(copy); new FillHoles().ApplyInPlace(copy); var blobCounter = new BlobCounter { // set filtering options FilterBlobs = true, MinWidth = 50, MinHeight = 50, }; blobCounter.ProcessImage(copy); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { var invertedOriginal = new Invert().Apply(bitmap); foreach (var blob in blobs) { // use inverted source to ensure correct edge colors blobCounter.ExtractBlobsImage(invertedOriginal, blob, false); var blobImage = blob.Image.ToManagedImage(); // straighten var angle = new DocumentSkewChecker().GetSkewAngle(EnsureGrayscale(blobImage)); var rotationFilter = new RotateBilinear(-angle) { FillColor = Color.Black }; blobImage = rotationFilter.Apply(blobImage); // crop blobImage = new ExtractBiggestBlob().Apply(blobImage); new Invert().ApplyInPlace(blobImage); yield return blobImage; } } else { yield return bitmap; } }
private WriteableBitmap FindPlate(IEnumerable<Rect> rects, WriteableBitmap image) { WriteableBitmap bestCandidate = null; foreach (var rect in rects) { var croppedImage = image.Crop(rect); var edgeFilter = new CannyEdgeDetector(); var smoothFilter = new Median(); var grayFilter = new Grayscale(0.2125, 0.7154, 0.0721); var blobCounter = new BlobCounter(); var cutTop = croppedImage.PixelHeight * 0.3; croppedImage = croppedImage.Crop(new Rect(0, cutTop, croppedImage.PixelWidth, croppedImage.PixelHeight)); var bitmap = (Bitmap)croppedImage; var grayImage = grayFilter.Apply(bitmap); bitmap = smoothFilter.Apply(grayImage); edgeFilter.ApplyInPlace(bitmap); blobCounter.ProcessImage(bitmap); var blobs = blobCounter.GetObjectsInformation(); var possibleChars = new List<Rectangle>(); foreach (var blob in blobs) { var objRectangle = blob.Rectangle; var ratio = (double)objRectangle.Height / (double)objRectangle.Width; if (ratio >= 1.16d && ratio <= 6.3d) { possibleChars.Add(objRectangle); } } if (possibleChars.Count == 0) { continue; } bestCandidate = croppedImage; } return bestCandidate; }
private static Blob[] blobRecognition(Bitmap thresholdedInverted) { //Use the AForge.NET BlobCounter to perform Blob Recognition / Connected Region Analysis BlobCounter blobRecognition = new BlobCounter(); //Filter out blobs that are abviously the wrong size to be characters blobRecognition.MinWidth = (int)(thresholdedInverted.Width * (BLOB_FILTER_MIN_DIMENSION_IMAGE_PERCENTAGE / 100)); blobRecognition.MinHeight = (int)(thresholdedInverted.Height * (BLOB_FILTER_MIN_DIMENSION_IMAGE_PERCENTAGE / 100)); blobRecognition.MaxWidth = (int)(thresholdedInverted.Width * (BLOB_FILTER_MAX_DIMENSION_IMAGE_PERCENTAGE / 100)); blobRecognition.MaxHeight = (int)(thresholdedInverted.Height * (BLOB_FILTER_MAX_DIMENSION_IMAGE_PERCENTAGE / 100)); blobRecognition.FilterBlobs = true; blobRecognition.ProcessImage(thresholdedInverted); Blob[] blobs = blobRecognition.GetObjectsInformation(); return blobs; }
public List<Blob> ExtractBlob() { // create instance of blob counter BlobCounter blobCounter = new BlobCounter(); // process input image blobCounter.ProcessImage(ImageBitmap); // get information about detected objects Blob[] blobArray = blobCounter.GetObjectsInformation(); foreach(Blob blobdata in blobArray) { blobCounter.ExtractBlobsImage(ImageBitmap, blobdata, true); } return blobArray.ToList(); }
Blob[] DetectBlobs(Bitmap bmp) { Invert filter = new Invert(); filter.ApplyInPlace(bmp); BlobCounter bc = new BlobCounter(); bc.BackgroundThreshold = Color.FromArgb(8, 8, 8); bc.BlobsFilter = new BlobsFilter(bmp.Size); bc.FilterBlobs = true; bc.ProcessImage(bmp); // Revert back filter.ApplyInPlace(bmp); return bc.GetObjectsInformation(); }
// 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); //get image byte[] textData = GetImageData(); UnmanagedImage img = CreateImage(textData); log.AddImage("Raw Image", img.ToManagedImage()); //resize Image AForge.Imaging.Filters.ResizeNearestNeighbor resizeFilter = new AForge.Imaging.Filters.ResizeNearestNeighbor(500, (int)(500 / res)); UnmanagedImage resizedImage = resizeFilter.Apply(img); log.AddImage("Resized Image", resizedImage.ToManagedImage()); //filter floor UnmanagedImage floorFilteredImage = FilterFloor(resizedImage, textData); log.AddImage("Floor filtered", floorFilteredImage.ToManagedImage()); // 1- grayscale image Bitmap grayImage = Grayscale.CommonAlgorithms.BT709.Apply(resizedImage.ToManagedImage()); log.AddImage("Grayscale", resizedImage.ToManagedImage()); // 2 - Otsu thresholding OtsuThreshold threshold = new OtsuThreshold(); Bitmap binaryImage = threshold.Apply(grayImage); log.AddImage("Binary", binaryImage); log.AddMessage("Otsu threshold: " + threshold.ThresholdValue); //resive image // 3 - Blob counting BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinWidth = 1; blobCounter.MinWidth = 1; blobCounter.ProcessImage(binaryImage); Blob[] blobs = blobCounter.GetObjectsInformation(); log.AddMessage("Found blobs (min width/height = 24): " + blobs.Length); }
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 List<Blob> ExtractBlob(int maxWidth, int maxHeight, int minWidth, int minHeight) { BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = minHeight; blobCounter.MinWidth = minWidth; blobCounter.MaxWidth = maxWidth; blobCounter.MaxHeight = maxHeight; blobCounter.FilterBlobs = true; // process input image blobCounter.ProcessImage(ImageBitmap); // get information about detected objects Blob[] blobArray = blobCounter.GetObjectsInformation(); foreach (Blob blobdata in blobArray) { blobCounter.ExtractBlobsImage(ImageBitmap, blobdata, true); } return blobArray.ToList(); }
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; }
public static AForge.Point GetRedBlobCenter(Bitmap image) { BlobCounter bCounter = new BlobCounter(); bCounter.ProcessImage(image); Blob[] blobs = bCounter.GetObjectsInformation(); Rectangle[] rects = bCounter.GetObjectsRectangles(); Pen pen = new Pen(Color.Red, 2); Brush brush = new SolidBrush(Color.Red); Graphics g = Graphics.FromImage(image); if (rects.Length > 0) { g.FillRectangle(brush, rects[0]); } if (blobs.Length > 0) { detected = true; lastPos = blobs[0].CenterOfGravity; AForge.Point rPos = new AForge.Point(); rPos.Y = ((lastPos.Y / 5) / 100) * 768; rPos.X = ((lastPos.X / 5) / 100) * 1366; return rPos; } else { detected = false; if (lastPos != null) { return lastPos; } else { return new AForge.Point(50.0f, 50.0f); } } }
public Boolean ContainOrange(Bitmap bitmap) { ColorFiltering RedFilter = new ColorFiltering(); RedFilter.Red = new IntRange(100, 255); RedFilter.Green = new IntRange(0, 100); RedFilter.Blue = new IntRange(0, 100); RedFilter.ApplyInPlace(bitmap); AForge.Imaging.BlobCounter blobCounterGreen = new AForge.Imaging.BlobCounter(); blobCounterGreen.FilterBlobs = true; blobCounterGreen.MinHeight = 5; blobCounterGreen.MinWidth = 5; blobCounterGreen.ProcessImage(bitmap); AForge.Imaging.Blob[] blobsGreen = blobCounterGreen.GetObjectsInformation(); SimpleShapeChecker shapeCheckerGreen = new SimpleShapeChecker(); if (blobsGreen.Length > 0) { return(true); } return(false); }
public String ContainRed(Bitmap bitmap) { HSLFiltering filterRed = new HSLFiltering(); filterRed.Hue = new IntRange(301, 9); //red at night (334, 40) filterRed.Saturation = new Range(0.4f, 1); //0.55 filterRed.Luminance = new Range(0.1f, 0.68f); //75 filterRed.ApplyInPlace(bitmap); AForge.Imaging.BlobCounter blobCounterRed = new AForge.Imaging.BlobCounter(); blobCounterRed.FilterBlobs = true; blobCounterRed.ObjectsOrder = ObjectsOrder.Area; blobCounterRed.MinHeight = 10; blobCounterRed.MinWidth = 10; blobCounterRed.ProcessImage(bitmap); AForge.Imaging.Blob[] blobsRed = blobCounterRed.GetObjectsInformation(); //capturedPhotoRed.Source = (WriteableBitmap)bitmap; //Mean filter = new Mean(); //// apply the filter //filter.ApplyInPlace(bitmap); for (int iBlob = 0; iBlob < blobsRed.Length; iBlob++) { for (int jBlob = iBlob + 1; jBlob < blobsRed.Length; jBlob++) { if ((Math.Abs(blobsRed[iBlob].CenterOfGravity.X - blobsRed[jBlob].CenterOfGravity.X) < blobsRed[iBlob].Rectangle.Width / 2) && (Math.Abs(blobsRed[iBlob].CenterOfGravity.Y - blobsRed[jBlob].CenterOfGravity.Y) < 3 * blobsRed[iBlob].Rectangle.Height) && (Math.Abs(blobsRed[iBlob].Area - blobsRed[jBlob].Area) < blobsRed[iBlob].Area / 2)) { //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsRed[iBlob].CenterOfGravity.X - blobsRed[jBlob].CenterOfGravity.X) + "w" + blobsRed[iBlob].Rectangle.Width / 2; } //catch (Exception ex) { text_log.Text = ex + ""; } return("red"); } } } return(""); }
public String ContainPurple(Bitmap bitmap) { HSLFiltering filter = new HSLFiltering(); // set color ranges to keep filter.Hue = new IntRange(220, 290); filter.Saturation = new Range(0.4f, 0.8f); filter.Luminance = new Range(0.35f, 0.78f); filter.ApplyInPlace(bitmap); AForge.Imaging.BlobCounter blobCounterPutple = new AForge.Imaging.BlobCounter(); blobCounterPutple.FilterBlobs = true; blobCounterPutple.ObjectsOrder = ObjectsOrder.Area; blobCounterPutple.MinHeight = 10; blobCounterPutple.MinWidth = 10; blobCounterPutple.ProcessImage(bitmap); AForge.Imaging.Blob[] blobsPurple = blobCounterPutple.GetObjectsInformation(); SimpleShapeChecker shapeCheckerPurple = new SimpleShapeChecker(); //capturedPhotoBlue.Source = (WriteableBitmap)bitmap; for (int iBlob = 0; iBlob < blobsPurple.Length; iBlob++) { for (int jBlob = iBlob + 1; jBlob < blobsPurple.Length; jBlob++) { if ((Math.Abs(blobsPurple[iBlob].CenterOfGravity.X - blobsPurple[jBlob].CenterOfGravity.X) < blobsPurple[iBlob].Rectangle.Width / 2) && (Math.Abs(blobsPurple[iBlob].CenterOfGravity.Y - blobsPurple[jBlob].CenterOfGravity.Y) < 3 * blobsPurple[iBlob].Rectangle.Height) && (Math.Abs(blobsPurple[iBlob].Area - blobsPurple[jBlob].Area) < blobsPurple[iBlob].Area / 2)) { //try { text_log.Text += "i" + iBlob + "j" + jBlob + "diff" + Math.Abs(blobsPurple[iBlob].CenterOfGravity.X - blobsPurple[jBlob].CenterOfGravity.X) + "w" + blobsPurple[iBlob].Rectangle.Width / 2; } //catch (Exception ex) { text_log.Text = ex + ""; } return("Purple"); } } } return(""); }
// ========================================================= 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); }
// ========================================================================================================== // Components: // ========================================================================================================== private List<Shapes.Component> FindComponentsFunct(Bitmap bitmap) { // Locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 8; blobCounter.MinWidth = 8; blobCounter.ProcessImage(bitmap); Blob[] blobs = blobCounter.GetObjectsInformation(); // create convex hull searching algorithm GrahamConvexHull hullFinder = new GrahamConvexHull(); ClosePointsMergingOptimizer optimizer1 = new ClosePointsMergingOptimizer(); FlatAnglesOptimizer optimizer2 = new FlatAnglesOptimizer(); List<Shapes.Component> Components = new List<Shapes.Component>(); // process each blob foreach (Blob blob in blobs) { List<IntPoint> leftPoints, rightPoints, edgePoints = new List<IntPoint>(); if ((blob.Rectangle.Height > 400) && (blob.Rectangle.Width > 600)) { break; // The whole image could be a blob, discard that } // get blob's edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftPoints, out rightPoints); edgePoints.AddRange(leftPoints); edgePoints.AddRange(rightPoints); // blob's convex hull List<IntPoint> Outline = hullFinder.FindHull(edgePoints); optimizer1.MaxDistanceToMerge = 4; optimizer2.MaxAngleToKeep = 170F; Outline = optimizer2.OptimizeShape(Outline); Outline = optimizer1.OptimizeShape(Outline); // find Longest line segment float dist = 0; LineSegment Longest = new LineSegment(Outline[0], Outline[1]); LineSegment line; dist = Longest.Length; int LongestInd = 0; for (int i = 1; i < Outline.Count; i++) { if (i != Outline.Count - 1) { line = new LineSegment(Outline[i], Outline[i + 1]); } else { // last iteration if (Outline[i] == Outline[0]) { break; } line = new LineSegment(Outline[i], Outline[0]); } if (line.Length > dist) { Longest = line; dist = line.Length; LongestInd = i; } } // Get the center point of it AForge.Point LongestCenter = new AForge.Point(); LongestCenter.X = (float)Math.Round((Longest.End.X - Longest.Start.X) / 2.0 + Longest.Start.X); LongestCenter.Y = (float)Math.Round((Longest.End.Y - Longest.Start.Y) / 2.0 + Longest.Start.Y); AForge.Point NormalStart = new AForge.Point(); AForge.Point NormalEnd = new AForge.Point(); // Find normal: // start= longest.start rotated +90deg relative to center // end= longest.end rotated -90deg and relative to center // If you rotate point (px, py) around point (ox, oy) by angle theta you'll get: // p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox // p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy // cos90 = 0, sin90= 1 => // p'x= -(py-oy) + ox= oy-py+ox, p'y= (px-ox)+ oy NormalStart.X = LongestCenter.Y - Longest.Start.Y + LongestCenter.X; NormalStart.Y = (Longest.Start.X - LongestCenter.X) + LongestCenter.Y; // cos-90=0, sin-90= -1 => // p'x= (py-oy) + ox // p'y= -(px-ox)+oy= ox-px+oy NormalEnd.X = (Longest.Start.Y - LongestCenter.Y) + LongestCenter.X; NormalEnd.Y = LongestCenter.X - Longest.Start.X + LongestCenter.Y; // Make line out of the points Line Normal = Line.FromPoints(NormalStart, NormalEnd); // Find the furthest intersection to the normal (skip the Longest) AForge.Point InterSection = new AForge.Point(); AForge.Point Furthest = new AForge.Point(); bool FurhtestAssinged = false; LineSegment seg; dist = 0; for (int i = 0; i < Outline.Count; i++) { if (i == LongestInd) { continue; } if (i != Outline.Count - 1) { seg = new LineSegment(Outline[i], Outline[i + 1]); } else { // last iteration if (Outline[i] == Outline[0]) { break; } seg = new LineSegment(Outline[i], Outline[0]); } if (seg.GetIntersectionWith(Normal) == null) { continue; } InterSection = (AForge.Point)seg.GetIntersectionWith(Normal); if (InterSection.DistanceTo(LongestCenter) > dist) { Furthest = InterSection; FurhtestAssinged = true; dist = InterSection.DistanceTo(LongestCenter); } } // Check, if there is a edge point that is close to the normal even further AForge.Point fPoint = new AForge.Point(); for (int i = 0; i < Outline.Count; i++) { fPoint.X = Outline[i].X; fPoint.Y = Outline[i].Y; if (Normal.DistanceToPoint(fPoint) < 1.5) { if (fPoint.DistanceTo(LongestCenter) > dist) { Furthest = fPoint; FurhtestAssinged = true; dist = fPoint.DistanceTo(LongestCenter); } } } AForge.Point ComponentCenter = new AForge.Point(); if (FurhtestAssinged) { // Find the midpoint of LongestCenter and Furthest: This is the centerpoint of component ComponentCenter.X = (float)Math.Round((LongestCenter.X - Furthest.X) / 2.0 + Furthest.X); ComponentCenter.Y = (float)Math.Round((LongestCenter.Y - Furthest.Y) / 2.0 + Furthest.Y); // Alignment is the angle of longest double Alignment; if (Math.Abs(Longest.End.X - Longest.Start.X) < 0.001) { Alignment = 0; } else { Alignment = Math.Atan((Longest.End.Y - Longest.Start.Y) / (Longest.End.X - Longest.Start.X)); Alignment = Alignment * 180.0 / Math.PI; // in deg. } Components.Add(new Shapes.Component(ComponentCenter, Alignment, Outline, Longest, NormalStart, NormalEnd)); } } return Components; }
// ========================================================================================================== // 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 void FindCenterMarker() { List<Marker> _blobs = new List<Marker>(); //блокируем изображение в памяти BitmapData bitmapData = _markersimg.LockBits( new Rectangle(0, 0, _markersimg.Width, _markersimg.Height), ImageLockMode.ReadWrite, _markersimg.PixelFormat); BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; //устанавливаем фильтр и максимальные и минимальные размеры маркера blobCounter.MinHeight = blobCounter.MinWidth = Geometry.MMtoPX(_makerdiameter - 2.0d, _image.VerticalResolution); blobCounter.MaxHeight = blobCounter.MaxWidth = Geometry.MMtoPX(_makerdiameter + 3.0d, _image.VerticalResolution); //собственно поиск blobCounter.ProcessImage(bitmapData); Blob[] blobs = blobCounter.GetObjectsInformation(); _markersimg.UnlockBits(bitmapData); for (int i = 0, n = blobs.Length; i < n; i++) { if (blobs[i].Fullness > 0.3) { Marker tempmark = new Marker(blobs[i]); _blobs.Add(tempmark); } } this.RecognizeMarkers(_blobs); }
/// <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> /// 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> /// Добавляет несколько несколько ячеек в ответ начиная с первой /// </summary> /// <param name="image">Ссылка ни изображение</param> /// <param name="CellsCount">Количество ячеек для добавления в ответ</param> /// <param name="FirstCellDistanses">Коллекция дистанций между первой ячейкой и маркерами</param> /// <param name="intercentresdistX">Расстояние между центрами ячеек</param> /// <param name="Width">Длина ячеек</param> /// <param name="Height">Высота ячеек</param> public void IntelligentAdd(Bitmap image, int CellsCount, Distances FirstCellDistanses, int intercentresdistX, int Width, int Height) { int maxslice = intercentresdistX/2; //находим первую доступную дистанцию Distance d = FirstCellDistanses.FindOneGood(); int maxWidth = Width + Convert.ToInt16(Width/2); int maxHeigth = Height + Convert.ToInt16(Height/2); //увеличиваем ячейки this.Add(image,CellsCount,FirstCellDistanses,intercentresdistX,maxWidth,maxHeigth); BitmapData data = image.LockBits(_cells[0].Rect, ImageLockMode.ReadWrite, image.PixelFormat); BlobCounter blobCounter = new BlobCounter(); Invert invertfilter = new Invert(); invertfilter.ApplyInPlace(data); blobCounter.ProcessImage(data); Blob[] blobs = blobCounter.GetObjectsInformation(); if (blobs.Length != 0) { int maxar = 0; int b = 0; for (int i = 0; i < blobs.Count(); i++) { if (blobs[i].Area > maxar) { maxar = blobs[i].Area; b = i; } } invertfilter.ApplyInPlace(data); System.Drawing.Point p = new System.Drawing.Point(_cells[0].CenterOfGravity.X - ((maxWidth / 2) - Convert.ToInt16(blobs[b].CenterOfGravity.X)), _cells[0].CenterOfGravity.Y - ((maxHeigth / 2) - Convert.ToInt16(blobs[b].CenterOfGravity.Y))); if (Math.Abs(_cells[0].CenterOfGravity.Y - p.Y) <= maxslice) { this.ReMeasure(p, intercentresdistX, Width, Height); } else { this.ReMeasure(_cells[0].CenterOfGravity, intercentresdistX, Width, Height); } } image.UnlockBits(data); }
/// <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> /// Scans rank of card and returns result. /// For recognizing rank, counts suits on image /// </summary> /// <param name="cardImage">Card image to be scanned</param> /// <returns>Rank of card</returns> private Rank ScanRank(Bitmap cardImage) { Rank rank = Rank.NOT_RECOGNIZED; int total = 0; Bitmap temp = commonSeq.Apply(cardImage); //Apply filters on image BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; //Filter blobs whose width or height less than 30 pixels blobCounter.MinHeight = blobCounter.MinWidth = 30; blobCounter.ProcessImage(temp); total = blobCounter.GetObjectsInformation().Length; //Get total number of objects rank = (Rank)total; //Convert it to Rank return rank; }
/// <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> /// Display little noise object on image /// </summary> /// <param name="fillColor">Color to fill noise bject</param> /// <param name="threshold">Threshold for noise oblect area</param> public Image DisplayNoise(Color fillColor, int threshold = 100) { Bitmap bitmapImage = new Bitmap(_digit); BlobCounter bc = new BlobCounter(bitmapImage); // specify sort order bc.ObjectsOrder = ObjectsOrder.Size; Blob[] blobs = bc.GetObjectsInformation(); SolidBrush redBrush = new SolidBrush(fillColor); using (Graphics digit1Graph = Graphics.FromImage(bitmapImage)) { foreach (Blob blob in blobs) { if (blob.Area < threshold) digit1Graph.FillRectangle(redBrush, blob.Rectangle); } } return bitmapImage; }
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; }
/// <summary> /// Remove little noise object on binary image /// </summary> /// <param name="threshold">Threshold for noise oblect area</param> public void RemoveNoise(int threshold = 100) { BlobCounter bc = new BlobCounter(new Bitmap(_digit)); // specify sort order bc.ObjectsOrder = ObjectsOrder.Size; Blob[] blobs = bc.GetObjectsInformation(); SolidBrush redBrush = new SolidBrush(Color.Black); Bitmap tempBitmap = new Bitmap(_digit); using (Graphics digitGraph = Graphics.FromImage(tempBitmap)) { foreach (Blob blob in blobs) { if (blob.Area < threshold) digitGraph.FillRectangle(redBrush, blob.Rectangle); } } _digit = tempBitmap; }
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; }
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> /// 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(); }