private double DistPToVect(Blob x, Vector vect, AForge.Point start) { vect.Normalize(); var diff = start - x.CenterOfGravity; var t = new AForge.Point((float)(diff.X * vect.X * vect.X), (float)(diff.Y * vect.Y * vect.Y)); return((diff - t).EuclideanNorm()); }
public void ChooseContour(double areaProportion, int areaMinLimit, double heightPropotion) { Bitmap result = Image.Bitmap.Invert(); List <BlobEntity> objects = result.FindBlobs(); int maxArea = -1; int maxHeight = -1; // ReSharper disable PossibleLossOfFraction AForge.Point imageCenter = new AForge.Point(result.Width / 2, result.Height / 2); int targetObjectIndex = -1; // for (int i = 0; i < objects.Count; i++) { int currentArea = objects[i].Blob.Area; if (currentArea > maxArea) { maxArea = currentArea; targetObjectIndex = i; } int currentHeight = objects[i].Blob.Rectangle.Height; if (currentHeight > maxHeight) { maxHeight = currentHeight; } } ; int limitArea = Math.Min((int)(maxArea * areaProportion), areaMinLimit); int limitHeight = (int)(maxHeight * heightPropotion); double minDistanceToCenter = result.Height + result.Width; //Triangle inequality:) for (int i = 0; i < objects.Count; i++) { if ((objects[i].Blob.Area >= limitArea) && (objects[i].Blob.Rectangle.Height >= limitHeight)) { AForge.Point objectCenter = objects[i].Blob.CenterOfGravity; double distToCenter = Math.Sqrt(Math.Pow(objectCenter.X - imageCenter.X, 2) + Math.Pow(objectCenter.X - imageCenter.X, 2)); if (distToCenter < minDistanceToCenter) { minDistanceToCenter = distToCenter; targetObjectIndex = i; } } } _targetObject = new ElastoBlob(objects[targetObjectIndex]); for (int i = 0; i < objects.Count; i++) { if (i != targetObjectIndex) { Image.FillBlob(objects[i].Blob, SimpleGrayImage.WhiteBrightness); } } }
private Point GetCrossingPoint(AForge.Point s1, Vector v1, Point s2, Vector v2) { if ((v2.Y == 0 && v1.Y == 0) || ((v2.Y != 0 && v1.Y != 0 && (v2.X / v2.Y == v1.X / v1.Y)))) { throw new ArgumentException("Doesn't cross"); } var r = (s1.X * v1.Y - s1.Y * v1.X + s2.Y * v1.X - s2.X * v1.Y) / (v2.Y * v1.X - v1.Y * v2.X); return(new Point((int)r, (int)((s1.X - s2.X + r * v2.X) / v1.X))); }
/// <summary> /// Checks if the point is in the Grid /// </summary> /// <param name="centerOfGravity"></param> /// <returns></returns> public bool Contains(AForge.Point centerOfGravity) { return(Contains(new Point((int)centerOfGravity.X, (int)centerOfGravity.Y))); }
private bool IsNextTo(AForge.Point p1, Point p2, int rownr, int colnr, double maxDist) { return(Math.Abs(p1.X - p2.X) < PredictRowDistance(colnr) * maxDist && Math.Abs(p1.Y - p2.Y) < PredictColumnDistance(rownr) * maxDist); }
private bool IsNextTo(AForge.Point p1, AForge.Point p2, int rownr, int colnr, double maxDist) { return(IsNextTo(p1, new Point((int)p2.X, (int)p2.Y), rownr, colnr, maxDist)); }
private void altProcess(Bitmap bm, int level) { var img = new Image <Bgr, byte>(bm); if (level == 1) { var resImage = new Image <Bgr, byte>(img.Bitmap); CvInvoke.BilateralFilter(resImage, img, 30, 80, 80); CvInvoke.MedianBlur(img, img, 5); resImage = img; } else if (level == 2) { CvInvoke.MedianBlur(img, img, 5); var resImage = new Image <Bgr, byte>(img.Bitmap); CvInvoke.BilateralFilter(resImage, img, 25, 75, 75); CvInvoke.Blur(img, img, new Size(5, 5), new Point(0, 0)); } var grayimage = new Image <Gray, byte>(bm); CvInvoke.CvtColor(img, grayimage, ColorConversion.Bgr2Gray); BlackBG(grayimage); Console.WriteLine("Filtering done"); var cannyThreshold = GetKMeansThreshold(grayimage); label2.Text = cannyThreshold.ToString(); Thresholding(grayimage, cannyThreshold); Console.WriteLine("Canny threshold using KMEANS found " + cannyThreshold); //Convert the image to grayscale and filter out the noise var cannyEdges = new UMat(); Console.WriteLine("Canny threshold using KMEANS found " + cannyThreshold); var uimage = new UMat(); CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray); CvInvoke.Canny(uimage, cannyEdges, cannyThreshold, cannyThreshold); BlobCounter blobCounter = new BlobCounter( ); if (level == 1) { blobCounter.FilterBlobs = true; blobCounter.MinHeight = 25; blobCounter.MinWidth = 25; blobCounter.ProcessImage(cannyEdges.Bitmap); } else { blobCounter.ProcessImage(grayimage.ToBitmap()); } //blobCounter.ProcessImage(grayimage.ToBitmap()); Blob[] blobs = blobCounter.GetObjectsInformation( ); SimpleShapeChecker shapeChecker = new SimpleShapeChecker(); var triangleList = new List <Triangle2DF>(); var boxList = new List <RotatedRect>(); var circleList = new List <CircleF>(); Bitmap newBM = new Bitmap(img.Bitmap); Graphics g = Graphics.FromImage(newBM); Pen redPen = new Pen(Color.Red, 2); Pen yellowPen = new Pen(Color.Yellow, 2); Pen greenPen = new Pen(Color.Green, 2); Pen bluePen = new Pen(Color.Blue, 2); for (int i = 0, n = blobs.Length; i < n; i++) { List <IntPoint> edgePoints = blobCounter.GetBlobsEdgePoints(blobs[i]); AForge.Point center; float radius; if (shapeChecker.IsCircle(edgePoints, out center, out radius)) { //g.DrawEllipse(bluePen, // (float)(center.X - radius), (float)(center.Y - radius), // (float)(radius * 2), (float)(radius * 2)); circleList.Add(new CircleF(new PointF(center.X, center.Y), radius)); } else { List <IntPoint> corners; if (edgePoints.Count > 1) { if (shapeChecker.IsQuadrilateral(edgePoints, out corners)) { System.Console.WriteLine(corners.Count); if (shapeChecker.CheckPolygonSubType(corners) == PolygonSubType.Square || shapeChecker.CheckPolygonSubType(corners) == PolygonSubType.Rectangle) { IntPoint minXY, maxXY; PointsCloud.GetBoundingRectangle(corners, out minXY, out maxXY); AForge.Point c = PointsCloud.GetCenterOfGravity(corners); //g.DrawPolygon(greenPen, ToPointsArray(corners)); boxList.Add(new RotatedRect(new PointF(c.X, c.Y), new SizeF(maxXY.X - minXY.X, maxXY.Y - minXY.Y), 0)); } } else { corners = PointsCloud.FindQuadrilateralCorners(edgePoints); if (corners.Count == 3) { Triangle2DF tri = new Triangle2DF(new PointF(corners[0].X, corners[0].Y), new PointF(corners[1].X, corners[1].Y), new PointF(corners[2].X, corners[2].Y)); triangleList.Add(tri); //g.DrawPolygon(yellowPen, ToPointsArray(corners)); } //g.DrawPolygon(redPen, ToPointsArray(corners)); } } } } Console.WriteLine("boxes " + boxList.Count); Console.WriteLine("triangles " + triangleList.Count); Console.WriteLine("circles " + circleList.Count); redPen.Dispose(); greenPen.Dispose(); bluePen.Dispose(); yellowPen.Dispose(); //g.Dispose(); resPicBox.Image = newBM; CircleF[] circles = circleList.ToArray(); var cList = circles.ToList(); FilterSame(boxList, triangleList, cList, img.Width * img.Height); circles = cList.ToArray(); var points = new List <PointF>(); var Image = img.CopyBlank(); foreach (var triangle in triangleList) { Image.Draw(triangle, new Bgr(Color.Red), 3); points.Add(triangle.Centeroid); } foreach (var box in boxList) { Image.Draw(box, new Bgr(Color.Blue), 3); points.Add(box.Center); } foreach (var circle in circles) { Image.Draw(circle, new Bgr(Color.DarkCyan), 3); points.Add(circle.Center); } var listPoints = SortPoints(points, img); for (var i = 0; i < listPoints.Length; i++) { Console.WriteLine(listPoints[i].X.ToString() + " " + listPoints[i].Y.ToString()); } System.Console.WriteLine("Points sorted, num of objects " + listPoints.Length.ToString()); resPicBox.Image = (Image + img).ToBitmap(); if (listPoints.Length > 3) { var bezSegList = InterpolatePointWithBeizerCurves(listPoints.ToList <PointF>()); var gr = Graphics.FromImage(resPicBox.Image); var p = new Pen(Color.Red); foreach (BeizerCurveSegment seg in bezSegList) { var bezierList = GetBez(new PointF[] { seg.StartPoint, seg.FirstControlPoint, seg.SecondControlPoint, seg.EndPoint }); for (var i = 0; i < bezierList.Length - 1; i++) { gr.DrawLine(p, bezierList[i], bezierList[i + 1]); } } } else { var gr = Graphics.FromImage(resPicBox.Image); var p = new Pen(Color.Red); for (var i = 0; i < listPoints.Length - 1; i++) { gr.DrawLine(p, listPoints[i], listPoints[i + 1]); } } //var bezierList = GetBezierCurve1(listPoints); }
/// <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) { var blobs = new Dictionary <Blob, Point>(new BlobComparer()); 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()) { blobs.Add(blob, new Point(-1, -1)); } var actVect = new Vector(Grid.BottomLeft.X - Grid.TopLeft.X, Grid.BottomLeft.Y - Grid.TopLeft.Y); var actStart = new AForge.Point(Grid.TopLeft.X, Grid.TopLeft.Y); for (int i = offset; i < VisibleRows; i += 2) { var nb = blobs.Where(x => x.Value.X == -1 && x.Value.Y == -1) .Select(x => x.Key) .OrderBy(x => DistPToVect(x, actVect, actStart)) .ToList(); if (nb.Count > Columncount) { nb = nb.GetRange(0, Columncount); } var nearby = nb.ToDictionary(x => x, x => DistPToVect(x, actVect, actStart)); if (nearby.Count == 0) { continue; } var stddev = StdDev(nearby.Values.ToList()); var mean = nearby.Values.Average(); var toRemove = new List <Blob>(); foreach (var blob in nearby) { if (blob.Value > mean + stddev) { toRemove.Add(blob.Key); } else { var t = blobs[blob.Key]; t.X = i; blobs[blob.Key] = t; } } foreach (var blob in toRemove) { nearby.Remove(blob); } var top = GetCrossingPoint(actStart, actVect, Grid.BottomLeft, new Vector(Grid.BottomRight.X - Grid.BottomLeft.X, Grid.BottomRight.Y - Grid.BottomLeft.Y)); var height = top.Y - GetCrossingPoint(actStart, actVect, Grid.TopLeft, new Vector(Grid.TopRight.X - Grid.TopLeft.X, Grid.TopRight.Y - Grid.TopLeft.Y)).Y; var pred = height / Math.Round(VisibleColumns / 2.0); foreach (var blob in nearby) { var t = blobs[blob.Key]; t.Y = (int)Math.Floor((blob.Key.CenterOfGravity.Y - top.Y) / pred) + offset; blobs[blob.Key] = t; } actStart = nearby.First(x => x.Key.CenterOfGravity.Y == nearby.Keys.Min(y => y.CenterOfGravity.Y)).Key.CenterOfGravity; var bott = nearby.First(x => x.Key.CenterOfGravity.Y == nearby.Keys.Max(y => y.CenterOfGravity.Y)).Key.CenterOfGravity; actVect = new Vector(bott.X - actStart.X, bott.Y - actStart.Y); } foreach (var blob in blobs) { #if DEBUG using (var g = Graphics.FromImage(actImg)) { g.DrawString(blob.Value.X + "," + blob.Value.Y, new Font(FontFamily.GenericSansSerif, 8.0f), new SolidBrush(Color.White), blob.Key.CenterOfGravity.X, blob.Key.CenterOfGravity.Y); g.Flush(); //Debug.WriteLine("wrote to image"); } #endif var corners = PointsCloud.FindQuadrilateralCorners(b.GetBlobsEdgePoints(blob.Key)); var xPos = blob.Value.X; var yPos = blob.Value.Y; 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); } } }