public static Shapes.Thing FindClosest(VideoProcessing vp, Shapes.ShapeTypes type, double FindTolerance, int retries, string templatefilename = null, double threshold = -1) { while (retries-- > 0) { Global.DoBackgroundWork(); //for (int i = 0; i < 3; i++) vp.GetMeasurementFrame(); //skip 10 frames Shapes.Thing thing = null; switch (type) { case Shapes.ShapeTypes.Circle: thing = GetClosestCircle(vp, FindTolerance); break; case Shapes.ShapeTypes.Fiducial: var things = FindTemplates(vp, templatefilename, threshold); thing = GetClosest(GetWithin(things, FindTolerance)); break; case Shapes.ShapeTypes.Rectangle: thing = GetSmallestCenteredRectangle(FindRectangles(vp)); break; default: Global.Instance.DisplayText("detection of " + type + " not yet supported", Color.Red); break; } if (thing != null) { return(thing); } } return(null); }
private Bitmap DrawRectanglesFunct(Bitmap image, VideoProcessing vp) { var rects = VideoDetection.FindRectangles(vp, image); if (rects.Count == 0) { return(image); } var rect2 = VideoDetection.GetSmallestCenteredRectangle(rects); try { using (Image <Bgr, Byte> img = new Image <Bgr, byte>(image)) { foreach (var rect in rects) { img.DrawPolyline(PointFToPoint(ToRotatedRectangle(rect)), true, new Bgr(Color.Red), 2); } if (rect2 != null) { img.DrawPolyline(PointFToPoint(ToRotatedRectangle(rect2)), true, new Bgr(Color.Green), 5); img.Draw(new Cross2DF(rect2.ToPartLocation().ToPointF(), 20, 20), new Bgr(Color.Blue), 2); } image = img.ToBitmap(); } } catch { } return(image); }
/// <summary> /// This function will take a bitmap image and find the locations of a template image in the file for a given threhsold /// </summary> /// <param name="image">Bitmap of image to look at</param> /// <param name="template_filename">File containg template image</param> /// <returns>imagefinder object</returns> public static List <Shapes.Fiducal> FindTemplates(VideoProcessing vp, Bitmap image, string template_filename, double threshold) { if (!File.Exists(template_filename)) { return(new List <Shapes.Fiducal>()); } Image <Bgr, Byte> img = new Image <Bgr, byte>(image); if (!templateCache.ContainsKey(template_filename)) { Image <Bgr, Byte> templ1 = new Image <Bgr, byte>(template_filename); Image <Bgr, Byte> templ2 = new Image <Bgr, byte>(templ1.Height, templ1.Width); CvInvoke.cvTranspose(templ1.Ptr, templ2.Ptr); templateCache.Add(template_filename, templ1); rotatedTemplateCache.Add(template_filename, templ2); } ImageFinder imageFinder = new ImageFinder(img, threshold); imageFinder.FindImage(templateCache[template_filename]); imageFinder.FindImage(rotatedTemplateCache[template_filename]); var ret = imageFinder.Points.Select(x => new Shapes.Fiducal(x.X, x.Y)).ToList(); SetVideoProcessing(ret, vp); return(ret); }
// Sorting Routines ================================ public static void SetVideoProcessing <T>(List <T> list, VideoProcessing vp) where T : Shapes.Thing { list.RemoveAll(x => x == null); foreach (var x in list) { x.videoProcessing = vp; } }
public static List <Shapes.Rectangle> FindRectangles(VideoProcessing vp, Bitmap frame) { List <Shapes.Rectangle> rects = new List <Shapes.Rectangle>(); using (Image <Bgr, Byte> img = new Image <Bgr, byte>(frame)) { // double cannyThresholdLinking = 120.0; // double cannyThreshold = 180.0; //Convert the image to grayscale and filter out the noise Image <Gray, Byte> gray = img.Convert <Gray, Byte>().PyrDown().PyrUp(); //Image<Gray, Byte> cannyEdges = gray.Canny(cannyThreshold, cannyThresholdLinking); using (MemStorage storage = new MemStorage()) { //allocate storage for contour approximation Contour <System.Drawing.Point> contours = gray.FindContours(CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, RETR_TYPE.CV_RETR_LIST, storage); for (; contours != null; contours = contours.HNext) { Contour <System.Drawing.Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage); if (currentContour.Area > 250) //only consider contours with area greater than 250 { if (currentContour.Total == 4) //The contour has 4 vertices. { #region determine if all the angles in the contour are within [80, 100] degree bool isRectangle = true; System.Drawing.Point[] pts = currentContour.ToArray(); LineSegment2D[] edges = PointCollection.PolyLine(pts, true); for (int i = 0; i < edges.Length; i++) { double angle = Math.Abs(edges[(i + 1) % edges.Length].GetExteriorAngleDegree(edges[i])); if (angle < 80 || angle > 100) { isRectangle = false; break; } } #endregion if (isRectangle) { var box = currentContour.GetMinAreaRect(); Shapes.Rectangle r = new Shapes.Rectangle(box.center.X, box.center.Y, box.angle); r.Height = box.size.Height; r.Width = box.size.Width; rects.Add(r); } } } } } } //ensure we dont have massive rectangles rects = rects.Where(x => (x.Height < .8 * vp.FrameSize.Height && x.Width < .8 * vp.FrameSize.Width)).ToList(); SetVideoProcessing(rects, vp); return(rects); }
public static Shapes.Circle GetClosestAverageCircle(VideoProcessing vp, double tolerance, double retries) { List <Shapes.Circle> circles = new List <Shapes.Circle>(); while (retries-- > 0) { circles.Add(GetClosestCircle(vp, tolerance)); } return(AverageLocation(circles)); }
// ========================================================= private void DrawFiducialFunct(ref Bitmap image, VideoProcessing vp) { MarkA.Clear(); var fids = VideoDetection.FindTemplates(vp, image); foreach (var f in fids) { f.ToScreenResolution(); } MarkA.AddRange(fids.Select(x => x.ToPartLocation().ToPointF()).ToArray()); }
// ========================================================= private void DrawCirclesFunct(Bitmap bitmap, VideoProcessing vp) { List <Shapes.Circle> Circles = VideoDetection.FindCircles(vp, bitmap); using (Graphics g = Graphics.FromImage(bitmap)) using (Pen pen = new Pen(Color.DarkOrange, 2)) for (int i = 0, n = Circles.Count; i < n; i++) { Circles[i].ToRawResolution(); g.DrawEllipse(pen, (float)(Circles[i].X - Circles[i].Radius), (float)(Circles[i].Y - Circles[i].Radius), (float)(Circles[i].Radius * 2), (float)(Circles[i].Radius * 2)); } }
public static PartLocation Convert(VideoProcessing videoProcessing, PartLocation p, PointMode fromMode, PointMode toMode) { Thing t = new Thing(p, fromMode); t.videoProcessing = videoProcessing; switch (toMode) { case PointMode.MM: return(t.ToMMResolution().ToPartLocation()); case PointMode.Raw: return(t.ToRawResolution().ToPartLocation()); case PointMode.Screen: return(t.ToScreenResolution().ToPartLocation()); case PointMode.ScreenUnzoomed: return(t.ToScreenUnzoomedResolution().ToPartLocation()); } return(null); }
public static void DoNeedleErrorMeasurement(VideoProcessing vp) { var cnc = Global.Instance.cnc; var originalLocation = cnc.XYALocation; PartLocation testLocation = Global.GoTo("Up Camera"); cnc.Zdown(Properties.Settings.Default.focus_height, true); // setup camera vp.SetFunctionsList("Needle"); vp.s.FindCircles = true; vp.s.Draw1mmGrid = true; var Needle = Global.Instance.needle; List <PartLocation> offsetError = new List <PartLocation>(); for (int i = 0; i <= 360; i += 45) { testLocation.A = i; var pp = testLocation - Needle.NeedleOffset; Needle.Move_m(pp); // move to target // mark erro var circle = VideoDetection.GetClosestCircle(vp, 10); if (circle != null) { vp.MarkA.Add(circle.ToScreenResolution().ToPartLocation().ToPointF()); circle.ToMMResolution(); offsetError.Add(circle.ToPartLocation()); } Thread.Sleep(500); //wait 1 second } Global.Instance.mainForm.ShowSimpleMessageBox("Upcamera offset Error is " + PartLocation.Average(offsetError) + "\nMax Error is " + PartLocation.MaxValues(offsetError)); cnc.Zup(); cnc.CNC_XYA(originalLocation); //revert to previous state vp.Reset(); }
public static void DoNeedleErrorMeasurement(VideoProcessing vp) { var cnc = Global.Instance.cnc; var originalLocation = cnc.XYALocation; PartLocation testLocation = Global.GoTo("Up Camera"); cnc.Zdown(Properties.Settings.Default.focus_height, true); // setup camera vp.SetFunctionsList("Needle"); vp.s.FindCircles = true; vp.s.Draw1mmGrid = true; var Needle = Global.Instance.needle; List<PartLocation> offsetError = new List<PartLocation>(); for (int i = 0; i <= 360; i += 45) { testLocation.A = i; var pp = testLocation - Needle.NeedleOffset; Needle.Move_m(pp); // move to target // mark erro var circle = VideoDetection.GetClosestCircle(vp, 10); if (circle != null) { vp.MarkA.Add(circle.ToScreenResolution().ToPartLocation().ToPointF()); circle.ToMMResolution(); offsetError.Add(circle.ToPartLocation()); } Thread.Sleep(500); //wait 1 second } Global.Instance.mainForm.ShowSimpleMessageBox("Upcamera offset Error is " + PartLocation.Average(offsetError) + "\nMax Error is " + PartLocation.MaxValues(offsetError)); cnc.Zup(); cnc.CNC_XYA(originalLocation); //revert to previous state vp.Reset(); }
/// <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 void DrawCirclesFunct(Bitmap bitmap, VideoProcessing vp) { List<Shapes.Circle> Circles = VideoDetection.FindCircles(vp, bitmap); using (Graphics g = Graphics.FromImage(bitmap)) using (Pen pen = new Pen(Color.DarkOrange, 2)) for (int i = 0, n = Circles.Count; i < n; i++) { Circles[i].ToRawResolution(); g.DrawEllipse(pen, (float)(Circles[i].X - Circles[i].Radius), (float)(Circles[i].Y - Circles[i].Radius), (float)(Circles[i].Radius * 2), (float)(Circles[i].Radius * 2)); } }
public static Shapes.Circle GetClosestCircle(VideoProcessing vp, double tolerance) { Global.Instance.DisplayText("GetClosestCircle(" + tolerance + ")", Color.Orange); return(GetClosest(GetWithin(FindCircles(vp), tolerance))); }
/************** These functions are intelligent about their resolution/offset and can be changed dynamically *****/ public static List <Shapes.Circle> FindCircles(VideoProcessing vp) { return(FindCircles(vp, vp.GetMeasurementFrame())); }
public static List <Shapes.Component> FindComponents(VideoProcessing vp, Bitmap bitmap) { // Locating objects BlobCounter blobCounter = new BlobCounter(); blobCounter.FilterBlobs = true; blobCounter.MinHeight = 8; blobCounter.MinWidth = 8; blobCounter.ProcessImage(bitmap); Blob[] blobs = blobCounter.GetObjectsInformation(); // create convex hull searching algorithm GrahamConvexHull hullFinder = new GrahamConvexHull(); ClosePointsMergingOptimizer optimizer1 = new ClosePointsMergingOptimizer(); FlatAnglesOptimizer optimizer2 = new FlatAnglesOptimizer(); List <Shapes.Component> Components = new List <Shapes.Component>(); // process each blob foreach (Blob blob in blobs) { List <IntPoint> leftPoints, rightPoints, edgePoints = new List <IntPoint>(); if ((blob.Rectangle.Height > 400) && (blob.Rectangle.Width > 600)) { break; // The whole image could be a blob, discard that } // get blob's edge points blobCounter.GetBlobsLeftAndRightEdges(blob, out leftPoints, out rightPoints); edgePoints.AddRange(leftPoints); edgePoints.AddRange(rightPoints); // blob's convex hull List <IntPoint> Outline = hullFinder.FindHull(edgePoints); optimizer1.MaxDistanceToMerge = 4; optimizer2.MaxAngleToKeep = 170F; Outline = optimizer2.OptimizeShape(Outline); Outline = optimizer1.OptimizeShape(Outline); // find Longest line segment float dist = 0; LineSegment Longest = new LineSegment(Outline[0], Outline[1]); LineSegment line; dist = Longest.Length; int LongestInd = 0; for (int i = 1; i < Outline.Count; i++) { if (i != Outline.Count - 1) { line = new LineSegment(Outline[i], Outline[i + 1]); } else { // last iteration if (Outline[i] == Outline[0]) { break; } line = new LineSegment(Outline[i], Outline[0]); } if (line.Length > dist) { Longest = line; dist = line.Length; LongestInd = i; } } // Get the center point of it Point LongestCenter = new Point(); LongestCenter.X = (float)Math.Round((Longest.End.X - Longest.Start.X) / 2.0 + Longest.Start.X); LongestCenter.Y = (float)Math.Round((Longest.End.Y - Longest.Start.Y) / 2.0 + Longest.Start.Y); Point NormalStart = new Point(); Point NormalEnd = new Point(); // Find normal: // start= longest.start rotated +90deg relative to center // end= longest.end rotated -90deg and relative to center // If you rotate point (px, py) around point (ox, oy) by angle theta you'll get: // p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox // p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy // cos90 = 0, sin90= 1 => // p'x= -(py-oy) + ox= oy-py+ox, p'y= (px-ox)+ oy NormalStart.X = LongestCenter.Y - Longest.Start.Y + LongestCenter.X; NormalStart.Y = (Longest.Start.X - LongestCenter.X) + LongestCenter.Y; // cos-90=0, sin-90= -1 => // p'x= (py-oy) + ox // p'y= -(px-ox)+oy= ox-px+oy NormalEnd.X = (Longest.Start.Y - LongestCenter.Y) + LongestCenter.X; NormalEnd.Y = LongestCenter.X - Longest.Start.X + LongestCenter.Y; // Make line out of the points Line Normal = Line.FromPoints(NormalStart, NormalEnd); // Find the furthest intersection to the normal (skip the Longest) Point InterSection = new Point(); Point Furthest = new Point(); bool FurhtestAssinged = false; LineSegment seg; dist = 0; for (int i = 0; i < Outline.Count; i++) { if (i == LongestInd) { continue; } if (i != Outline.Count - 1) { seg = new LineSegment(Outline[i], Outline[i + 1]); } else { // last iteration if (Outline[i] == Outline[0]) { break; } seg = new LineSegment(Outline[i], Outline[0]); } if (seg.GetIntersectionWith(Normal) == null) { continue; } InterSection = (Point)seg.GetIntersectionWith(Normal); if (InterSection.DistanceTo(LongestCenter) > dist) { Furthest = InterSection; FurhtestAssinged = true; dist = InterSection.DistanceTo(LongestCenter); } } // Check, if there is a edge point that is close to the normal even further Point fPoint = new Point(); for (int i = 0; i < Outline.Count; i++) { fPoint.X = Outline[i].X; fPoint.Y = Outline[i].Y; if (Normal.DistanceToPoint(fPoint) < 1.5) { if (fPoint.DistanceTo(LongestCenter) > dist) { Furthest = fPoint; FurhtestAssinged = true; dist = fPoint.DistanceTo(LongestCenter); } } } Point ComponentCenter = new Point(); if (FurhtestAssinged) { // Find the midpoint of LongestCenter and Furthest: This is the centerpoint of component ComponentCenter.X = (float)Math.Round((LongestCenter.X - Furthest.X) / 2.0 + Furthest.X); ComponentCenter.Y = (float)Math.Round((LongestCenter.Y - Furthest.Y) / 2.0 + Furthest.Y); // Alignment is the angle of longest double Alignment; if (Math.Abs(Longest.End.X - Longest.Start.X) < 0.001) { Alignment = 0; } else { Alignment = Math.Atan((Longest.End.Y - Longest.Start.Y) / (Longest.End.X - Longest.Start.X)); Alignment = Alignment * 180.0 / Math.PI; // in deg. } Components.Add(new Shapes.Component(ComponentCenter, Alignment, Outline, Longest, NormalStart, NormalEnd)); } } SetVideoProcessing(Components, vp); return(Components); }
private Bitmap DrawRectanglesFunct(Bitmap image, VideoProcessing vp ) { var rects = VideoDetection.FindRectangles(vp, image); if (rects.Count == 0) return image; var rect2 = VideoDetection.GetSmallestCenteredRectangle(rects); try { using (Image<Bgr, Byte> img = new Image<Bgr, byte>(image)) { foreach (var rect in rects) { img.DrawPolyline(PointFToPoint(ToRotatedRectangle(rect)), true, new Bgr(Color.Red), 2); } if (rect2 != null) { img.DrawPolyline(PointFToPoint(ToRotatedRectangle(rect2)), true, new Bgr(Color.Green), 5); img.Draw(new Cross2DF(rect2.ToPartLocation().ToPointF(), 20, 20), new Bgr(Color.Blue), 2); } image = img.ToBitmap(); } } catch { } return image; }
private static PartLocation DoCameraCalibration(VideoProcessing vp, PartLocation movement) { var cnc = Global.Instance.cnc; var distance = new List<PartLocation>(); var pixels = new List<PartLocation>(); // turn on slack compensation var savedSlackCompensation = cnc.SlackCompensation; cnc.SlackCompensation = true; var startingPos = cnc.XYLocation; startingPos.A = 0; vp.MarkA.Clear(); for (int i = -4; i < 5; i++) { //move var newLocation = startingPos + (i * movement); if (!cnc.CNC_XYA(newLocation)) return null; //try 5 times to find a circle List<Shapes.Circle> circles = new List<Shapes.Circle>(); for (int tries = 5; tries > 0 && circles.Count == 0; tries--) circles = VideoDetection.FindCircles(vp); if (circles.Count == 0) continue; //not found, move and try again //find largest circle of the bunch var circle = circles.Aggregate((c, d) => c.Radius > d.Radius ? c : d); //find largest circle if we have multiple // var circlePL = (1 / zoom) * circle.ToPartLocation(); //compensate for zoom circle.ToScreenUnzoomedResolution(); distance.Add(newLocation); pixels.Add(circle.ToPartLocation()); vp.MarkA.Add(circle.Clone().ToScreenResolution().ToPartLocation().ToPointF()); //DisplayText(String.Format("Actual Loc = {0}\t Measured Loc = {1}", newLocation, UpCamera.PixelsToActualLocation(circlePL)), Color.Blue); } double XmmPerPixel = 0, YmmPerPixel = 0; if (pixels.Count < 2) { Global.Instance.mainForm.ShowMessageBox("Unable To Detect Circles", "Try to adjust upcamera processing to see circles, and ensure upcamera needle position is correctly configured", MessageBoxButtons.OK); } else { // Do regression on X and Y var Xs = pixels.Select(xx => xx.X).ToArray(); var Ys = distance.Select(xx => xx.X).ToArray(); var result = SimpleRegression.Fit(Xs, Ys); XmmPerPixel = result.Item2; Xs = pixels.Select(xx => xx.Y).ToArray(); Ys = distance.Select(xx => xx.Y).ToArray(); result = SimpleRegression.Fit(Xs, Ys); YmmPerPixel = result.Item2; Global.Instance.DisplayText(String.Format("{0} Xmm/pixel {1} Ymm/pixel", XmmPerPixel, YmmPerPixel), Color.Purple); // Now move to the center /* need to get gotolocation upcamera working still double X, Y; //error offset GotoUpCamPosition_button_Click(null, null); for (int tries = 5; tries > 0; tries--) { if (GoToLocation_m(UpCamera, Shapes.ShapeTypes.Circle, 1.8, 0.5, out X, out Y)) { Properties.Settings.Default.UpCam_PositionX = Cnc.CurrentX + X; Properties.Settings.Default.UpCam_PositionY = Cnc.CurrentY - Y; UpcamPositionX_textBox.Text = Properties.Settings.Default.UpCam_PositionX.ToString("0.00", CultureInfo.InvariantCulture); UpcamPositionY_textBox.Text = Properties.Settings.Default.UpCam_PositionY.ToString("0.00", CultureInfo.InvariantCulture); } } */ } //restore settings cnc.SlackCompensation = savedSlackCompensation; vp.MarkA.Clear(); //return value return (pixels.Count < 2) ? null : new PartLocation(Math.Abs(XmmPerPixel), Math.Abs(YmmPerPixel)); }
private Bitmap DrawComponentsFunct(Bitmap bitmap, VideoProcessing vp) { List <Shapes.Component> Components = VideoDetection.FindComponents(vp, bitmap); Graphics g = Graphics.FromImage(bitmap); Pen OrangePen = new Pen(Color.DarkOrange, 1); Pen RedPen = new Pen(Color.DarkRed, 2); Pen BluePen = new Pen(Color.Blue, 2); Shapes.Component Component; Point p1 = new Point(); Point p2 = new Point(); for (int i = 0, n = Components.Count; i < n; i++) { Component = Components[i]; // move Component.Longest start to ComponentCenter, draw it float dx = Component.Center.X - Component.Longest.Start.X; float dy = Component.Center.Y - Component.Longest.Start.Y; p1.X = (int)Math.Round(Component.Longest.Start.X + dx); p1.Y = (int)Math.Round(Component.Longest.Start.Y + dy); p2.X = (int)Math.Round(Component.Longest.End.X + dx); p2.Y = (int)Math.Round(Component.Longest.End.Y + dy); g.DrawLine(RedPen, p1, p2); // move Component.Longest end to ComponentCenter, draw Component.Longest dx = Component.Center.X - Component.Longest.End.X; dy = Component.Center.Y - Component.Longest.End.Y; p1.X = (int)Math.Round(Component.Longest.Start.X + dx); p1.Y = (int)Math.Round(Component.Longest.Start.Y + dy); p2.X = (int)Math.Round(Component.Longest.End.X + dx); p2.Y = (int)Math.Round(Component.Longest.End.Y + dy); g.DrawLine(RedPen, p1, p2); // move Normal start to ComponentCenter, draw it dx = Component.Center.X - Component.NormalStart.X; dy = Component.Center.Y - Component.NormalStart.Y; p1.X = (int)Math.Round(Component.NormalStart.X + dx); p1.Y = (int)Math.Round(Component.NormalStart.Y + dy); p2.X = (int)Math.Round(Component.NormalEnd.X + dx); p2.Y = (int)Math.Round(Component.NormalEnd.Y + dy); g.DrawLine(RedPen, p1, p2); // move Component.Normal end to ComponentCenter, draw it dx = Component.Center.X - Component.NormalEnd.X; dy = Component.Center.Y - Component.NormalEnd.Y; p1.X = (int)Math.Round(Component.NormalStart.X + dx); p1.Y = (int)Math.Round(Component.NormalStart.Y + dy); p2.X = (int)Math.Round(Component.NormalEnd.X + dx); p2.Y = (int)Math.Round(Component.NormalEnd.Y + dy); g.DrawLine(RedPen, p1, p2); // draw outline g.DrawPolygon(OrangePen, ToPointsArray(Component.Outline)); // draw Component.Longest p1.X = (int)Math.Round(Component.Longest.Start.X); p1.Y = (int)Math.Round(Component.Longest.Start.Y); p2.X = (int)Math.Round(Component.Longest.End.X); p2.Y = (int)Math.Round(Component.Longest.End.Y); g.DrawLine(BluePen, p1, p2); } return(bitmap); }
// will only work with downcamera public Shapes.Thing GoToClosestThing(Shapes.ShapeTypes type, double FindTolerance, double MoveTolerance, VideoProcessing vp = null, string template = null, double threshold = -1) { DisplayText("GoToThing(" + type + "), FindTolerance: " + FindTolerance + ", MoveTolerance: " + MoveTolerance, Color.Orange); vp = vp ?? cameraView.downVideoProcessing; Shapes.Thing thing = null; double dir = (vp.IsUpCamera()) ? -1 : 1; for (int i = 0; i < 8; i++) { //move up to 8 times Global.DoBackgroundWork(); thing = VideoDetection.FindClosest(vp, type, FindTolerance, 2, template, threshold); if (thing == null) break; //couldn't find thing.ToMMResolution(); DisplayText("--> round " + i + ", offset= " + thing.ToPartLocation() + " dist/tol = " + thing.ToPartLocation().VectorLength().ToString("F2") + " of " + FindTolerance); // If we are further than move tolerance, go there, else end loop if (thing.ToPartLocation().VectorLength() > MoveTolerance) { Console.WriteLine("\tmoving by " + thing.ToPartLocation()); Cnc.CNC_XY(Cnc.XYLocation + (dir * thing.ToPartLocation())); } else break; } //if (thing == null) ShowSimpleMessageBox("Optical positioning: Process is unstable, result is unreliable!"); if (thing != null) thing.AddOffset(Cnc.XYLocation); return thing; }
private Bitmap DrawComponentsFunct(Bitmap bitmap, VideoProcessing vp) { List<Shapes.Component> Components = VideoDetection.FindComponents(vp,bitmap); Graphics g = Graphics.FromImage(bitmap); Pen OrangePen = new Pen(Color.DarkOrange, 1); Pen RedPen = new Pen(Color.DarkRed, 2); Pen BluePen = new Pen(Color.Blue, 2); Shapes.Component Component; Point p1 = new Point(); Point p2 = new Point(); for (int i = 0, n = Components.Count; i < n; i++) { Component = Components[i]; // move Component.Longest start to ComponentCenter, draw it float dx = Component.Center.X - Component.Longest.Start.X; float dy = Component.Center.Y - Component.Longest.Start.Y; p1.X = (int)Math.Round(Component.Longest.Start.X + dx); p1.Y = (int)Math.Round(Component.Longest.Start.Y + dy); p2.X = (int)Math.Round(Component.Longest.End.X + dx); p2.Y = (int)Math.Round(Component.Longest.End.Y + dy); g.DrawLine(RedPen, p1, p2); // move Component.Longest end to ComponentCenter, draw Component.Longest dx = Component.Center.X - Component.Longest.End.X; dy = Component.Center.Y - Component.Longest.End.Y; p1.X = (int)Math.Round(Component.Longest.Start.X + dx); p1.Y = (int)Math.Round(Component.Longest.Start.Y + dy); p2.X = (int)Math.Round(Component.Longest.End.X + dx); p2.Y = (int)Math.Round(Component.Longest.End.Y + dy); g.DrawLine(RedPen, p1, p2); // move Normal start to ComponentCenter, draw it dx = Component.Center.X - Component.NormalStart.X; dy = Component.Center.Y - Component.NormalStart.Y; p1.X = (int)Math.Round(Component.NormalStart.X + dx); p1.Y = (int)Math.Round(Component.NormalStart.Y + dy); p2.X = (int)Math.Round(Component.NormalEnd.X + dx); p2.Y = (int)Math.Round(Component.NormalEnd.Y + dy); g.DrawLine(RedPen, p1, p2); // move Component.Normal end to ComponentCenter, draw it dx = Component.Center.X - Component.NormalEnd.X; dy = Component.Center.Y - Component.NormalEnd.Y; p1.X = (int)Math.Round(Component.NormalStart.X + dx); p1.Y = (int)Math.Round(Component.NormalStart.Y + dy); p2.X = (int)Math.Round(Component.NormalEnd.X + dx); p2.Y = (int)Math.Round(Component.NormalEnd.Y + dy); g.DrawLine(RedPen, p1, p2); // draw outline g.DrawPolygon(OrangePen, ToPointsArray(Component.Outline)); // draw Component.Longest p1.X = (int)Math.Round(Component.Longest.Start.X); p1.Y = (int)Math.Round(Component.Longest.Start.Y); p2.X = (int)Math.Round(Component.Longest.End.X); p2.Y = (int)Math.Round(Component.Longest.End.Y); g.DrawLine(BluePen, p1, p2); } return (bitmap); }
private static PartLocation DoCameraCalibration(VideoProcessing vp, PartLocation movement) { var cnc = Global.Instance.cnc; var distance = new List <PartLocation>(); var pixels = new List <PartLocation>(); // turn on slack compensation var savedSlackCompensation = cnc.SlackCompensation; cnc.SlackCompensation = true; var startingPos = cnc.XYLocation; startingPos.A = 0; vp.MarkA.Clear(); for (int i = -4; i < 5; i++) { //move var newLocation = startingPos + (i * movement); if (!cnc.CNC_XYA(newLocation)) { return(null); } //try 5 times to find a circle List <Shapes.Circle> circles = new List <Shapes.Circle>(); for (int tries = 5; tries > 0 && circles.Count == 0; tries--) { circles = VideoDetection.FindCircles(vp); } if (circles.Count == 0) { continue; //not found, move and try again } //find largest circle of the bunch var circle = circles.Aggregate((c, d) => c.Radius > d.Radius ? c : d); //find largest circle if we have multiple // var circlePL = (1 / zoom) * circle.ToPartLocation(); //compensate for zoom circle.ToScreenUnzoomedResolution(); distance.Add(newLocation); pixels.Add(circle.ToPartLocation()); vp.MarkA.Add(circle.Clone().ToScreenResolution().ToPartLocation().ToPointF()); //DisplayText(String.Format("Actual Loc = {0}\t Measured Loc = {1}", newLocation, UpCamera.PixelsToActualLocation(circlePL)), Color.Blue); } double XmmPerPixel = 0, YmmPerPixel = 0; if (pixels.Count < 2) { Global.Instance.mainForm.ShowMessageBox("Unable To Detect Circles", "Try to adjust upcamera processing to see circles, and ensure upcamera needle position is correctly configured", MessageBoxButtons.OK); } else { // Do regression on X and Y var Xs = pixels.Select(xx => xx.X).ToArray(); var Ys = distance.Select(xx => xx.X).ToArray(); var result = SimpleRegression.Fit(Xs, Ys); XmmPerPixel = result.Item2; Xs = pixels.Select(xx => xx.Y).ToArray(); Ys = distance.Select(xx => xx.Y).ToArray(); result = SimpleRegression.Fit(Xs, Ys); YmmPerPixel = result.Item2; Global.Instance.DisplayText(String.Format("{0} Xmm/pixel {1} Ymm/pixel", XmmPerPixel, YmmPerPixel), Color.Purple); // Now move to the center /* need to get gotolocation upcamera working still * double X, Y; //error offset * GotoUpCamPosition_button_Click(null, null); * for (int tries = 5; tries > 0; tries--) { * if (GoToLocation_m(UpCamera, Shapes.ShapeTypes.Circle, 1.8, 0.5, out X, out Y)) { * Properties.Settings.Default.UpCam_PositionX = Cnc.CurrentX + X; * Properties.Settings.Default.UpCam_PositionY = Cnc.CurrentY - Y; * UpcamPositionX_textBox.Text = Properties.Settings.Default.UpCam_PositionX.ToString("0.00", CultureInfo.InvariantCulture); * UpcamPositionY_textBox.Text = Properties.Settings.Default.UpCam_PositionY.ToString("0.00", CultureInfo.InvariantCulture); * * } * } */ } //restore settings cnc.SlackCompensation = savedSlackCompensation; vp.MarkA.Clear(); //return value return((pixels.Count < 2) ? null : new PartLocation(Math.Abs(XmmPerPixel), Math.Abs(YmmPerPixel))); }
public CameraView() { InitializeComponent(); this.Closing += new CancelEventHandler(Cleanup); //setup video processing // load the different filter blocks upSet = new AForgeFunctionSet("UP"); downSet = new AForgeFunctionSet("DOWN"); HideFilters(); //start hidden //start video capture upVideoCapture = new VideoCapture(CameraType.UpCamera); upVideoProcessing = new VideoProcessing(upVideoCapture); upVideoCapture.FrameCaptureDelegates.Add(UpCameraVideoProcessingCallback); upVideoProcessing.SetFunctionsList(currentUpBinding); downVideoCapture = new VideoCapture(CameraType.DownCamera); downVideoProcessing = new VideoProcessing(downVideoCapture); downVideoCapture.FrameCaptureDelegates.Add(DownCameraVideoProcessingCallback); downVideoProcessing.SetFunctionsList(currentDownBinding); //fill combobox // todo - restore from defaults UpCamera_FilterSet.DataSource = new BindingSource { DataSource = upSet.GetNames() }; DownCamera_FilterSet.DataSource = new BindingSource { DataSource = downSet.GetNames() }; var videoSources = VideoCapture.GetVideoDeviceList(); UpCam_ComboBox.DataSource = new BindingSource { DataSource = videoSources }; DownCam_ComboBox.DataSource = new BindingSource { DataSource = videoSources }; //load saved values var s = Properties.Settings.Default; if (s.DownCam_index > 0 && s.DownCam_index <= videoSources.Count + 1) { DownCam_ComboBox.SelectedIndex = s.DownCam_index - 1; downVideoCapture.Start(DownCam_ComboBox.SelectedIndex); } if (s.UpCam_index > 0 && s.UpCam_index <= videoSources.Count + 1 && s.UpCam_index != s.DownCam_index) { UpCam_ComboBox.SelectedIndex = s.UpCam_index - 1; upVideoCapture.Start(UpCam_ComboBox.SelectedIndex); } //bind editor values uFilter_dataGridView.DataSource = currentUpBinding; dFilter_dataGridView.DataSource = currentDownBinding; methodDataGridViewTextBoxColumn.DataSource = Enum.GetValues(typeof(AForgeMethod)); methodDataGridViewTextBoxColumn1.DataSource = Enum.GetValues(typeof(AForgeMethod)); }
public static List <Shapes.Fiducal> FindTemplates(VideoProcessing vp, Bitmap image) { return(FindTemplates(vp, image, Settings.Default.template_file, Settings.Default.template_threshold)); }
// higher levels tuff public static int MeasureClosestComponentInPx(out double X, out double Y, out double A, VideoProcessing vp, double Tolerance, int averages) { X = 0; double Xsum = 0; Y = 0; double Ysum = 0; A = 0.0; double Asum = 0.0; List <Shapes.Component> components = new List <Shapes.Component>(); for (int i = 0; i < 5; i++) { components.Add( GetClosest( GetWithin(FindComponents(vp), Tolerance) )); } int count = components.Count; if (count == 0) { return(0); } foreach (var c in components) { Xsum += c.X; Ysum += c.Y; Asum += Global.ReduceRotation(c.A); } X = Xsum / count; Y = Ysum / count; A = -Asum / count; return(count); }
public static List <Shapes.Component> FindComponents(VideoProcessing vp) { return(FindComponents(vp, vp.GetMeasurementFrame())); }
public static List <Shapes.Rectangle> FindRectangles(VideoProcessing vp) { Global.DoBackgroundWork(); return(FindRectangles(vp, vp.GetMeasurementFrame())); }
// ========================================================= private void DrawFiducialFunct(ref Bitmap image, VideoProcessing vp) { MarkA.Clear(); var fids = VideoDetection.FindTemplates(vp, image); foreach (var f in fids) f.ToScreenResolution(); MarkA.AddRange(fids.Select(x => x.ToPartLocation().ToPointF()).ToArray()); }
public CameraView() { InitializeComponent(); //call this function when closing //this.Closing +=new CancelEventHandler(Cleanup); //this is depreciated this.FormClosing += new FormClosingEventHandler(CameraView_FormClosing); //do not allow the cameraview to be closed by itself //setup key handeling KeyPreview = true; Global.Instance.mainForm.SetupCursorNavigation(Controls); KeyUp += Global.Instance.mainForm.My_KeyUp; //setup video processing // load the different filter blocks upSet = new AForgeFunctionSet("UP"); downSet = new AForgeFunctionSet("DOWN"); HideFilters(); //start hidden //Setup Checkbox Bindings DownCamera_drawGrid_checkBox.DataBindings.Add("Checked", downSettings, "Draw1mmGrid", false, DataSourceUpdateMode.OnPropertyChanged); DownCameraDrawCross_checkBox.DataBindings.Add("Checked", downSettings, "DrawCross", false, DataSourceUpdateMode.OnPropertyChanged); DownCameraDrawBox_checkBox.DataBindings.Add("Checked", downSettings, "DrawBox", false, DataSourceUpdateMode.OnPropertyChanged); DownCameraDrawTicks_checkBox.DataBindings.Add("Checked", downSettings, "DrawSidemarks", false, DataSourceUpdateMode.OnPropertyChanged); DownCamFindCircles_checkBox.DataBindings.Add("Checked", downSettings, "FindCircles", false, DataSourceUpdateMode.OnPropertyChanged); DownCamFindRectangles_checkBox.DataBindings.Add("Checked", downSettings, "FindRectangles", false, DataSourceUpdateMode.OnPropertyChanged); DownCam_FindComponents_checkBox.DataBindings.Add("Checked", downSettings, "FindComponent", false, DataSourceUpdateMode.OnPropertyChanged); DownCamera_FindFiducials_cb.DataBindings.Add("Checked", downSettings, "FindFiducial", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_DrawCross.DataBindings.Add("Checked", upSettings, "DrawCross", false, DataSourceUpdateMode.OnPropertyChanged); UpCan_DrawBox.DataBindings.Add("Checked", upSettings, "DrawBox", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_DrawDashedBox.DataBindings.Add("Checked", upSettings, "DrawDashedCross", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_FindCircles.DataBindings.Add("Checked", upSettings, "FindCircles", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_FindComponents.DataBindings.Add("Checked", upSettings, "FindComponent", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_FindRectangles.DataBindings.Add("Checked", upSettings, "FindRectangles", false, DataSourceUpdateMode.OnPropertyChanged); //start video capture upVideoCapture = new VideoCapture(CameraType.UpCamera); upVideoProcessing = new VideoProcessing(upVideoCapture, upSettings); upVideoCapture.FrameCaptureDelegates.Add(UpCameraVideoProcessingCallback); upVideoProcessing.SetFunctionsList(""); downVideoCapture = new VideoCapture(CameraType.DownCamera); downVideoProcessing = new VideoProcessing(downVideoCapture, downSettings); downVideoCapture.FrameCaptureDelegates.Add(DownCameraVideoProcessingCallback); downVideoProcessing.SetFunctionsList(""); //fill combobox // todo - restore from defaults UpCamera_FilterSet.DataSource = new BindingSource { DataSource = upSet.GetNames() }; DownCamera_FilterSet.DataSource = new BindingSource { DataSource = downSet.GetNames() }; var videoSources = VideoCapture.GetVideoDeviceList(); UpCam_ComboBox.DataSource = new BindingSource { DataSource = videoSources}; DownCam_ComboBox.DataSource = new BindingSource { DataSource = videoSources}; //load saved values var s = Properties.Settings.Default; if (s.UpCam_index != s.DownCam_index) { if (s.DownCam_index > 0 && s.DownCam_index <= videoSources.Count) { DownCam_ComboBox.SelectedIndex = s.DownCam_index-1; downVideoCapture.Start(DownCam_ComboBox.SelectedIndex); } if (s.UpCam_index > 0 && s.UpCam_index <= videoSources.Count) { UpCam_ComboBox.SelectedIndex = s.UpCam_index-1; upVideoCapture.Start(UpCam_ComboBox.SelectedIndex); } } //right click context menu ContextMenu cms = new System.Windows.Forms.ContextMenu(); var i = Global.Instance; cms.MenuItems.Add(new MenuItem("Needle To Table (Probe) And Back", delegate { var x = i.cnc.XYLocation; if (i.needle.Move_m(x) && i.needle.ProbeDown() && i.cnc.Zup() && i.cnc.CNC_XY(x)) { }; })); cms.MenuItems.Add(new MenuItem("Move To Closest Circle", delegate { i.mainForm.FindPositionAndMoveToClosest(Shapes.ShapeTypes.Circle, 5, .1); })); DownCamera_PictureBox.ContextMenu = cms; //bind editor values uFilter_dataGridView.DataSource = currentUpBinding; dFilter_dataGridView.DataSource = currentDownBinding; methodDataGridViewTextBoxColumn.DataSource = Enum.GetValues(typeof(AForgeMethod)); methodDataGridViewTextBoxColumn1.DataSource = Enum.GetValues(typeof(AForgeMethod)); //monitor frame rate FPStimer.Elapsed += delegate { UpdateFPS();}; FPStimer.Start(); }
/// <summary> /// Will use default settings for finding the template /// </summary> /// <param name="image">the image to search</param> /// <returns>list of fiducary points</returns> public static List <Shapes.Fiducal> FindTemplates(VideoProcessing vp, string template = null, double threshold = -1) { template = template ?? Settings.Default.template_file; threshold = (threshold == -1) ? Settings.Default.template_threshold : threshold; return(FindTemplates(vp, vp.GetMeasurementFrame(), template, threshold)); }
public CameraView() { InitializeComponent(); //call this function when closing //this.Closing +=new CancelEventHandler(Cleanup); //this is depreciated this.FormClosing += new FormClosingEventHandler(CameraView_FormClosing); //do not allow the cameraview to be closed by itself //setup key handeling KeyPreview = true; Global.Instance.mainForm.SetupCursorNavigation(Controls); KeyUp += Global.Instance.mainForm.My_KeyUp; //setup video processing // load the different filter blocks upSet = new AForgeFunctionSet("UP"); downSet = new AForgeFunctionSet("DOWN"); HideFilters(); //start hidden //Setup Checkbox Bindings DownCamera_drawGrid_checkBox.DataBindings.Add("Checked", downSettings, "Draw1mmGrid", false, DataSourceUpdateMode.OnPropertyChanged); DownCameraDrawCross_checkBox.DataBindings.Add("Checked", downSettings, "DrawCross", false, DataSourceUpdateMode.OnPropertyChanged); DownCameraDrawBox_checkBox.DataBindings.Add("Checked", downSettings, "DrawBox", false, DataSourceUpdateMode.OnPropertyChanged); DownCameraDrawTicks_checkBox.DataBindings.Add("Checked", downSettings, "DrawSidemarks", false, DataSourceUpdateMode.OnPropertyChanged); DownCamFindCircles_checkBox.DataBindings.Add("Checked", downSettings, "FindCircles", false, DataSourceUpdateMode.OnPropertyChanged); DownCamFindRectangles_checkBox.DataBindings.Add("Checked", downSettings, "FindRectangles", false, DataSourceUpdateMode.OnPropertyChanged); DownCam_FindComponents_checkBox.DataBindings.Add("Checked", downSettings, "FindComponent", false, DataSourceUpdateMode.OnPropertyChanged); DownCamera_FindFiducials_cb.DataBindings.Add("Checked", downSettings, "FindFiducial", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_DrawCross.DataBindings.Add("Checked", upSettings, "DrawCross", false, DataSourceUpdateMode.OnPropertyChanged); UpCan_DrawBox.DataBindings.Add("Checked", upSettings, "DrawBox", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_DrawDashedBox.DataBindings.Add("Checked", upSettings, "DrawDashedCross", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_FindCircles.DataBindings.Add("Checked", upSettings, "FindCircles", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_FindComponents.DataBindings.Add("Checked", upSettings, "FindComponent", false, DataSourceUpdateMode.OnPropertyChanged); UpCam_FindRectangles.DataBindings.Add("Checked", upSettings, "FindRectangles", false, DataSourceUpdateMode.OnPropertyChanged); //start video capture upVideoCapture = new VideoCapture(CameraType.UpCamera); upVideoProcessing = new VideoProcessing(upVideoCapture, upSettings); upVideoCapture.FrameCaptureDelegates.Add(UpCameraVideoProcessingCallback); upVideoProcessing.SetFunctionsList(""); downVideoCapture = new VideoCapture(CameraType.DownCamera); downVideoProcessing = new VideoProcessing(downVideoCapture, downSettings); downVideoCapture.FrameCaptureDelegates.Add(DownCameraVideoProcessingCallback); downVideoProcessing.SetFunctionsList(""); //fill combobox // todo - restore from defaults UpCamera_FilterSet.DataSource = new BindingSource { DataSource = upSet.GetNames() }; DownCamera_FilterSet.DataSource = new BindingSource { DataSource = downSet.GetNames() }; var videoSources = VideoCapture.GetVideoDeviceList(); UpCam_ComboBox.DataSource = new BindingSource { DataSource = videoSources }; DownCam_ComboBox.DataSource = new BindingSource { DataSource = videoSources }; //load saved values var s = Properties.Settings.Default; if (s.UpCam_index != s.DownCam_index) { if (s.DownCam_index > 0 && s.DownCam_index <= videoSources.Count + 1) { DownCam_ComboBox.SelectedIndex = s.DownCam_index - 1; downVideoCapture.Start(DownCam_ComboBox.SelectedIndex); } if (s.UpCam_index > 0 && s.UpCam_index <= videoSources.Count + 1) { UpCam_ComboBox.SelectedIndex = s.UpCam_index - 1; upVideoCapture.Start(UpCam_ComboBox.SelectedIndex); } } //right click context menu ContextMenu cms = new System.Windows.Forms.ContextMenu(); var i = Global.Instance; cms.MenuItems.Add(new MenuItem("Needle To Table (Probe) And Back", delegate { var x = i.cnc.XYLocation; if (i.needle.Move_m(x) && i.needle.ProbeDown() && i.cnc.Zup() && i.cnc.CNC_XY(x)) { } ; })); cms.MenuItems.Add(new MenuItem("Move To Closest Circle", delegate { i.mainForm.FindPositionAndMoveToClosest(Shapes.ShapeTypes.Circle, 5, .1); })); DownCamera_PictureBox.ContextMenu = cms; //bind editor values uFilter_dataGridView.DataSource = currentUpBinding; dFilter_dataGridView.DataSource = currentDownBinding; methodDataGridViewTextBoxColumn.DataSource = Enum.GetValues(typeof(AForgeMethod)); methodDataGridViewTextBoxColumn1.DataSource = Enum.GetValues(typeof(AForgeMethod)); //monitor frame rate FPStimer.Elapsed += delegate { UpdateFPS(); }; FPStimer.Start(); }
public static PartLocation Convert(VideoProcessing videoProcessing, PartLocation p, PointMode fromMode, PointMode toMode) { Thing t = new Thing(p, fromMode); t.videoProcessing = videoProcessing; switch (toMode) { case PointMode.MM: return t.ToMMResolution().ToPartLocation(); case PointMode.Raw: return t.ToRawResolution().ToPartLocation(); case PointMode.Screen: return t.ToScreenResolution().ToPartLocation(); case PointMode.ScreenUnzoomed: return t.ToScreenUnzoomedResolution().ToPartLocation(); } return null; }