static void Main(string[] args) { try { string path = "D:\\HACK2015\\PICS"; Bitmap sourceImage = AForge.Imaging.Image.FromFile(Path.Combine(path, "CAM1s.jpg")); Difference differenceFilter = new Difference(); //AForge.Imaging.Filters.Difference differenceFilter.OverlayImage = sourceImage; Bitmap sourceImg = AForge.Imaging.Image.FromFile(Path.Combine(path, "CAM1.jpg")); Bitmap tempImg = sourceImg.Clone() as Bitmap; tempImg = differenceFilter.Apply(tempImg); FiltersSequence seq = new FiltersSequence(); seq.Add(Grayscale.CommonAlgorithms.BT709); seq.Add(new OtsuThreshold()); tempImg = seq.Apply(tempImg); tempImg.Save(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CAM1.jpg")); int objectCount = 0; BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 60; blobCounter.MinWidth = 40; blobCounter.ProcessImage(tempImg); Blob[] blobs = blobCounter.GetObjectsInformation(); for (int i = 0; i < blobs.Length; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List <IntPoint> corners = null; SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { ++objectCount; } } Console.WriteLine("No. of BLOBS: " + blobCounter.GetObjectsInformation().Length); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read(); }
public Bitmap DetectCircle(Bitmap image) { SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); // locate objects using blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.ProcessImage(image); Blob[] blobs = blobCounter.GetObjectsInformation(); // create Graphics object to draw on the image and a pen Graphics g = Graphics.FromImage(image); Pen redPen = new Pen(Color.Red, 2); // 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]); try { shapeChecker.CheckShapeType(edgePoints); } catch (Exception) { continue; } List <IntPoint> corners; AForge.Point center; float radius; if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { g.DrawEllipse(redPen, (int)(center.X - radius), (int)(center.Y - radius), (int)(radius * 2), (int)(radius * 2)); } else if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { g.DrawPolygon(redPen, ToPointsArray(corners)); } } redPen.Dispose(); g.Dispose(); return(image); }
public static void EternitySplinterDetect() { try { Bitmap bmp = Image.FromFile(PATH + @"\test.png") as Bitmap; Bitmap newBmp = LootSystem.EternitySplinterFilter(bmp); // locate objects using blob counter BlobCounter blobCounter = new BlobCounter() { FilterBlobs = true, MinWidth = 2, MinHeight = 2, MaxWidth = 28, MaxHeight = 28 }; // Process input image blobCounter.ProcessImage(newBmp); // Get information about detected objects Blob[] blobs = blobCounter.GetObjectsInformation(); // create Graphics object to draw on the image and a pen Graphics g = Graphics.FromImage(newBmp); Pen bluePen = new Pen(Color.Blue, 2); // 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]); List <IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); g.DrawPolygon(bluePen, Helper.AForgeToPointsArray(corners)); } bluePen.Dispose(); g.Dispose(); newBmp.Save(PATH + @"\outtest.png"); } catch (Exception ex) { Debug.WriteLine(ex.StackTrace); } }
public void FindContourTest() { Bitmap bmp = Properties.Resources.sample_black; Bitmap gray = AForge.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(bmp); BlobCounter bc = new BlobCounter(gray); bc.ObjectsOrder = ObjectsOrder.Size; Blob[] blobs = bc.GetObjectsInformation(); bc.ExtractBlobsImage(bmp, blobs[0], true); List <IntPoint> expected = bc.GetBlobsEdgePoints(blobs[0]); Bitmap blob = blobs[0].Image.ToManagedImage(); BorderFollowing bf = new BorderFollowing(); List <IntPoint> actual = bf.FindContour(blob); Assert.AreEqual(expected.Count, actual.Count); foreach (IntPoint point in expected) { Assert.IsTrue(actual.Contains(point)); } foreach (IntPoint point in actual) { Assert.IsTrue(expected.Contains(point)); } IntPoint prev = actual[0]; for (int i = 1; i < actual.Count; i++) { IntPoint curr = actual[i]; Assert.IsTrue(System.Math.Abs(prev.X - curr.X) <= 1 && System.Math.Abs(prev.Y - curr.Y) <= 1); prev = curr; } IntPoint first = actual[0]; IntPoint last = actual[actual.Count - 1]; Assert.IsTrue(System.Math.Abs(first.X - last.X) <= 1 && System.Math.Abs(first.Y - last.Y) <= 1); }
/// <summary> /// calculate the blob's position based on the grids position /// </summary> /// <param name="b"></param> /// <param name="offset"></param> private void ProcessBlobs(BlobCounter b, int offset) { double xOff = ((_calibrationStep - 3) % (int)Math.Sqrt(CalibrationFrames - 3)) * _sqrwidth / (int)Math.Sqrt(CalibrationFrames - 3); double yOff = Math.Floor((_calibrationStep - 3) / Math.Sqrt(CalibrationFrames - 3)) * _sqrwidth / (int)Math.Sqrt(CalibrationFrames - 3); foreach (var blob in b.GetObjectsInformation()) { var pos = _mapper.FromPresentation(blob.CenterOfGravity); if (pos.X >= 0 && pos.X <= _vs.Width && pos.Y >= 0 && pos.Y <= _vs.Height) { var xPos = (int)Math.Floor((pos.X - xOff) / _sqrwidth); var yPos = (int)Math.Floor((pos.Y - yOff) / _sqrheight); #if DEBUG using (var g = Graphics.FromImage(actImg)) { g.DrawString(yPos + "," + xPos, new Font(FontFamily.GenericSansSerif, 8.0f), new SolidBrush(Color.White), blob.CenterOfGravity.X, blob.CenterOfGravity.Y); g.Flush(); //Debug.WriteLine("wrote to image"); } #endif if (xPos % 2 == offset && yPos % 2 == offset) // check if the position is plausible { var corners = PointsCloud.FindQuadrilateralCorners(b.GetBlobsEdgePoints(blob)); if (corners.Count == 4) { RecursiveAForgeCalibrator.GridBlobs.InPlaceSort(corners); Grid.AddPoint((int)(xPos * _sqrwidth + xOff), (int)(yPos * _sqrheight + yOff), corners[0].X, corners[0].Y); Grid.AddPoint((int)((xPos + 1) * _sqrwidth + xOff), (int)(yPos * _sqrheight + yOff), corners[1].X, corners[1].Y); Grid.AddPoint((int)(xPos * _sqrwidth + xOff), (int)((yPos + 1) * _sqrheight + yOff), corners[2].X, corners[2].Y); Grid.AddPoint((int)((xPos + 1) * _sqrwidth + xOff), (int)((yPos + 1) * _sqrheight + yOff), corners[3].X, corners[3].Y); } } } } }
public Bitmap extractBlobs(Bitmap originalImage, Bitmap alteredImage) { extractor.ProcessImage(alteredImage); foreach (Blob blob in extractor.GetObjectsInformation()) { List <IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob); List <IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); if (draw2D) { using (var graphics = Graphics.FromImage(originalImage)) { if (corners.Count == 4) { graphics.DrawLine(pen, corners[0].X, corners[0].Y, corners[1].X, corners[1].Y); graphics.DrawLine(pen, corners[1].X, corners[1].Y, corners[2].X, corners[2].Y); graphics.DrawLine(pen, corners[2].X, corners[2].Y, corners[3].X, corners[3].Y); graphics.DrawLine(pen, corners[3].X, corners[3].Y, corners[0].X, corners[0].Y); if (draw3D) { //Reken de afstand tussen de eerste twee hoekpunten uit double Distance = Math.Sqrt((corners[3].X - corners[0].X) * (corners[3].X - corners[0].X) + (corners[3].Y - corners[0].Y) * (corners[3].Y - corners[0].Y)); //Convert naar integer int IDistance = Convert.ToInt32(Distance); //Teken alle verticale lijnen van de kubus graphics.DrawLine(pen, corners[0].X, corners[0].Y, corners[0].X, corners[0].Y - IDistance); graphics.DrawLine(pen, corners[1].X, corners[1].Y, corners[1].X, corners[1].Y - IDistance); graphics.DrawLine(pen, corners[2].X, corners[2].Y, corners[2].X, corners[2].Y - IDistance); graphics.DrawLine(pen, corners[3].X, corners[3].Y, corners[3].X, corners[3].Y - IDistance); //Teken het bovenste vierkant van de kubub graphics.DrawLine(pen, corners[0].X, corners[0].Y - IDistance, corners[1].X, corners[1].Y - IDistance); graphics.DrawLine(pen, corners[1].X, corners[1].Y - IDistance, corners[2].X, corners[2].Y - IDistance); graphics.DrawLine(pen, corners[2].X, corners[2].Y - IDistance, corners[3].X, corners[3].Y - IDistance); graphics.DrawLine(pen, corners[3].X, corners[3].Y - IDistance, corners[0].X, corners[0].Y - IDistance); } } } } } return(originalImage); }
/// <summary> /// APPLY FILTER TO IMAGE /// </summary> /// <param name="bgSelect">TRUE, SET BACKGROUND FILTER. FALSE, SET COLONY FILTER</param> /// <returns></returns> private List <ColonyModel> ProcessIMG(bool bgSelect) { if (bgSelect) { // SET FILTER WITH BG COLOR FilterImgBgSelect(); } else { // SET FILTER WITH COLONY COLOR FilterImgColonySelect(); } // INIT BLOB COUNTER SetBlobCounter(); blobCounter.ProcessImage(bitmapData); BlobCounterToList(blobCounter.GetObjectsInformation()); bitmap.UnlockBits(bitmapData); // SET DISTORTION shapeChecker.MinAcceptableDistortion = 0.2f; shapeChecker.RelativeDistortionLimit = 0.2f; var cellLijst = new List <ColonyModel>(); // DRAW CIRCLE AROUND BLOB for (int i = 0, n = blobList.Count; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobList[i]); AForge.Point center; float radius; // IF SHAPE IS CIRCLE if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { // ADD COLONY TO LIST cellLijst.Add(new ColonyModel(center, radius)); } } this.blobList.Clear(); return(cellLijst); }
private void button6_Click(object sender, EventArgs e) { Bitmap image = (Bitmap)pictureBox5.Image; // create instance of blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.MaxWidth = 350; blobCounter.MaxHeight = 350; //process the dilated image blobCounter.ProcessImage(image); // get info about detected objects Blob[] blobs = blobCounter.GetObjectsInformation(); // create a graphics object to draw on the image and a pen Graphics g = Graphics.FromImage(image); Pen Redpen = new Pen(Color.Red, 4); SimpleShapeChecker shapechecker = new SimpleShapeChecker(); //check in image and draw around the object found as rectangle for (int i = 0, n = blobs.Length; i < n; i++) { List <IntPoint> edgepoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List <IntPoint> cornerpoints; Bitmap bmpCrop; List <Point> Points = new List <Point>(); if (shapechecker.IsQuadrilateral(edgepoints, out cornerpoints)) { if (shapechecker.CheckPolygonSubType(cornerpoints) == PolygonSubType.Rectangle) { g.DrawPolygon(Redpen, cornerpoints.Select(p => new System.Drawing.Point(p.X, p.Y)).ToArray()); } } } Redpen.Dispose(); g.Dispose(); pictureBox6.Image = image; }
public void GetDisplayCornerfrombmp(Bitmap processbmp, out List <IntPoint> displaycornerPoints) { BlobCounter bbc = new BlobCounter(); bbc.FilterBlobs = true; bbc.MinHeight = 5; bbc.MinWidth = 5; bbc.ProcessImage(processbmp); Blob[] blobs = bbc.GetObjectsInformation(); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); foreach (var blob in blobs) { List <IntPoint> edgePoints = bbc.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 from a rectangle if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle) { flagPoints = cornerPoints; continue; } else { flagPoints = null; continue; } } } if (flagPoints == null) { throw new Exception(); } // MessageBox.Show("Cannot Find the Display"); displaycornerPoints = flagPoints; }
public List <PoreAnalyzeData> FindShapes(Bitmap bitmap) { Bitmap reversedbmp = ReverseBitmapColors(bitmap); BlobCounter blobCounter = new BlobCounter(reversedbmp); Blob[] blobs = blobCounter.GetObjects(reversedbmp, false); PoreAnalyzeData[] poreData = new PoreAnalyzeData[blobs.Length]; OnStart?.Invoke(this, blobs.Length); Parallel.For(0, blobs.Length, index => { var edgePoints = blobCounter.GetBlobsEdgePoints(blobs[index]); poreData[index] = new PoreAnalyzeData(blobs[index], ReverseBitmapColors(blobs[index].Image.ToManagedImage()), edgePoints); OnProgress?.Invoke(this, new EventArgs()); }); return(poreData.ToList()); }
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); }
// ========================================================= private Bitmap DrawRectanglesFunct_OLD(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 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); } } } }
/// <summary> /// 扑克识别 /// </summary> /// <param name="bmp"></param> public void PokerDetection(Bitmap bmp) { FiltersSequence seq = new FiltersSequence(); seq.Add(Grayscale.CommonAlgorithms.BT709); // 添加灰度滤镜 seq.Add(new OtsuThreshold()); // 添加二值化滤镜 bmp = seq.Apply(bmp); // 应用滤镜 // 从图像中提取宽度和高度大于150的blob BlobCounter extractor = new BlobCounter(); extractor.FilterBlobs = true; extractor.MinWidth = extractor.MinHeight = 150; extractor.MaxWidth = extractor.MaxHeight = 350; extractor.ProcessImage(bmp); // 用于从原始图像提取扑克牌 QuadrilateralTransformation quadTransformer = new QuadrilateralTransformation(); int CardWidth = 200; int CardHeight = 300; // 用于调整扑克牌大小 ResizeBilinear resizer = new ResizeBilinear(CardWidth, CardHeight); foreach (Blob blob in extractor.GetObjectsInformation()) { // 获取扑克牌的边缘点 List <IntPoint> edgePoints = extractor.GetBlobsEdgePoints(blob); // 利用边缘点,在原始图像上找到四角 List <IntPoint> corners = PointsCloud.FindQuadrilateralCorners(edgePoints); Bitmap cardImg = quadTransformer.Apply(bmp); // 提取扑克牌图像 if (cardImg.Width > cardImg.Height) // 如果扑克牌横放 { cardImg.RotateFlip(RotateFlipType.Rotate90FlipNone); // 旋转之 } cardImg = resizer.Apply(cardImg); // 归一化(重设大小)扑克牌 RefreshBitmap(3, cardImg); } }
public static IntPoint[] DetectSurface(Bitmap image) { var blobCounter = new BlobCounter { FilterBlobs = true, MinHeight = 10, MinWidth = 10 }; var shapes = new List <Shape>(); var shapeChecker = new SimpleShapeChecker(); var threshold = GetThreshold(image); blobCounter.BackgroundThreshold = Color.FromArgb(255, threshold, threshold, threshold); blobCounter.ProcessImage(image); var blobs = blobCounter.GetObjectsInformation(); foreach (var blob in blobs) { if (blob.Fullness >= 1) { continue; } var edgePoints = blobCounter.GetBlobsEdgePoints(blob); if (shapeChecker.IsQuadrilateral(edgePoints, out List <IntPoint> corners)) { shapes.Add(new Shape { Blob = blob, Corners = corners }); } } var bestShape = shapes.OrderBy(s => s.Blob.Area) .Skip(shapes.Count / 2) .Take(1).FirstOrDefault(); return(bestShape?.Corners?.ToArray()); }
private static void DrawMainObjectEdges(ref Bitmap mainObject, BlobCounter blobCounter) { List <IntPoint> corners = new(); // create convex hull searching algorithm GrahamConvexHull hullFinder = new(); foreach (Blob blob in blobCounter.GetObjectsInformation()) { // get blob's edge points List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); corners.AddRange(edgePoints); // blob's convex hull corners = hullFinder.FindHull(corners); } if (corners.Any()) { //using (Graphics g = Graphics.FromImage(mainObject)) //using (Pen pen = new Pen(Color.FromArgb(160, 255, 160), 3)) //{ // g.DrawPolygon(pen, corners.Select(c => new Point(c.X, c.Y)).ToArray()); //} GraphicsPath graphicsPath = new(); graphicsPath.AddPolygon(corners.Select(c => new Point(c.X, c.Y)).ToArray()); RectangleF mainObjectBounds = graphicsPath.GetBounds(); Region clipRegion = new(graphicsPath); clipRegion.Translate(-mainObjectBounds.X, -mainObjectBounds.Y); Bitmap clippedImage = new((int)mainObjectBounds.Width, (int)mainObjectBounds.Height); //, PixelFormat.Format32bppArgb); using var g = Graphics.FromImage(clippedImage); g.Clip = clipRegion; // restrict drawing region g.DrawImage(mainObject, -mainObjectBounds.X, -mainObjectBounds.Y, mainObject.Width, mainObject.Height); // draw clipped mainObject = clippedImage; } }
public void FindContourTest() { Bitmap bmp = Properties.Resources.sample_black; Bitmap gray = AForge.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(bmp); BlobCounter bc = new BlobCounter(gray); bc.ObjectsOrder = ObjectsOrder.Size; Blob[] blobs = bc.GetObjectsInformation(); bc.ExtractBlobsImage(bmp, blobs[0], true); List<IntPoint> expected = bc.GetBlobsEdgePoints(blobs[0]); Bitmap blob = blobs[0].Image.ToManagedImage(); BorderFollowing bf = new BorderFollowing(); List<IntPoint> actual = bf.FindContour(blob); Assert.AreEqual(expected.Count, actual.Count); foreach (IntPoint point in expected) Assert.IsTrue(actual.Contains(point)); foreach (IntPoint point in actual) Assert.IsTrue(expected.Contains(point)); IntPoint prev = actual[0]; for (int i = 1; i < actual.Count; i++) { IntPoint curr = actual[i]; Assert.IsTrue(System.Math.Abs(prev.X - curr.X) <= 1 && System.Math.Abs(prev.Y - curr.Y) <= 1); prev = curr; } IntPoint first = actual[0]; IntPoint last = actual[actual.Count - 1]; Assert.IsTrue(System.Math.Abs(first.X - last.X) <= 1 && System.Math.Abs(first.Y - last.Y) <= 1); }
public List <List <System.Drawing.Point> > GetEdges() { // 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); List <List <System.Drawing.Point> > edges = new List <List <System.Drawing.Point> >(); for (int i = 0; i < blobs.Length; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List <System.Drawing.Point> edgePointsNormal = ToPointsArray(edgePoints); edges.Add(edgePointsNormal); } return(edges); }
/// <summary> /// Finds circles - zoom is NOT compensated for in returned results /// </summary> /// <returns>Graphic coordinates with zoom not accounted for for found circles</returns> public static List <Shapes.Circle> FindCircles(VideoProcessing vp, Bitmap frame) { // locating objects if (frame == null) { return(null); } BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 5; blobCounter.MinWidth = 5; blobCounter.ProcessImage(frame); 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]); Point center; float radius; // is circle ? if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { if (radius > 3) // filter out some noise { var circle = new Shapes.Circle(center.X, center.Y, radius); Circles.Add(circle); } } } SetVideoProcessing(Circles, vp); return(Circles); }
private static Bitmap ClipMainObject(Bitmap image, BlobCounter blobCounter) { List <IntPoint> corners = new(); // Create convex hull searching algorithm GrahamConvexHull hullFinder = new(); foreach (Blob blob in blobCounter.GetObjectsInformation()) { // Get blob's edge points List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blob); corners.AddRange(edgePoints); // Blob's convex hull corners = hullFinder.FindHull(corners); } if (corners.Any()) { GraphicsPath graphicsPath = new GraphicsPath(); graphicsPath.AddPolygon(corners.Select(c => new Point(c.X, c.Y)).ToArray()); RectangleF mainObjectBounds = graphicsPath.GetBounds(); // Move region to top left corner Region clipRegion = new Region(graphicsPath); clipRegion.Translate(-mainObjectBounds.X, -mainObjectBounds.Y); // Draw selected region Bitmap clippedImage = new((int)mainObjectBounds.Width, (int)mainObjectBounds.Height); //, PixelFormat.Format32bppArgb); using var g = Graphics.FromImage(clippedImage); g.Clip = clipRegion; // Restrict drawing region g.DrawImage(image, -mainObjectBounds.X, -mainObjectBounds.Y, image.Width, image.Height); // Draw clipped return(clippedImage); } return(image); }
public void FindContourTest2() { Bitmap bmp = Properties.Resources.hand2; BlobCounter bc = new BlobCounter(bmp); bc.ObjectsOrder = ObjectsOrder.Size; Blob[] blobs = bc.GetObjectsInformation(); bc.ExtractBlobsImage(bmp, blobs[0], true); List <IntPoint> expected = bc.GetBlobsEdgePoints(blobs[0]); Bitmap blob = blobs[0].Image.ToManagedImage(); BorderFollowing bf = new BorderFollowing(); List <IntPoint> actual = bf.FindContour(blob); foreach (IntPoint point in expected) { Assert.IsTrue(actual.Contains(point)); } IntPoint prev = actual[0]; for (int i = 1; i < actual.Count; i++) { IntPoint curr = actual[i]; Assert.IsTrue(System.Math.Abs(prev.X - curr.X) <= 1 && System.Math.Abs(prev.Y - curr.Y) <= 1); prev = curr; } IntPoint first = actual[0]; IntPoint last = actual[actual.Count - 1]; Assert.IsTrue(System.Math.Abs(first.X - last.X) <= 1 && System.Math.Abs(first.Y - last.Y) <= 1); }
public List <IntPoint> GetDisplayCorner(Bitmap bitmap) { BlobCounter bbc = new BlobCounter(); bbc.FilterBlobs = true; bbc.MinHeight = 5; bbc.MinWidth = 5; bbc.ProcessImage(bitmap); Blob[] blobs = bbc.GetObjectsInformation(); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); foreach (var blob in blobs) { List <IntPoint> edgePoints = bbc.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 from a rectangle if (shapeChecker.CheckPolygonSubType(cornerPoints) == PolygonSubType.Rectangle) { flagPoints = cornerPoints; continue; } else { flagPoints = null; continue; } } } return(flagPoints); }
private void process_image(PictureBox box, bool toinvert) { Bitmap original = (Bitmap)Bitmap.FromFile(_fname); original.Save("C:\\users\\alberto geniola\\desktop\\dbg\\original_" + toinvert + ".bmp"); // Setup the Blob counter BlobCounter blobCounter = new BlobCounter(); blobCounter.BackgroundThreshold = Color.FromArgb(10, 10, 10); blobCounter.FilterBlobs = true; blobCounter.CoupledSizeFiltering = false; blobCounter.MinHeight = minHeight; blobCounter.MinWidth = minWidth; List <Blob> blobs = new List <Blob>(); // Button scanning // Apply the grayscale. This is needed for AForge's filters using (Bitmap grey_scaled = Grayscale.CommonAlgorithms.BT709.Apply(original)) { // Invert the image if requested if (toinvert) { Invert invert = new Invert(); invert.ApplyInPlace(grey_scaled); } using (Bitmap t1 = new Threshold(64).Apply(grey_scaled)) { using (var tmp = new Bitmap(t1.Width, t1.Height)) { using (Graphics g = Graphics.FromImage(tmp)) { g.DrawImage(t1, 0, 0); } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\filtered_" + toinvert + ".bmp"); // The blob counter will analyze the bitmap looking for shapes blobCounter.ProcessImage(tmp); var tmparr = blobCounter.GetObjectsInformation(); blobs.AddRange(tmparr); for (int i = 0, n = tmparr.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { IntPoint p0, p1; PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1); var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y); // Skip any shape representing the border of the whole window ( +10px padding) if (r.Width >= (original.Width - 10)) { continue; } using (var g = Graphics.FromImage(tmp)) { g.DrawRectangle(_marker, r); } } } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\processed_" + toinvert + ".bmp"); } } using (Bitmap t2 = new SISThreshold().Apply(grey_scaled)) { using (var tmp = new Bitmap(t2.Width, t2.Height)) { using (Graphics g = Graphics.FromImage(tmp)) { g.DrawImage(t2, 0, 0); } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\t2_" + toinvert + ".bmp"); // The blob counter will analyze the bitmap looking for shapes blobCounter.ProcessImage(tmp); var tmparr = blobCounter.GetObjectsInformation(); blobs.AddRange(tmparr); for (int i = 0, n = tmparr.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { IntPoint p0, p1; PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1); var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y); // Skip any shape representing the border of the whole window ( +10px padding) if (r.Width >= (original.Width - 10)) { continue; } using (var g = Graphics.FromImage(tmp)) { g.DrawRectangle(_marker, r); } } } tmp.Save("C:\\users\\alberto geniola\\desktop\\dbg\\t1_" + toinvert + ".bmp"); } } } Bitmap test = (Bitmap)original.Clone(); // Let's analyze every single shape for (int i = 0, n = blobs.Count; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); if (edgePoints.Count > 1) { IntPoint p0, p1; PointsCloud.GetBoundingRectangle(edgePoints, out p0, out p1); var r = new Rectangle(p0.X, p0.Y, p1.X - p0.X, p1.Y - p0.Y); // Skip any shape representing the border of the whole window ( +10px padding) if (r.Width >= (original.Width - 10)) { continue; } using (var g = Graphics.FromImage(test)) { g.DrawRectangle(_marker, r); } // This is most-likely a button! // Crop the image and pass it to the OCR engine for text recognition using (Bitmap button = new Bitmap(r.Width, r.Height)) { // Scan the original shape String txt = null; using (var g1 = Graphics.FromImage(button)) { g1.DrawImage(original, 0, 0, r, GraphicsUnit.Pixel); } // Process OCR on that image txt = scanButton(button); if (String.IsNullOrEmpty(txt)) { using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button)) { if (toinvert) { new Invert().ApplyInPlace(tmp); } new SISThreshold().ApplyInPlace(tmp); txt = scanButton(tmp); } } // If still nothing is found, repeat the analysis with the second version of the filter if (String.IsNullOrEmpty(txt)) { using (Bitmap tmp = Grayscale.CommonAlgorithms.BT709.Apply(button)) { if (toinvert) { new Invert().ApplyInPlace(tmp); } new Threshold(64).ApplyInPlace(tmp); txt = scanButton(tmp); } } if (!String.IsNullOrEmpty(txt)) { using (var g = Graphics.FromImage(test)) { int SPACING = 5; double angle = 45 * 2 * Math.PI / 360; // 45 degrees to radiants for (int x = 0; x < r.Width; x += SPACING) { PointF start = new PointF(r.X + x, r.Y); PointF end = new PointF((float)(r.X + x + r.Height * Math.Tan(angle)), r.Y + r.Height); if (end.X > (r.X + r.Width)) { // Calculate midpoint var delta = end.X - r.Width; end.X = r.X + r.Width; end.Y = r.Y + (float)(Math.Tan(angle) * r.Width) - x; // Draw the overflow line g.DrawLine(_marker2, r.X, end.Y, delta, r.Y + r.Height); } g.DrawLine(_marker2, start, end); } g.FillRectangle(_b, r); var dim = g.MeasureString(txt.Trim(), _f); g.DrawString(txt.Trim().ToUpper(), _f, _b2, r.X + (r.Width - dim.Width) / 2, r.Y + (r.Height - dim.Height) / 2); } } test.Save("C:\\users\\alberto geniola\\desktop\\dbg\\processed_" + toinvert + ".bmp"); /* * // At this point we should have a result. Add it to list if it does not overlap any UIAutomated element * UIControlCandidate t = new UIControlCandidate(); * t.PositionWindowRelative = r; * var winLoc = w.WindowLocation; * t.PositionScreenRelative = new Rectangle(r.X + winLoc.X, r.Y + winLoc.Y, r.Width, r.Height); * t.Text = txt; * t.Score = policy.RankElement(t); * * // If the item falls into the same area of a UI element, ignore it. * bool overlaps = false; * foreach (var el in res) * { * if (el.AutoElementRef != null && el.PositionScreenRelative.IntersectsWith(t.PositionScreenRelative)) * { * overlaps = true; * break; * } * } * if (!overlaps) * res.Add(t); */ } } box.Image = test; } }
/// <summary> /// 图片处理过程 /// </summary> /// <param name="bitmap"></param> private /*Bitmap*/ 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(); //Bitmap test = bitmap.Save("12345.jpg", ImageFormat.Gif); Graphics g = Graphics.FromImage(CheckPixPicture(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(redPen, ToPointsArray(corners)); } //} } //yellowPen.Dispose(); redPen.Dispose(); //greenPen.Dispose(); //bluePen.Dispose(); //brownPen.Dispose(); g.Dispose(); // put new image to clipboard Clipboard.SetDataObject(bitmap); //return bitmap; }
private async Task CalibThread(FrameReadyEventArgs e) { Debug.WriteLine("Calibrating " + _calibrationStep + " " + _drawing); e.Frame.Bitmap.Save(@"C:\temp\daforge\src\img" + (_calibrationStep < 10?"0":"") + _calibrationStep + "-" + (_drawing?"1":"0") + "-" + _errors + ".jpg", ImageFormat.Jpeg); if (_errors > 100) { //calibration not possible return; } if (_calibrationStep == CalibrationFrames && !_drawing) { _cc.FrameReady -= BaseCalibration; // TODO //Grid.Calculate(); _vs.Close(); CalibrationCompleted(this, new EventArgs()); } else { if (_calibrationStep > 2) { if (_drawing) { // draw diffimage _drawing = false; _vs.Clear(); FillRects(); diffFilter.OverlayImage = e.Frame.Bitmap; } else { // analyse diffimage _calibrationStep++; _drawing = true; _vs.Clear(); FillRects(); _calibrationStep--; var gbm = diffFilter.Apply(e.Frame.Bitmap); gbm.Save(@"C:\temp\daforge\diff\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg); #if DEBUG actImg = (Bitmap)gbm.Clone(); #endif var d = UnmanagedImage.FromManagedImage(gbm); var stats = new ImageStatistics(d); var gcf = new ColorFiltering(new IntRange(0, 255), new IntRange((int)(stats.GreenWithoutBlack.Mean + stats.GreenWithoutBlack.StdDev + 5), 255), new IntRange(0, 255)); var bcf = new ColorFiltering(new IntRange(0, 255), new IntRange(0, 255), new IntRange((int)(stats.BlueWithoutBlack.Mean + stats.BlueWithoutBlack.StdDev), 255)); //Debug.WriteLine("Green: " + stats.GreenWithoutBlack.Median + " Blue: " + stats.BlueWithoutBlack.Median); //Debug.WriteLine("Green: " + stats.GreenWithoutBlack.Mean + " Blue: " + stats.BlueWithoutBlack.Mean); var bf = new Difference(gcf.Apply(d)); bcf.ApplyInPlace(d); bf.ApplyInPlace(d); d.ToManagedImage().Save(@"C:\temp\daforge\diff\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg); stats = new ImageStatistics(d); gcf = new ColorFiltering(new IntRange(0, 255), new IntRange((int)stats.GreenWithoutBlack.Mean, 255), new IntRange(0, 255)); bcf = new ColorFiltering(new IntRange(0, 255), new IntRange(0, 255), new IntRange((int)stats.BlueWithoutBlack.Mean, 255)); // split channels var bbm = bcf.Apply(d); bbm.ToManagedImage().Save(@"C:\temp\daforge\bimg\img" + _calibrationStep + ".jpg", ImageFormat.Bmp); gcf.ApplyInPlace(d); d.ToManagedImage().Save(@"C:\temp\daforge\gimg\img" + _calibrationStep + ".jpg", ImageFormat.Bmp); var gblobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.YX, MaxHeight = 60, MinHeight = 15, MaxWidth = 60, MinWidth = 15, FilterBlobs = true, CoupledSizeFiltering = false }; gblobCounter.ProcessImage(d); var bblobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.YX, MaxHeight = 60, MinHeight = 15, MaxWidth = 60, MinWidth = 15, FilterBlobs = true, CoupledSizeFiltering = false }; bblobCounter.ProcessImage(bbm); ProcessBlobs(gblobCounter, 0); ProcessBlobs(bblobCounter, 1); #if DEBUG actImg.Save(@"C:\temp\daforge\squares\img" + _calibrationStep + ".jpg", ImageFormat.Jpeg); #endif _calibrationStep++; } } else { switch (_calibrationStep) { case 2: var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\src" + _errors + ".jpg", ImageFormat.Jpeg); bm = diffFilter.Apply(bm); var gf = new GaussianBlur(9.0, 3); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, BackgroundThreshold = Color.FromArgb(255, 15, 20, 20), FilterBlobs = true }; blobCounter.ProcessImage(bm); bm.ToManagedImage().Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.Jpeg); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); RecursiveAForgeCalibrator.GridBlobs.InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 && Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 && Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 && Grid.TopLeft.X < Grid.BottomRight.X && blobs[i - 1].Area > 60000 && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _drawing = true; _vs.Clear(); FillRects(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); //_mapper.PredictFromCorners(); } else { _calibrationStep = 0; _errors++; } } else { _calibrationStep = 0; _errors++; _vs.Draw(); } break; case 1: diffFilter.OverlayImage = e.Frame.Bitmap; //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\srcf" + _errors + ".jpg", ImageFormat.Jpeg); //_vs.AddRect(0, 0, (int) _vs.Width, (int) _vs.Height, Color.FromArgb(255, 255, 255, 255)); _vs.Clear(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (!(y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1)) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height); Grid.ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height); _mapper = new CornerBarycentricMapper(Grid); var thread = new Thread(() => { _vs.Show(); _vs.AddRect(0, 0, _vs.Width, _vs.Height, Color.FromArgb(255, 0, 0, 0)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; } } } Debug.WriteLine("Releasing"); await Task.Delay(500); _sem.Release(); }
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); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = Graphics.FromImage(bitmap); Pen brownPen = new Pen(Color.Red, 3); 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)) { PolygonSubType subType = shapeChecker.CheckPolygonSubType(corners); if (subType == PolygonSubType.Unknown) { if (corners.Count == 4) { g.DrawPolygon(brownPen, ToPointsArray(corners)); } } else { if (corners.Count == 4) { g.DrawPolygon(brownPen, ToPointsArray(corners)); } } } } brownPen.Dispose(); g.Dispose(); Clipboard.SetDataObject(bitmap); pictureBox5.Image = bitmap; }
public void FindContourTest2() { Bitmap bmp = Properties.Resources.hand2; BlobCounter bc = new BlobCounter(bmp); bc.ObjectsOrder = ObjectsOrder.Size; Blob[] blobs = bc.GetObjectsInformation(); bc.ExtractBlobsImage(bmp, blobs[0], true); List<IntPoint> expected = bc.GetBlobsEdgePoints(blobs[0]); Bitmap blob = blobs[0].Image.ToManagedImage(); BorderFollowing bf = new BorderFollowing(); List<IntPoint> actual = bf.FindContour(blob); foreach (IntPoint point in expected) Assert.IsTrue(actual.Contains(point)); IntPoint prev = actual[0]; for (int i = 1; i < actual.Count; i++) { IntPoint curr = actual[i]; Assert.IsTrue(System.Math.Abs(prev.X - curr.X) <= 1 && System.Math.Abs(prev.Y - curr.Y) <= 1); prev = curr; } IntPoint first = actual[0]; IntPoint last = actual[actual.Count - 1]; Assert.IsTrue(System.Math.Abs(first.X - last.X) <= 1 && System.Math.Abs(first.Y - last.Y) <= 1); }
private async Task CalibThread(FrameReadyEventArgs e) { try { if (_errors > MaxErrorCount) { _cc.FrameReady -= BaseCalibration; _vs.Close(); Console.WriteLine("Calibration impossible"); } if (_calibrationStep == CalibrationFrames) { _cc.FrameReady -= BaseCalibration; _vs.Close(); Console.WriteLine("Calibration complete"); CalibrationCompleted(this, new EventArgs()); } else { switch (_calibrationStep) { // get the corners from the difference image case 2: var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); bm = _diffFilter.Apply(bm); var gf = new GaussianBlur(9.0, 3); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, BackgroundThreshold = Color.FromArgb(255, 15, 20, 20), FilterBlobs = true }; blobCounter.ProcessImage(bm); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 && Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 && Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 && Grid.TopLeft.X < Grid.BottomRight.X && //blobs[i - 1].Area > 60000 && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _vs.Clear(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); } else { _calibrationStep = 0; _errors++; } } else { _calibrationStep = 0; _errors++; _vs.Draw(); } break; case 1: // draw second image, store the first _diffFilter.OverlayImage = e.Frame.Bitmap; _vs.Clear(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (!(y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1)) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; //draw the first image case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height) { ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height) }; var thread = new Thread(() => { _vs.Show(); _vs.AddRect(0, 0, _vs.Width, _vs.Height, Color.FromArgb(255, 0, 0, 0)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; } } await Task.Delay(MillisecondsDelay); } finally { _sem.Release(); } }
public List <Spot> DetectBlobs() { BlobCounterBase counter = new BlobCounter { FilterBlobs = true, MinHeight = minHeight, MinWidth = minWidth, ObjectsOrder = ObjectsOrder.Area }; counter.ProcessImage(image); Blob[] blobs = counter.GetObjectsInformation(); List <Spot> spots = new List <Spot>(); foreach (Blob blob in blobs) { counter.ExtractBlobsImage(image, blob, false); Point position = new Point(blob.Rectangle.X, blob.Rectangle.Y); int width = blob.Rectangle.Width; int heigth = blob.Rectangle.Height; Spot spot = new Spot(blob.Image.ToManagedImage(), position, width, heigth, blob.Area, counter.GetBlobsEdgePoints(blob)); spots.Add(spot); } return(spots); }
private void ProcessImage(Bitmap bitmap) { if (CBApplyCanny.Checked) { Bitmap video2 = (Bitmap)bitmap.Clone(); Grayscale gray = new Grayscale(0.2125, 0.7154, 0.0721); Bitmap video3 = gray.Apply(video2); CannyEdgeDetector canny = new CannyEdgeDetector(0, 70); canny.ApplyInPlace(video3); //PictureViewerEditor.Image = (Bitmap)Image.FromFile(imageFileName); PBCanny.Image = (Bitmap)video3.Clone();//assign the pointer back to the clone //if (CBFindCircles.Checked) //{ // //System.Drawing.Image returnImage = null; // //returnImage = (System.Drawing.Image)CaptureBox.Image.Clone(); // // Clipboard.SetImage(replacementImage); // Bitmap cannyImage = (Bitmap)PBCapture.Image.Clone(); // ProcessImage(cannyImage); // return; //} GC.Collect(); //return; } // 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); PBCanny.Image = (Bitmap)bitmap.Clone(); // 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 PBAnalysis.Image = bitmap; //UpdatePictureBoxPosition(); }
private async Task CalibThread(FrameReadyEventArgs e) { //Debug.WriteLine("Calibrating " + _calibrationStep + " " + _drawing); //e.Frame.Bitmap.Save(@"C:\temp\daforge\src\img" + (_calibrationStep<10?"0":"") + _calibrationStep + "-" + (_drawing?"1":"0") + "-" + _errors + ".jpg", ImageFormat.Jpeg); if (_errors > 100) { //calibration not possible return; } if (_calibrationStep == CalibrationFrames) { _cc.FrameReady -= BaseCalibration; // TODO //Grid.Calculate(); //Grid.PredictFromCorners(); _vs.Close(); Console.WriteLine("Calibration complete"); CalibrationCompleted(this, new EventArgs()); } else { switch (_calibrationStep) { // get the corners from the difference image case 2: var bm = UnmanagedImage.FromManagedImage(e.Frame.Bitmap); //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\src" + _errors + ".jpg", ImageFormat.Jpeg); bm = diffFilter.Apply(bm); var gf = new GaussianBlur(9.0, 3); gf.ApplyInPlace(bm); var cf = new ColorFiltering(new IntRange(10, 255), new IntRange(20, 255), new IntRange(20, 255)); cf.ApplyInPlace(bm); var blobCounter = new BlobCounter { ObjectsOrder = ObjectsOrder.Size, BackgroundThreshold = Color.FromArgb(255, 15, 20, 20), FilterBlobs = true }; blobCounter.ProcessImage(bm); //bm.ToManagedImage().Save(@"C:\temp\daforge\diff\img" + _calibrationStep + "-" + _errors + ".jpg", ImageFormat.Jpeg); var blobs = blobCounter.GetObjectsInformation(); if (blobs.Any()) { int i = 0; List <IntPoint> corners; do { corners = PointsCloud.FindQuadrilateralCorners(blobCounter.GetBlobsEdgePoints(blobs[i++])); } while (corners.Count != 4); RecursiveAForgeCalibrator.GridBlobs.InPlaceSort(corners); Grid.TopLeft = new Point(corners[0].X, corners[0].Y); Grid.TopRight = new Point(corners[1].X, corners[1].Y); Grid.BottomLeft = new Point(corners[2].X, corners[2].Y); Grid.BottomRight = new Point(corners[3].X, corners[3].Y); if (Grid.TopLeft.X > 10 && Grid.TopRight.X < _vs.Width - 5 && Grid.BottomLeft.X > 5 && Grid.BottomRight.X < _vs.Width - 5 && Grid.TopLeft.Y > 10 && Grid.TopRight.Y > 5 && Grid.BottomLeft.Y < _vs.Height - 5 && Grid.BottomRight.Y < _vs.Height - 5 && Grid.TopLeft.X < Grid.BottomRight.X && //blobs[i - 1].Area > 60000 && Grid.BottomLeft.X < Grid.TopRight.X && Grid.BottomLeft.X < Grid.BottomRight.X && Grid.TopLeft.Y < Grid.BottomLeft.Y && Grid.TopLeft.Y < Grid.BottomRight.Y && Grid.TopRight.Y < Grid.BottomLeft.Y && Grid.TopRight.Y < Grid.BottomRight.Y) { _calibrationStep++; _vs.Clear(); Grid.AddPoint(new Point(), new Point(corners[0].X, corners[0].Y)); Grid.AddPoint(new Point(0, _vs.Height), new Point(corners[1].X, corners[1].Y)); Grid.AddPoint(new Point(_vs.Width, 0), new Point(corners[2].X, corners[2].Y)); Grid.AddPoint(new Point(_vs.Width, _vs.Height), new Point(corners[3].X, corners[3].Y)); } else { _calibrationStep = 0; _errors++; } } else { _calibrationStep = 0; _errors++; _vs.Draw(); } break; case 1: // draw second image, store the first diffFilter.OverlayImage = e.Frame.Bitmap; //diffFilter.OverlayImage.Save(@"C:\temp\daforge\diff\srcf" + _errors + ".jpg", ImageFormat.Jpeg); //_vs.AddRect(0, 0, (int) _vs.Width, (int) _vs.Height, Color.FromArgb(255, 255, 255, 255)); _vs.Clear(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (!(y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1)) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; //draw the first image case 0: Grid = new Grid(e.Frame.Bitmap.Width, e.Frame.Bitmap.Height); Grid.ScreenSize = new Rectangle(0, 0, _vs.Width, _vs.Height); var thread = new Thread(() => { _vs.Show(); _vs.AddRect(0, 0, _vs.Width, _vs.Height, Color.FromArgb(255, 0, 0, 0)); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); for (int y = 0; y < Columncount; y++) { for (int x = 0; x < Rowcount; x++) { if (y % 2 == 0 && x % 2 == 0 || y % 2 == 1 && x % 2 == 1) { _vs.AddRect((int)(x * _sqrwidth), (int)(y * _sqrheight), (int)_sqrwidth, (int)_sqrheight, Color.FromArgb(255, 255, 255, 255)); } } } _vs.Draw(); _calibrationStep++; break; } } Debug.WriteLine("Releasing"); await Task.Delay(500); _sem.Release(); }
public void nesnebul(Bitmap image) { BlobCounter blobCounter = new BlobCounter(); blobCounter.MinWidth = 5; blobCounter.MinHeight = 5; blobCounter.FilterBlobs = true; blobCounter.ObjectsOrder = ObjectsOrder.Size; //Grayscale griFiltre = new Grayscale(0.2125, 0.7154, 0.0721); //Grayscale griFiltre = new Grayscale(0.2, 0.2, 0.2); //Bitmap griImage = griFiltre.Apply(image); BitmapData objectsData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, image.PixelFormat); // grayscaling Grayscale grayscaleFilter = new Grayscale(0.2125, 0.7154, 0.0721); UnmanagedImage grayImage = grayscaleFilter.Apply(new UnmanagedImage(objectsData)); // unlock image image.UnlockBits(objectsData); blobCounter.ProcessImage(image); Rectangle[] rects = blobCounter.GetObjectsRectangles(); Blob[] blobs = blobCounter.GetObjectsInformation(); pictureBox2.Image = image; if (radio_single_object_track.Checked) { //Single Object Tracking Single Tracking-------- foreach (Rectangle recs in rects) { if (rects.Length > 0) { Rectangle objectRect = rects[0]; //Graphics g = Graphics.FromImage(image); Graphics g = pictureBox1.CreateGraphics(); Graphics g2 = pictureBox2.CreateGraphics(); using (Pen pen = new Pen(Color.FromArgb(252, 3, 26), 2)) { g.DrawRectangle(pen, objectRect); } //Coordinates of the rectified rectangle are taken. int objectX = objectRect.X + (objectRect.Width / 2); int objectY = objectRect.Y + (objectRect.Height / 2); g.DrawString(objectX.ToString() + "X" + objectY.ToString(), new Font("Arial", 12), Brushes.Red, new System.Drawing.Point(250, 1)); Rectangle rec = new Rectangle(objectX, objectY, 5, 5); g2.DrawEllipse(Pens.White, rec); g.Dispose(); if (chek_show_coordi.Checked) { this.Invoke((MethodInvoker) delegate { richTextBox1.Text = objectRect.Location.ToString() + "\n" + richTextBox1.Text + "\n";; }); } } } } if (radio_multi_obj_track.Checked) { //Multi tracking Çoklu cisim Takibi------- for (int i = 0; rects.Length > i; i++) { Rectangle objectRect = rects[i]; //Graphics g = Graphics.FromImage(image); Graphics g = pictureBox1.CreateGraphics(); using (Pen pen = new Pen(Color.FromArgb(252, 3, 26), 2)) { g.DrawRectangle(pen, objectRect); g.DrawString((i + 1).ToString(), new Font("Arial", 12), Brushes.Red, objectRect); } //Cizdirilen Dikdörtgenin Koordinatlari aliniyor. int objectX = objectRect.X + (objectRect.Width / 2); int objectY = objectRect.Y + (objectRect.Height / 2); g.DrawString(objectX.ToString() + "X" + objectY.ToString(), new Font("Arial", 12), Brushes.Red, new System.Drawing.Point(250, 1)); if (chck_dis_meter.Checked) { if (rects.Length > 1) { for (int j = 0; j < rects.Length - 1; j++) { int ilkx = (rects[j].Right + rects[j].Left) / 2; int ilky = (rects[j].Top + rects[j].Bottom) / 2; int ikix = (rects[j + 1].Right + rects[j + 1].Left) / 2; int ikiy = (rects[j + 1].Top + rects[j + 1].Bottom) / 2; g = pictureBox1.CreateGraphics(); g.DrawLine(Pens.Red, rects[j].Location, rects[j + 1].Location); g.DrawLine(Pens.Blue, rects[0].Location, rects[rects.Length - 1].Location); g.DrawLine(Pens.Red, ilkx, ilky, ikix, ikiy); } } if (rects.Length == 2) { Rectangle ilk = rects[0]; Rectangle iki = rects[1]; int ilkX = ilk.X + (ilk.Width / 2); int ilkY = ilk.Y + (ilk.Height / 2); int ikiX = iki.X + (iki.Width / 2); int ikiY = iki.Y + (iki.Height / 2); //1 pixel (X) = 0.0264583333333334 centimeter [cm] double formul = Math.Floor((Math.Sqrt((Math.Pow((ilkX - ikiX), 2)) + Math.Pow((ilkY - ikiY), 2))) * 0.0264); string uzaklikY = "Y-" + Convert.ToString(ilkX - ikiX); string uzaklikX = "X-" + Convert.ToString(ilkY - ikiY); string distance = uzaklikX + " " + uzaklikY; AForge.Imaging.Drawing.Line(objectsData, new IntPoint((int)ilkX, (int)ilkY), new IntPoint((int)ikiX, (int)ikiY), Color.Blue); this.Invoke((MethodInvoker) delegate { richTextBox2.Text = formul.ToString() + " cm\n" + richTextBox2.Text + " cm\n";; }); if (check_dist_coord.Checked) { this.Invoke((MethodInvoker) delegate { richTextBox3.Text = distance.ToString() + "\n" + richTextBox3.Text + "\n";; }); } } } g.Dispose(); // this.Invoke((MethodInvoker)delegate //{ // richTextBox1.Text = objectRect.Location.ToString() + "\n" + richTextBox1.Text + "\n"; ; //}); } } if (radio_geometric.Checked) { SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); Graphics g = pictureBox1.CreateGraphics(); 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(); } }