public static Point[] GetAnchorsFOV(Image <Gray, byte> ImgGerber, Rectangle ROI, Size FOV, StartPoint StartPoint = StartPoint.TOP_LEFT) { ImgGerber.ROI = ROI; Point[] Anchors = null; Size fovTruncate = new Size(FOV.Width - 64, FOV.Height - 64); using (Image <Gray, byte> img = ImgGerber.Copy()) { ExtremePoints extreme = FindExtremeImage(img); Point[][] AnchorsArr = GetAnchorsX(img, extreme, fovTruncate, FOV); Anchors = Sort(AnchorsArr, StartPoint); } if (ROI != null) { for (int i = 0; i < Anchors.Length; i++) { Anchors[i].X += ROI.X; Anchors[i].Y += ROI.Y; } } ImgGerber.ROI = Rectangle.Empty; return(Anchors); }
private static ExtremePoints FindExtremeImage(Image <Gray, byte> ImgInput) { ExtremePoints points = new ExtremePoints(); points.Top = new Point(0, (int)Math.Pow(2, 16)); points.Bot = new Point(0, 0); points.Left = new Point((int)Math.Pow(2, 16), 0); points.Right = new Point(0, 0); using (VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint()) { CvInvoke.FindContours(ImgInput, contours, null, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxSimple); for (int i = 0; i < contours.Size; i++) { Point[] p = contours[i].ToArray(); var sortx = p.OrderBy(x => x.X); var sorty = p.OrderBy(y => y.Y); points.Top = sorty.ElementAt(0).Y < points.Top.Y ? sorty.ElementAt(0) : points.Top; points.Bot = sorty.ElementAt(p.Length - 1).Y > points.Bot.Y ? sorty.ElementAt(p.Length - 1) : points.Bot; points.Left = sortx.ElementAt(0).X < points.Left.X ? sortx.ElementAt(0) : points.Left; points.Right = sortx.ElementAt(p.Length - 1).X > points.Right.X ? sortx.ElementAt(p.Length - 1) : points.Right; } } return(points); }
private static Point[][] GetAnchorsX(Image <Gray, byte> Img, ExtremePoints Extreme, Size FOVTruncate, Size FOVNormal) { ArrayList listAnchors = new ArrayList(); int stx = Extreme.Left.X, sty = Extreme.Top.Y; int width = Extreme.Right.X - Extreme.Left.X; int height = Extreme.Bot.Y - Extreme.Top.Y; int step = height % FOVTruncate.Height == 0 ? height / FOVTruncate.Height : height / FOVTruncate.Height + 1; using (Image <Gray, byte> img = Img.Copy()) { for (int i = 0; i < step; i++) { ArrayList anchors = new ArrayList(); int x = stx; int y = i * FOVTruncate.Height + sty; int w = width; int h = FOVTruncate.Height; Rectangle ROINormal = new Rectangle(x, y, w, h); Rectangle ROIExtened = new Rectangle(x, y, w, h * 2); if (y + h > sty + height) { ROINormal = new Rectangle(x, y, w, sty + height - y); } if (y + 2 * h > sty + height) { ROIExtened = new Rectangle(x, y, w, sty + height - y); } img.ROI = ROINormal; using (Image <Gray, byte> tempImg = img.Copy()) { while (true) { int count = CvInvoke.CountNonZero(tempImg); if (count == 0) { break; } Rectangle fov = Rectangle.Empty; Point anchor = new Point(); ExtremePoints extROI = FindExtremeImage(tempImg); Rectangle tempRect = new Rectangle(extROI.Left.X, 0, FOVTruncate.Width, FOVTruncate.Height); if (tempRect.X + tempRect.Width > width) { tempRect = new Rectangle(tempRect.X, tempRect.Y, width - tempRect.X, tempRect.Height); } if (tempRect.Y + tempRect.Height > height) { tempRect = new Rectangle(tempRect.X, tempRect.Y, tempRect.Width, height - tempRect.Y); } tempImg.ROI = tempRect; extROI = FindExtremeImage(tempImg); tempImg.ROI = Rectangle.Empty; tempRect = new Rectangle(tempRect.X, extROI.Top.Y, tempRect.Width, tempRect.Height); img.ROI = Rectangle.Empty; img.ROI = ROIExtened; if (tempRect.X + tempRect.Width > img.Width) { tempRect = new Rectangle(tempRect.X, tempRect.Y, img.Width - tempRect.X, tempRect.Height); } if (tempRect.Y + tempRect.Height > img.Height) { tempRect = new Rectangle(tempRect.X, tempRect.Y, tempRect.Width, img.Height - tempRect.Y); } using (Image <Gray, byte> tempimgfindAnchor = img.Copy()) { tempimgfindAnchor.ROI = tempRect; extROI = FindExtremeImage(tempimgfindAnchor); int top = extROI.Top.Y; int bot = extROI.Bot.Y; int left = extROI.Left.X; int right = extROI.Right.X; anchor = new Point(left + (right - left + 1) / 2, top + (bot - top + 1) / 2); anchor.X += tempRect.X; anchor.Y += tempRect.Y; fov = new Rectangle(anchor.X - FOVTruncate.Width / 2, anchor.Y - FOVTruncate.Height / 2, FOVTruncate.Width, FOVTruncate.Height); } CvInvoke.Rectangle(img, fov, new MCvScalar(0), -1); CvInvoke.Rectangle(tempImg, fov, new MCvScalar(0), -1); //fov = new Rectangle(fov.X + x, fov.Y + y, fov.Width, fov.Height); // add condition anchor.X += x; anchor.Y += y; if (anchor.X + FOVNormal.Width / 2 > Img.Width - 1) { anchor.X -= (anchor.X + FOVNormal.Width / 2) - (Img.Width - 1); } if (anchor.Y + FOVNormal.Height / 2 > Img.Height - 1) { anchor.Y -= (anchor.Y + FOVNormal.Height / 2) - (Img.Height - 1); } if (anchor.X - FOVNormal.Width / 2 < 0) { anchor.X += FOVNormal.Width / 2 - anchor.X; } if (anchor.Y - FOVNormal.Height / 2 < 0) { anchor.Y += FOVNormal.Height / 2 - anchor.Y; } anchors.Add(anchor); } } Point[] fovs = (Point[])anchors.ToArray(typeof(Point)); listAnchors.Add(fovs); } } Point[][] bestAnchors = (Point[][])listAnchors.ToArray(typeof(Point[])); return(bestAnchors); }