/// <summary> /// 找到一个圆 /// </summary> /// <param name="image">图片</param> /// <param name="rect">ROI</param> /// <param name="minr">最小圆半径</param> /// <param name="maxr">最大圆半径</param> /// <param name="center">圆心</param> /// <param name="radius">半径</param> /// <param name="gain">预处理参数</param> /// <param name="offset">预处理参数</param> /// <param name="cycle">预处理参数</param> /// <returns>找到/没找到</returns> public static bool FindCircle(VisionImage image, RectangleContour rect, short minr, short maxr, ref PointContour center, ref double radius, double gain, double offset, int cycle) { if (image == null) { return(false); } for (int i = 0; i < cycle; i++) { image = Form_Main.Instance.GainOffset(image, gain, offset); } Roi roi = rect.ConvertToRoi(); short rtn = 0; try { rtn = Form_Main.Instance.CamDetect_Circle(image, roi, minr, maxr, ref center, ref radius); if (rtn != 0) { return(false); } } catch { return(false); } return(true); }
private double MeasureMaximumDistance(VisionImage image, RectangleContour searchRectangle, RakeDirection rakeDirection, DrawOptions drawOptions, CoordinateTransform transform) { // Convert the search rectangle to an Roi. Roi roi = searchRectangle.ConvertToRoi(); // Transform the Roi. Algorithms.TransformRoi(roi, transform); // Perform a rake operation. RakeReport report = Algorithms.Rake(image, roi, rakeDirection, EdgeProcess.FirstAndLast); // Find the maximum edge positions and compute the distance. Collection <LineContour> perpendicularLines; PointContour closestFirstEdge, closestLastEdge; double distance = FindMinMaxPosition(report, out perpendicularLines, out closestFirstEdge, out closestLastEdge); // Draw the results. if (drawOptions.ShowSearchLines) { foreach (SearchLineInfo lineInfo in report.SearchLines) { image.Overlays.Default.AddLine(lineInfo.Line, Rgb32Value.BlueColor); } } if (drawOptions.ShowSearchArea) { image.Overlays.Default.AddRoi(roi); } if (drawOptions.ShowEdgesFound) { foreach (EdgeInfo edgeInfo in report.FirstEdges) { image.Overlays.Default.AddRectangle(new RectangleContour(edgeInfo.Position.X - 1, edgeInfo.Position.Y - 1, 3, 3), Rgb32Value.YellowColor, DrawingMode.PaintValue); } foreach (EdgeInfo edgeInfo in report.LastEdges) { image.Overlays.Default.AddRectangle(new RectangleContour(edgeInfo.Position.X - 1, edgeInfo.Position.Y - 1, 3, 3), Rgb32Value.YellowColor); } } if (drawOptions.ShowResult) { // Overlay the measurement edge points. image.Overlays.Default.AddOval(new OvalContour(closestFirstEdge.X - 2, closestFirstEdge.Y - 2, 5, 5), Rgb32Value.RedColor, DrawingMode.PaintValue); image.Overlays.Default.AddOval(new OvalContour(closestLastEdge.X - 2, closestLastEdge.Y - 2, 5, 5), Rgb32Value.RedColor, DrawingMode.PaintValue); // Overlay the two lines that point inward from the search area to the clamp position. LineContour line1 = new LineContour(FindMidpoint(report.SearchLines[0].Line.Start, report.SearchLines[report.SearchLines.Count - 1].Line.Start), FindMidpoint(perpendicularLines[0])); image.Overlays.Default.AddLine(line1, Rgb32Value.RedColor); DrawArrow(image.Overlays.Default, line1, Rgb32Value.RedColor); LineContour line2 = new LineContour(FindMidpoint(report.SearchLines[0].Line.End, report.SearchLines[report.SearchLines.Count - 1].Line.End), FindMidpoint(perpendicularLines[1])); image.Overlays.Default.AddLine(line2, Rgb32Value.RedColor); DrawArrow(image.Overlays.Default, line2, Rgb32Value.RedColor); // Overlay the two lines perpendicular to the search lines that correspond to the clamp position. image.Overlays.Default.AddLine(perpendicularLines[0], Rgb32Value.RedColor); image.Overlays.Default.AddLine(perpendicularLines[1], Rgb32Value.RedColor); } return(distance); }
public static short FitLine(VisionImage image, RectangleContour roi, double EdgeStength, int searchDir, int edgeMode, ref PointContour PointStart, ref PointContour PointEnd)//视觉抓边算法 { SearchDirection SearchDirection = SearchDirection.BottomToTop; EdgePolaritySearchMode EdgeMode = EdgePolaritySearchMode.Falling; if (searchDir == 0) { SearchDirection = SearchDirection.LeftToRight; } else if (searchDir == 1) { SearchDirection = SearchDirection.RightToLeft; } else if (searchDir == 2) { SearchDirection = SearchDirection.TopToBottom; } else if (searchDir == 3) { SearchDirection = SearchDirection.BottomToTop; } if (edgeMode == 0) { EdgeMode = EdgePolaritySearchMode.Rising; } else if (edgeMode == 1) { EdgeMode = EdgePolaritySearchMode.Falling; } if (roi != null) { VisionImage imageTemp = new VisionImage(); Algorithms.Extract(image, imageTemp, roi); Algorithms.ImageToImage(imageTemp, image, new PointContour(roi.Left, roi.Top)); #region 抓边参数 StraightEdgeOptions vaStraightEdgeOptions = new StraightEdgeOptions(); vaStraightEdgeOptions.NumberOfLines = 1; vaStraightEdgeOptions.SearchMode = StraightEdgeSearchMode.FirstRakeEdges; vaStraightEdgeOptions.ScoreRange = new Range(0, 1024); vaStraightEdgeOptions.Orientation = 0; vaStraightEdgeOptions.AngleRange = 90; vaStraightEdgeOptions.AngleTolerance = 1; vaStraightEdgeOptions.StepSize = 3; vaStraightEdgeOptions.MinimumSignalToNoiseRatio = 0; vaStraightEdgeOptions.MinimumCoverage = 25; vaStraightEdgeOptions.HoughIterations = 5; // Set EdgeOptions EdgeOptions vaEdgeOptions = new EdgeOptions(); vaEdgeOptions.Polarity = EdgeMode; vaEdgeOptions.KernelSize = 7; vaEdgeOptions.Width = 3; vaEdgeOptions.MinimumThreshold = EdgeStength; vaEdgeOptions.InterpolationType = InterpolationMethod.ZeroOrder; vaEdgeOptions.ColumnProcessingMode = ColumnProcessingMode.Average; #endregion try { StraightEdgeReport report1 = Algorithms.StraightEdge2(image, roi.ConvertToRoi(), SearchDirection, vaEdgeOptions, vaStraightEdgeOptions, false); if (report1.StraightEdges.Count > 0) { PointStart = report1.StraightEdges[0].StraightEdge.Start; PointEnd = report1.StraightEdges[0].StraightEdge.End; //image.Overlays.Default.Clear(); image.Overlays.Default.AddLine(new LineContour(report1.StraightEdges[0].StraightEdge.Start, report1.StraightEdges[0].StraightEdge.End)); return(0); } } catch { } } PointStart.X = 0; PointStart.Y = 0; PointEnd.X = 0; PointEnd.Y = 0; return(1); }
public static void AutoCheck() { MachineOrgConfig MachineCFG = new MachineOrgConfig(); SerializableHelper <MachineOrgConfig> helper = new SerializableHelper <MachineOrgConfig>(MachineCFG); MachineCFG = helper.DeXMLSerialize(System.AppDomain.CurrentDomain.BaseDirectory + "Configure\\MachineOrg.xml"); if (Form_Main.Instance.RunMode != 1) { try { PointF circle = new PointF(); double offsetX = 0; double offsetY = 0; PointContour center = null; RectangleContour roi = null; VisionImage img = null; double rCenter = 0; var machine = Form_Main.Instance; var config = Form_Main.VariableSys; var vel = config.VelMode_Current_Manual; if (!machine.All_ZGoSafeTillStop(3000, vel)) { new Exception("Z轴回原点失败"); } short rtn = machine.XYGoPosTillStop(3000, config.pReadyPoint, vel); if (rtn != 0) { throw new Exception("移动XY到位失败"); } rtn += machine.Turn.GoPosTillStop(3000, config.dTurnXIAngle, vel); if (rtn != 0) { throw new Exception("移动翻转到位失败"); } machine.LightON_U(); machine.SetShutter(MachineCFG.Exp, CAM.Top); // 到机械原点 rtn += machine.XYGoPosTillStop(3000, MachineCFG.OrgXY, vel); if (rtn != 0) { throw new Exception("移动XY到位失败"); } Thread.Sleep(1000); img = CameraDefine.Instance[CAM.Top]._Session.Snap(machine.imageSet.Image); roi = new RectangleContour(0, 0, img.Width, img.Height); center = new PointContour(); rCenter = 0; rtn = Form_Main.Instance.CamDetect_Circle(img , roi.ConvertToRoi(), (short)MachineCFG.MinR, (short)MachineCFG.MaxR, ref center, ref rCenter); if (rtn != 0) { throw new Exception("抓取XY机械原点失败"); } circle = CameraDefine.Instance[CAM.Top].ImagePt2WorldPt(MachineCFG.OrgXY, center, 0); offsetX = circle.X - MachineCFG.OrgXY.X; offsetY = circle.Y - MachineCFG.OrgXY.Y; if (Math.Abs(offsetX) > MachineCFG.UpLimit || Math.Abs(offsetY) > MachineCFG.UpLimit) { new Exception($"XY 机械原点检验成功,误差过大 X:{offsetX:N3} Y:{offsetY:N3}"); } File.AppendAllText("D://机械原点校验数据.csv", $"XY机械原点误差,{offsetX:N3},{offsetY:N3},"); // 到翻转头 Thread.Sleep(500); machine.LightON_D(); machine.SetShutter(MachineCFG.D_Exp, CAM.Bottom1); #region 检验翻转头机械原点1 rtn += machine.XYGoPosTillStop(3000, MachineCFG.D_Org1XY, vel); if (rtn != 0) { throw new Exception("移动XY到位失败"); } Thread.Sleep(1000); img = CameraDefine.Instance[CAM.Bottom1]._Session.Snap(machine.imageSet.Image); roi = new RectangleContour(0, 0, img.Width, img.Height); center = new PointContour(); rCenter = 0; rtn = Form_Main.Instance.CamDetect_Circle(img , roi.ConvertToRoi(), (short)MachineCFG.D_MinR, (short)MachineCFG.D_MaxR, ref center, ref rCenter); if (rtn != 0) { throw new Exception("抓取翻转头1机械原点失败"); } circle = CameraDefine.Instance[CAM.Bottom1].ImagePt2WorldPt(MachineCFG.D_Org1XY, center, 0); offsetX = circle.X - MachineCFG.D_Org1XY.X; offsetY = circle.Y - MachineCFG.D_Org1XY.Y; if (Math.Abs(offsetX) > MachineCFG.UpLimit || Math.Abs(offsetY) > MachineCFG.UpLimit) { throw new Exception($"翻转头机械1原点检验成功,误差过大 X:{offsetX:N3} Y:{offsetY:N3}"); } File.AppendAllText("D://机械原点校验数据.csv", $"翻转头机械1原点误差,{offsetX:N3},{offsetY:N3},"); #endregion #region 检验翻转头机械原点2 rtn += machine.XYGoPosTillStop(3000, MachineCFG.D_Org2XY, vel); if (rtn != 0) { throw new Exception("移动XY到位失败"); } Thread.Sleep(1000); img = CameraDefine.Instance[CAM.Bottom1]._Session.Snap(machine.imageSet.Image); roi = new RectangleContour(0, 0, img.Width, img.Height); center = new PointContour(); rCenter = 0; rtn += Form_Main.Instance.CamDetect_Circle(img , roi.ConvertToRoi(), (short)MachineCFG.D_MinR, (short)MachineCFG.D_MaxR, ref center, ref rCenter); if (rtn != 0) { throw new Exception("抓取翻转头2机械原点失败"); } circle = CameraDefine.Instance[CAM.Bottom1].ImagePt2WorldPt(MachineCFG.D_Org2XY, center, 0); offsetX = circle.X - MachineCFG.D_Org2XY.X; offsetY = circle.Y - MachineCFG.D_Org2XY.Y; if (Math.Abs(offsetX) > MachineCFG.UpLimit || Math.Abs(offsetY) > MachineCFG.UpLimit) { throw new Exception($"翻转头机械2原点检验成功,误差过大 X:{offsetX:N3} Y:{offsetY:N3}"); } File.AppendAllText("D://机械原点校验数据.csv", $"翻转头机械2原点误差,{offsetX:N3},{offsetY:N3}\r\n"); } catch (Exception ex) { File.AppendAllText("D://机械原点校验数据.csv", $"失败原因{ex.Message}\r\n"); } #endregion } }