private Bitmap processImage(Bitmap img) { //Generate closing structural element short[,] structEl = new short[13, 13]; for (int i = 0; i < 13; i++) for (int j = 0; j < 13; j++) if ((i - 6) * (i - 6) + (j - 6) * (j - 6) < 64) structEl[i, j] = 1; else structEl[i, j] = -1; //Initialize filters HSLFiltering borderFind = new HSLFiltering(); Closing borderClose = new Closing(structEl); Invert invert = new Invert(); Grayscale grayFilter = new Grayscale(0, 0, 1.0); Threshold bwFilter = new Threshold(1); PointedColorFloodFill blackout = new PointedColorFloodFill(); blackout.Tolerance = Color.FromArgb(0, 0, 0); blackout.FillColor = Color.FromArgb(0, 0, 0); ExtractBiggestBlob getgame = new ExtractBiggestBlob(); getgame.OriginalImage = new Bitmap(img); GrayscaleToRGB colorFilter = new GrayscaleToRGB(); //Color determined with ColorProbe. borderFind.Hue = new IntRange(190, 200); borderFind.Saturation = new Range(0.6f, 0.8f); borderFind.Luminance = new Range(0.6f, 1.0f); borderFind.ApplyInPlace(img); borderClose.ApplyInPlace(img); img = grayFilter.Apply(img); bwFilter.ApplyInPlace(img); invert.ApplyInPlace(img); img = colorFilter.Apply(img); blackout.StartingPoint = new AForge.IntPoint(0, 0); blackout.ApplyInPlace(img); img = getgame.Apply(img); int tilesx = img.Width / 56; int tilesy = img.Height / 56; int offsetx = 56 * (int)(tilesx - img.Width / 56.0); int offsety = 56 * (int)(tilesy - img.Height / 56.0); if ((Math.Abs(offsetx) > 11) || (Math.Abs(offsety) > 11)) throw new GameNotFoundException(); List<IntPoint> corners = new List<IntPoint>(); Dictionary<IntPoint, Bitmap> tiles = new Dictionary<IntPoint, Bitmap>(); SimpleQuadrilateralTransformation tileXtract = new SimpleQuadrilateralTransformation(); for (int j = 0; j < tilesy; j++) for (int i = 0; i < tilesx; i++) { corners.Add(new IntPoint(offsetx + i * 56, offsety + j * 56 )); corners.Add(new IntPoint(offsetx + i * 56, offsety + (j + 1) * 56 - 1)); corners.Add(new IntPoint(offsetx + (i + 1) * 56 - 1, offsety + (j + 1) * 56 - 1)); corners.Add(new IntPoint(offsetx + (i + 1) * 56 - 1, offsety + j * 56 )); tileXtract.SourceQuadrilateral = corners; tiles.Add(new IntPoint(i, j), tileXtract.Apply(img)); corners.Clear(); } img = (Bitmap)Properties.Resources.ResourceManager.GetObject("cb"); /*Graphics g = Graphics.FromImage(img); Pen bluePen = new Pen(Color.Blue, 2); for (int i = 0, n = blobs.Length; i < n; i++) { List<IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { List<IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); g.DrawPolygon(bluePen, ToPointsArray(corners)); } } bluePen.Dispose(); g.Dispose(); */ return img; }
/// <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; }
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; } }
/// <summary> /// Determines whether card is a face card(Jack,Queen,King) or not. /// If card is a face card , then it will have a big blob whose width will be /// larger than half width of card /// If card isn't a face card, then width of all blobs will be less than half width of card /// </summary> /// <param name="bmp">Card of image to be analyzed</param> /// <returns>True if its a face card, false if not</returns> private bool IsFaceCard(Bitmap bmp) { Bitmap temp = this.commonSeq.Apply(bmp); ExtractBiggestBlob extractor = new ExtractBiggestBlob(); temp = extractor.Apply(temp); //Extract biggest blob if (temp.Height > bmp.Height / 5) //If width is larger than half width of card return true; //Its a face card return false; //It is not a face card }
/// <summary> /// Scans and returns suit of card. NOTE : Scans suit of cards that are not face cards /// For recognizing suit, analyzes color and size of suit blob /// </summary> /// <param name="suitBmp">Suit image to be scanned</param> /// <param name="color">Color of card. 'R' means Red, 'B' means black</param> /// <returns>Scanned Suit</returns> private Suit ScanSuit(Bitmap suitBmp, char color) { Bitmap temp = commonSeq.Apply(suitBmp); ExtractBiggestBlob extractor = new ExtractBiggestBlob(); //Extract biggest blob on card temp = extractor.Apply(temp); //Biggest blob is suit blob so extract it Suit suit = Suit.NOT_RECOGNIZED; //Determine type of suit according to its color and width if (color == 'R') suit = temp.Width >= 55 ? Suit.Diamonds : Suit.Hearts; if (color == 'B') suit = temp.Width <= 48 ? Suit.Spades : Suit.Clubs; return suit; }
private void InitFilters() { L_brownFilter = new ColorFiltering(); D_brownFilter = new ColorFiltering(); L_brownFilter.Red = new IntRange(125, 140); L_brownFilter.Green = new IntRange(95, 110); L_brownFilter.Blue = new IntRange(110, 130); D_brownFilter.Red = new IntRange(55, 85); D_brownFilter.Green = new IntRange(45, 75); D_brownFilter.Blue = new IntRange(45, 75); blobFilter = new BlobsFiltering(); blobFilter.CoupledSizeFiltering = true; blobFilter.MinWidth = 70; blobFilter.MinHeight = 70; diffFilter = new Difference(); diffFilter.OverlayImage = back; thresholdFilter = new Threshold(40); erosionFilter = new Erosion(); edgeFilter = new Edges(); openFilter = new Opening(); pixelFilter = new Pixellate(); morphFilter = new Morph(); morphFilter.SourcePercent = 0.9; towardsFilter = new MoveTowards(); towardsFilter.StepSize = 10; blobCounter = new BlobCounter(); blobGrabber = new ExtractBiggestBlob(); }
void sensor_AllFramesReady(object sender, Microsoft.Kinect.AllFramesReadyEventArgs e) { if(this.command == "Stop") { Bot.stop(); } if(this.command == "Forward") { Bot.traverse(); } if (this.command == "Right") { Bot.turnRight(); } if (this.command == "Left") { Bot.turnRight(); } xf++; if (xf % 5 == 0) { xf = 0; if (this.command != null) { using (ColorImageFrame colorFrame = e.OpenColorImageFrame()) { using (DepthImageFrame depthFrame = e.OpenDepthImageFrame()) { using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame()) { humanPosition = frameToHuman(skeletonFrame); if (colorFrame != null) { // Copy the pixel data from the image to a temporary array colorFrame.CopyPixelDataTo(this.colorPixels); // Write the pixel data into our bitmap this.colorBitmap.WritePixels( new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight), this.colorPixels, this.colorBitmap.PixelWidth * sizeof(int), 0); // Error here due to OpenCV_core290.dll //int[] objPos = new int[2]; //objPos = tmp.matchColor(ImageProc.colorFrameToImage(colorFrame)); //if (objPos != null) //{ // short blobDepth = getDepthAtPoint(objPos, depthFrame); // this.lblObject.Content = objPos[0] + ", " + objPos[1] + ", " + blobDepth; //} //else //{ // this.lblObject.Content = "Null"; //} System.Drawing.Bitmap bmp = ImageProc.colorFrameToAforge(colorFrame); HSLFiltering filter = new HSLFiltering(); // set color ranges to keep if (objec[0] == -1) { if (command == "Fetching Bottle") { filter.Hue = bottleH; filter.Saturation = bottleS; filter.Luminance = bottleL; } else if (command == "Fetching Box") { filter.Hue = boxH; filter.Saturation = boxS; filter.Luminance = boxL; } //// apply the filter filter.ApplyInPlace(bmp); BlobCounter blobCounter = new BlobCounter(bmp); int i = blobCounter.ObjectsCount; ExtractBiggestBlob fil = new ExtractBiggestBlob(); int[] pp = new int[2]; pp[0] = 0; pp[1] = 0; int h = 0; if (i > 0) { fil.Apply(bmp); pp[0] = fil.BlobPosition.X; pp[1] = fil.BlobPosition.Y; h = fil.Apply(bmp).Height; } short blobDepth = getDepthAtPoint(pp, depthFrame); this.lblObject.Content = pp[0] + ", " + pp[1] + ", " + blobDepth; this.objec[0] = pp[0]; this.objec[1] = pp[1]; this.objec[2] = blobDepth; } else { filter.Hue = botH; filter.Saturation = botS; filter.Luminance = botL; filter.ApplyInPlace(bmp); BlobCounter blobCounter = new BlobCounter(bmp); int i = blobCounter.ObjectsCount; ExtractBiggestBlob fil = new ExtractBiggestBlob(); int[] pp = new int[2]; pp[0] = 0; pp[1] = 0; int h = 0; if (i > 0) { fil.Apply(bmp); pp[0] = fil.BlobPosition.X; pp[1] = fil.BlobPosition.Y; h = fil.Apply(bmp).Height; } short blobDepth = getDepthAtPoint(pp, depthFrame); this.lblBot.Content = pp[0] + ", " + pp[1] + ", " + blobDepth; this.bot[0] = pp[0]; this.bot[1] = pp[1]; this.bot[2] = blobDepth; } //Assign Manual Position to bot and object } if (humanPosition != null) { this.lblHuman.Content = humanPosition[0] + ", " + humanPosition[1] + ", " + humanPosition[2]; } else { this.lblHuman.Content = "No Human detected"; } if (this.path == 0) { if (humanPosition != null) { if (Bot.moveDoraemon(this.bot[0], this.humanPosition[0], this.bot[2], this.humanPosition[2]) == 0) { this.path = 1; } } } else { if (Bot.moveDoraemon(this.bot[0], this.objec[0], this.bot[2], this.objec[2]) == 0) { Bot.stop(); } } } } } this.lbl.Content = command; } } }