// Set image to display by the control public int SetImage(Bitmap image) { leftEdges.Clear(); rightEdges.Clear(); topEdges.Clear(); bottomEdges.Clear(); hulls.Clear(); quadrilaterals.Clear(); selectedBlobID = 0; this.image = Accord.Imaging.Image.Clone(image, PixelFormat.Format24bppRgb); imageWidth = this.image.Width; imageHeight = this.image.Height; blobCounter.ProcessImage(this.image); blobs = blobCounter.GetObjectsInformation(); GrahamConvexHull grahamScan = new GrahamConvexHull(); foreach (Blob blob in blobs) { List<IntPoint> leftEdge = new List<IntPoint>(); List<IntPoint> rightEdge = new List<IntPoint>(); List<IntPoint> topEdge = new List<IntPoint>(); List<IntPoint> bottomEdge = new List<IntPoint>(); // collect edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge); blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge); leftEdges.Add(blob.ID, leftEdge); rightEdges.Add(blob.ID, rightEdge); topEdges.Add(blob.ID, topEdge); bottomEdges.Add(blob.ID, bottomEdge); // find convex hull List<IntPoint> edgePoints = new List<IntPoint>(); edgePoints.AddRange(leftEdge); edgePoints.AddRange(rightEdge); List<IntPoint> hull = grahamScan.FindHull(edgePoints); hulls.Add(blob.ID, hull); List<IntPoint> quadrilateral = null; // find quadrilateral if (hull.Count < 4) { quadrilateral = new List<IntPoint>(hull); } else { quadrilateral = PointsCloud.FindQuadrilateralCorners(hull); } quadrilaterals.Add(blob.ID, quadrilateral); // shift all points for vizualization IntPoint shift = new IntPoint(1, 1); PointsCloud.Shift(leftEdge, shift); PointsCloud.Shift(rightEdge, shift); PointsCloud.Shift(topEdge, shift); PointsCloud.Shift(bottomEdge, shift); PointsCloud.Shift(hull, shift); PointsCloud.Shift(quadrilateral, shift); } UpdatePosition(); Invalidate(); return blobs.Length; }
/// <summary> /// calculate the blob's position based on the grids position /// </summary> /// <param name="b"></param> /// <param name="offset"></param> private bool ProcessBlobs(BlobCounter bc) { var blobs = new List <Blob>(bc.GetObjectsInformation()); blobs.RemoveAll(x => !Grid.Contains(x.CenterOfGravity)); blobs.RemoveAll(x => x.Fullness < 0.5); //if (blobs.Count < 4) //{ // Debug.WriteLine("too few blobs"); // return false; //} //if (blobs.Count > 5) //{ // Debug.WriteLine("too many blobs"); // return false; //} var refs = new Dictionary <AForge.Point, Point>(); var parts = (int)Math.Pow(2, _calibrationStep - 2); var w = _vs.Width / parts; var h = _vs.Height / parts; Point?missing = null; for (int i = 0; i <= parts; i++) { for (int j = 0; j <= parts; j++) { if (i % 2 == 1) { if (j % 2 == 1) { //center of a rectangle var tl = Grid.GetRefPoint((i - 1) * w, (j - 1) * h, 1); var tr = Grid.GetRefPoint((i + 1) * w, (j - 1) * h, 1); var bl = Grid.GetRefPoint((i - 1) * w, (j + 1) * h, 1); var br = Grid.GetRefPoint((i + 1) * w, (j + 1) * h, 1); refs.Add(new AForge.Point((tl.X + tr.X + bl.X + br.X) / 4.0f, (tl.Y + tr.Y + bl.Y + br.Y) / 4.0f), new Point(i, j)); } else { // middle of a horizontal outline var l = Grid.GetRefPoint((i - 1) * w, (j) * h, 1); var r = Grid.GetRefPoint((i + 1) * w, (j) * h, 1); refs.Add(new AForge.Point((l.X + r.X) / 2.0f, (l.Y + r.Y) / 2.0f), new Point(i, j)); } } else if (j % 2 == 1) { // middle of a horizontal outline var t = Grid.GetRefPoint((i) * w, (j - 1) * h, 1); var b = Grid.GetRefPoint((i) * w, (j + 1) * h, 1); refs.Add(new AForge.Point((t.X + b.X) / 2.0f, (t.Y + b.Y) / 2.0f), new Point(i, j)); } } } var clusters = KMeansCluster.KMeansClustering(blobs.Select(x => x.CenterOfGravity).ToList(), refs.Keys.ToList(), 5); foreach (var cluster in clusters) { if (cluster.Points.Count(refs.ContainsKey) > 1) { Debug.WriteLine("Multiple Centers in a Cluster"); return(false); } if (!cluster.Points.Any(refs.ContainsKey)) { Debug.WriteLine("No Center in a Cluster"); return(false); } var center = cluster.Points.First(refs.ContainsKey); var pos = refs[center]; if (cluster.Points.Count == 1) { Debug.WriteLine("Point missing in cluster"); if (missing.HasValue) { return(false); } missing = pos; continue; } if (cluster.Points.Count > 2) { Debug.WriteLine("Multiple Points in a cluster"); } cluster.Points.Remove(center); #if DEBUG foreach (var point in cluster.Points) { using (var g = Graphics.FromImage(actImg)) { g.DrawString(pos.X + "," + pos.Y, new Font(FontFamily.GenericSansSerif, 8.0f), new SolidBrush(Color.Red), point.X, point.Y); g.Flush(); //Debug.WriteLine("wrote to image"); } } #endif var p = cluster.Points.First(); if (pos.X == 0) { //left var b = blobs.First(x => x.CenterOfGravity == p); List <IntPoint> rightEdge; List <IntPoint> leftEdge; bc.GetBlobsLeftAndRightEdges(b, out leftEdge, out rightEdge); //var ep = leftEdge.First(x => x.Y == (int)Math.Round(p.Y)); //p = ep; //p.Y = (float) Math.Round(leftEdge.Average(x => x.Y)); p = leftEdge.First(x => x.Y == (int)Math.Round(leftEdge.Average(y => y.Y))); } else if (pos.X == parts) { //right var b = blobs.First(x => x.CenterOfGravity == p); List <IntPoint> rightEdge; List <IntPoint> leftEdge; bc.GetBlobsLeftAndRightEdges(b, out leftEdge, out rightEdge); //var ep = rightEdge.First(x => x.Y == (int)Math.Round(p.Y)); //p.X = ep.X; p = rightEdge.First(x => x.Y == (int)Math.Round(rightEdge.Average(y => y.Y))); } if (pos.Y == 0) { //top var b = blobs.First(x => x.CenterOfGravity == p); List <IntPoint> bottomEdge; List <IntPoint> topEdge; bc.GetBlobsTopAndBottomEdges(b, out topEdge, out bottomEdge); //var ep = topEdge.First(x => x.X == (int)Math.Round(p.X)); //p = ep; //p.X = (float) topEdge.Average(x => x.X); p = topEdge.First(x => x.X == (int)Math.Round(topEdge.Average(y => y.X))); } else if (pos.Y == parts) { //bottom var b = blobs.First(x => x.CenterOfGravity == p); List <IntPoint> bottomEdge; List <IntPoint> topEdge; bc.GetBlobsTopAndBottomEdges(b, out topEdge, out bottomEdge); //var ep = bottomEdge.First(x => x.X == (int)Math.Round(p.X)); //p.Y = ep.Y; p = bottomEdge.First(x => x.X == (int)Math.Round(bottomEdge.Average(y => y.X))); } var ip = p.Round(); Grid.AddPoint(pos.X * w, pos.Y * h, ip.X, ip.Y); } return(true); }
public int SetImage(Bitmap image) { leftEdges.Clear(); rightEdges.Clear(); topEdges.Clear(); bottomEdges.Clear(); hulls.Clear(); quadrilaterals.Clear(); selectedBlobID = 0; Bitmap imageclone = AForge.Imaging.Image.Clone(image, image.PixelFormat); // create filter Median filterMedian = new Median(); // apply the filter // create filter Threshold filterThreshold = new Threshold(250); // configure filter // create filter BlobsFiltering filterBlobsFiltering = new BlobsFiltering(); filterBlobsFiltering.CoupledSizeFiltering = false; filterBlobsFiltering.MinWidth = 6; //7 filterBlobsFiltering.MinHeight = 6; //7 filterBlobsFiltering.MaxWidth = 8; //8 filterBlobsFiltering.MaxHeight = 8; //8 // apply the filter filterThreshold.ApplyInPlace(imageclone); filterBlobsFiltering.ApplyInPlace(imageclone); filterMedian.ApplyInPlace(imageclone); //this.image = AForge.Imaging.Image.Clone( image, PixelFormat.Format16bppGrayScale ); //imageclone = AForge.Imaging.Image.Clone(image); imageWidth = imageclone.Width; imageHeight = imageclone.Height; blobCounter.ProcessImage(imageclone); blobs = blobCounter.GetObjectsInformation(); center = new List <AForge.Point>(); GrahamConvexHull grahamScan = new GrahamConvexHull(); foreach (Blob blob in blobs) { List <IntPoint> leftEdge = new List <IntPoint>(); List <IntPoint> rightEdge = new List <IntPoint>(); List <IntPoint> topEdge = new List <IntPoint>(); List <IntPoint> bottomEdge = new List <IntPoint>(); // collect edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftEdge, out rightEdge); blobCounter.GetBlobsTopAndBottomEdges(blob, out topEdge, out bottomEdge); AForge.Point centering = blob.CenterOfGravity; leftEdges.Add(blob.ID, leftEdge); rightEdges.Add(blob.ID, rightEdge); topEdges.Add(blob.ID, topEdge); bottomEdges.Add(blob.ID, bottomEdge); // find convex hull List <IntPoint> edgePoints = new List <IntPoint>(); edgePoints.AddRange(leftEdge); edgePoints.AddRange(rightEdge); List <IntPoint> hull = grahamScan.FindHull(edgePoints); hulls.Add(blob.ID, hull); List <IntPoint> quadrilateral = null; // List array center of gravity center.Add(centering); // find quadrilateral // if (hull.Count < 4) { quadrilateral = new List <IntPoint>(hull); } else { quadrilateral = PointsCloud.FindQuadrilateralCorners(hull); } quadrilaterals.Add(blob.ID, quadrilateral); // shift all points for vizualization IntPoint shift = new IntPoint(1, 1); PointsCloud.Shift(leftEdge, shift); PointsCloud.Shift(rightEdge, shift); PointsCloud.Shift(topEdge, shift); PointsCloud.Shift(bottomEdge, shift); PointsCloud.Shift(hull, shift); PointsCloud.Shift(quadrilateral, shift); } double xhair = imageWidth / 2; double yhair = imageHeight / 2; if (image.PixelFormat != PixelFormat.Format24bppRgb) { //filterBlobX(516.0, 670.0); //filterBlobY(360.0, 520.0); filterBlobX(516.0, 1117.0); filterBlobY(357.0, 460.0); refPointList = new List <AForge.Point>(); //findRef(388.0, 0.5); findRef(20.0, 1.5);// findPick(refPoint.X, refPoint.Y); } //UpdatePosition(); //Invalidate(); //if (!Directory.Exists(path)) //{ // System.IO.Directory.CreateDirectory(path); //} ////file = path + DateTime.Now.ToString(datePatt); file = path + "visimg.bmp"; imageclone.Save(file); if (blobs.Length > 0) { return(blobs.Length); } else { return(0); } }
public double[] detectionGlyph(bool CalculTailleTerrain) { bool Trouve = false; double[] ratio = new double[2] { 0, 0 }; SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); BlobCounter blobCounter = new BlobCounter(); blobCounter.MinHeight = 23; blobCounter.MinWidth = 23; blobCounter.FilterBlobs = true; blobCounter.ObjectsOrder = ObjectsOrder.Size; // 4 - find all stand alone blobs blobCounter.ProcessImage(imgContour); Blob[] blobs = blobCounter.GetObjectsInformation(); // 5 - check each blob for (int i = 0, n = blobs.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); List <IntPoint> corners = null; // Test de la forme selectionnée if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { // Détection des points de coutour List <IntPoint> leftEdgePoints, rightEdgePoints, topEdgePoints, bottomEdgePoints; Line Horizontale = Line.FromPoints(new IntPoint(0, 0), new IntPoint(10, 0)); blobCounter.GetBlobsLeftAndRightEdges(blobs[i], out leftEdgePoints, out rightEdgePoints); blobCounter.GetBlobsTopAndBottomEdges(blobs[i], out topEdgePoints, out bottomEdgePoints); // calculate average difference between pixel values from outside of the // shape and from inside float diff = CalculateAverageEdgesBrightnessDifference(leftEdgePoints, rightEdgePoints, imgNB); // check average difference, which tells how much outside is lighter than // inside on the average if (diff > 20) { // Transformation de l'image reçu en un carré pour la reconnaissance QuadrilateralTransformation quadrilateralTransformation = new QuadrilateralTransformation(corners, 60, 60); UnmanagedImage glyphImage = quadrilateralTransformation.Apply(imgNB); // Filtre de contraste OtsuThreshold otsuThresholdFilter = new OtsuThreshold(); otsuThresholdFilter.ApplyInPlace(glyphImage); imgContour = glyphImage; // Reconnaissance du Glyph Glyph Gl = new Glyph(glyphImage, GlyphSize); Gl.ReconnaissanceGlyph(corners, imgNB); // Si le Glyph est valide if (Gl.getIdentifiant() > 0) { if (AutAffichage[0]) { // Coloration des contours des zones détectées UnImgReel.SetPixels(leftEdgePoints, Color.Red); UnImgReel.SetPixels(rightEdgePoints, Color.Red); UnImgReel.SetPixels(topEdgePoints, Color.Red); UnImgReel.SetPixels(bottomEdgePoints, Color.Red); } // Détection du milieu Line line = Line.FromPoints(corners[0], corners[2]); Line line2 = Line.FromPoints(corners[1], corners[3]); IntPoint intersection = (IntPoint)line.GetIntersectionWith(line2); if (AutAffichage[1]) { dessinePoint(intersection, UnImgReel, 4, Color.Yellow); } // Calcul de la rotation Line ComparasionAngle = Line.FromPoints(corners[0], corners[1]); Double rotation = (int)ComparasionAngle.GetAngleBetweenLines(Horizontale); rotation += 90 * Gl.getNbRotation(); Gl.rotation = 360 - rotation; rotation *= (Math.PI / 180.0); // Calcul d'un point en bout de pince float Taille = corners[0].DistanceTo(corners[1]); float taille = (Taille / BibliotequeGlyph.Biblioteque[Gl.getPosition()].taille) * BibliotequeGlyph.Biblioteque[Gl.getPosition()].DistancePince; int x = -(int)(System.Math.Sin(rotation) * taille); int y = -(int)(System.Math.Cos(rotation) * taille); x += (int)intersection.X; y += (int)intersection.Y; Gl.Position = new int[2] { x, y }; if (AutAffichage[2]) { dessinePoint(new IntPoint(x, y), UnImgReel, 4, Color.Cyan); } imgContour = Gl.getImage(); addGlyph(Gl); if (CalculTailleTerrain == true && Trouve == false) { Trouve = true; int tailleglyph = BibliotequeGlyph.Biblioteque[Gl.getPosition()].taille; // Pythagore pour detection taille Rectangle a = blobs[i].Rectangle; double angle = -Gl.rotation + 180; List <IntPoint> coins = new List <IntPoint>(); coins.Add(new IntPoint(100, 100)); coins.Add(new IntPoint(100, 100 + tailleglyph)); coins.Add(new IntPoint(100 + tailleglyph, 100 + tailleglyph)); coins.Add(new IntPoint(100 + tailleglyph, 100)); IntPoint Centre = new IntPoint((coins[2].X + coins[0].X) / 2, (coins[2].Y + coins[0].Y) / 2); int radius = (int)(0.5 * Math.Sqrt(coins[0].DistanceTo(coins[1]) * coins[0].DistanceTo(coins[1]) + coins[1].DistanceTo(coins[2]) * coins[1].DistanceTo(coins[2]))); double alpha = Math.Atan2(coins[0].DistanceTo(coins[1]), coins[1].DistanceTo(coins[2])) * (180 / Math.PI); double ang = 0; for (i = 0; i < 4; i++) { IntPoint tmp = coins[i]; switch (i) { case 0: ang = alpha - 180 + angle; break; case 1: ang = +angle - alpha; break; case 2: ang = +angle + alpha; break; case 3: ang = -alpha + 180 + angle; break; } ang *= (Math.PI / 180); tmp.X = (int)(Centre.X + radius * Math.Cos(ang)); tmp.Y = (int)(Centre.Y + radius * Math.Sin(ang)); coins[i] = tmp; } Rectangle r = new Rectangle(min(coins[0].X, coins[1].X, coins[2].X, coins[3].X), min(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y), max(coins[0].X, coins[1].X, coins[2].X, coins[3].X) - min(coins[0].X, coins[1].X, coins[2].X, coins[3].X), max(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y) - min(coins[0].Y, coins[1].Y, coins[2].Y, coins[3].Y)); ratio[0] = ((double)r.Width / (double)a.Width) * 1.48; ratio[1] = ((double)r.Height / (double)a.Height) * 1.48; } } } } } if (Trouve == false || ratio[0] == 0 || ratio[0] == 1 || ratio[1] == 0 || ratio[1] == 1) { return(null); } ratio[0] *= 0.7; ratio[1] *= 0.7; return(ratio); }