using System; using HalconDotNet; using static DataStruct.DataStruct; using ToolBase; using CommonMethods; using System.Diagnostics; namespace FindLineTool { [Serializable] public class FindLine:IToolBase { public bool toolEnable = true; /// /// 输入姿态 /// public PosXYU inputPose = new PosXYU(); /// /// 制作模板时的输入位姿 /// public PosXYU templatePose = new PosXYU(); /// /// 卡尺 /// public HObject contoursDisp = null; /// /// 箭头 /// public HObject arrowDisp = null; /// /// 交点 /// public HObject crossDisp = null; /// /// 期望线起点行坐标 /// public HTuple expectLineStartRow = 200; /// /// 期望线起点列坐标 /// public HTuple expectLineStartCol = 200; /// /// 期望线终点行坐标 /// public HTuple expectLineEndRow = 200; /// /// 期望线终点列坐标 /// public HTuple expectLineEndCol = 600; /// /// 新的跟随姿态变化后的预期线信息 /// HTuple newExpectLineStartRow = new HTuple(200), newExpectLineStartCol = new HTuple(200), newExpectLineEndRow = new HTuple(200), newExpectLineEndCol = new HTuple(600); ///// ///// 区域中心行坐标 ///// //public HTuple recCenterRow = 200; ///// ///// 区域中心列坐标 ///// //public HTuple recCenterCol = 200; //public HTuple recAngle = 0; //public HTuple recWidth = 100; //public HTuple recLength = 200; /// /// 找边极性,从明到暗或从暗到明 /// public string polarity = "negative"; /// /// 卡尺数量 /// public int cliperNum = 20; /// /// 卡尺高 /// public int length = 80; /// /// 卡尺宽 /// public int weidth = 5; /// /// 边阈值 /// public int threshold = 30; /// /// 边Sigma /// public double sigma = 1.0; /// /// 选择所查找到的边 /// public string edgeSelect = "all"; /// /// 分数阈值 /// public double _minScore = 0.5; /// /// 矩形框显示 /// public bool dispRec = true; /// /// 交点显示 /// public bool dispCross = true; public double minScore { get { return _minScore; } set { if(minScore >= 1) { _minScore = 1; } else if(minScore <= 0) { _minScore = 0; } else { _minScore = value; } } } /// /// 找到的线段 /// public Line resultLine = null; /// /// 显示的线 /// public HObject LineDisp = null; /// /// 新的跟随姿态变化后的预期线信息 /// HTuple newExpectCenterRow = new HTuple(200), newExpectCenterCol = new HTuple(200), newExpectAngle = new HTuple(0); /// /// 查找到的线的起点行坐标 /// private HTuple _resultLineStartRow = 0; internal HTuple ResultLineStartRow { get { _resultLineStartRow = Math.Round((double)_resultLineStartRow, 3); return _resultLineStartRow; } set { _resultLineStartRow = value; } } /// /// 查找到的线的起点列坐标 /// private HTuple _resultLineStartCol = 0; internal HTuple ResultLineStartCol { get { _resultLineStartCol = Math.Round((double)_resultLineStartCol, 3); return _resultLineStartCol; } set { _resultLineStartCol = value; } } /// /// 查找到的线的终点行坐标 /// private HTuple _resultLineEndRow = 0; internal HTuple ResultLineEndRow { get { _resultLineEndRow = Math.Round((double)_resultLineEndRow, 3); return _resultLineEndRow; } set { _resultLineEndRow = value; } } /// /// 查找到的线的终点列坐标 /// private HTuple _resultLineEndCol = 0; internal HTuple ResultLineEndCol { get { _resultLineEndCol = Math.Round((double)_resultLineEndCol, 3); return _resultLineEndCol; } set { _resultLineEndCol = value; } } /// /// 查找到线的方向 /// private HTuple _angle = 0; internal HTuple Angle { get { _angle = Math.Round((double)_angle, 3); return _angle; } set { _angle = value; } } public override void DispImage() { if(inputImage != null) { FormFindLine.Instance.myHwindow.DispImage(new HImage(inputImage)); } } public void UpdateImage() { FormFindLine.Instance.myHwindow.DispHWindow.ClearWindow(); DispImage(); } public override void Run(SoftwareRunState softwareRunState) { Stopwatch sw = new Stopwatch(); sw.Restart(); HTuple homMat2DArrow = null; HObject arrow = null, arrowTrans = null; HObject drawLine = null, imageReducedLine; if (inputImage == null) { FormFindLine.Instance.SetToolStatus("工具输入图像为空", ToolRunStatu.Not_Input_Image); return; } try { if(softwareRunState == SoftwareRunState.Debug) { UpdateImage(); } if (inputPose != null) { HTuple Row = inputPose.X - templatePose.X; HTuple Col = inputPose.Y - templatePose.Y; HTuple angle = inputPose.U - templatePose.U; HTuple _homMat2D; HOperatorSet.HomMat2dIdentity(out _homMat2D); HOperatorSet.HomMat2dRotate(_homMat2D, (HTuple)(angle), (HTuple)templatePose.X, (HTuple)templatePose.Y, out _homMat2D); HOperatorSet.HomMat2dTranslate(_homMat2D, (HTuple)(Row), (HTuple)(Col), out _homMat2D); //对预期线的起始点做放射变换 HOperatorSet.AffineTransPixel(_homMat2D, (HTuple)expectLineStartRow, (HTuple)expectLineStartCol, out newExpectLineStartRow, out newExpectLineStartCol); HOperatorSet.AffineTransPixel(_homMat2D, (HTuple)expectLineEndRow, (HTuple)expectLineEndCol, out newExpectLineEndRow, out newExpectLineEndCol); } else { newExpectLineStartRow = expectLineStartRow; newExpectLineStartCol = expectLineStartCol; newExpectLineEndRow = expectLineEndRow; newExpectLineEndCol = expectLineEndCol; } HTuple handleID; HOperatorSet.CreateMetrologyModel(out handleID); HTuple width, height; HOperatorSet.GetImageSize(inputImage, out width, out height); HOperatorSet.SetMetrologyModelImageSize(handleID, width[0], height[0]); HTuple index; HOperatorSet.AddMetrologyObjectLineMeasure(handleID, newExpectLineStartRow, newExpectLineStartCol, newExpectLineEndRow, newExpectLineEndCol, new HTuple(50), new HTuple(20), new HTuple(1), new HTuple(30), new HTuple(), new HTuple(), out index); //参数在这里设置 HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_transition"), new HTuple(polarity)); HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("num_measures"), new HTuple(cliperNum)); HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_length1"), new HTuple(length)); HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_length2"), new HTuple(weidth)); HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_threshold"), new HTuple(threshold)); HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_select"), new HTuple(edgeSelect)); HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("measure_sigma"), new HTuple(sigma)); HOperatorSet.SetMetrologyObjectParam(handleID, new HTuple("all"), new HTuple("min_score"), new HTuple(minScore)); HOperatorSet.ApplyMetrologyModel(inputImage, handleID); //显示所有卡尺 HTuple pointRow, pointCol; HOperatorSet.GetMetrologyObjectMeasures(out contoursDisp, handleID, new HTuple("all"), new HTuple("all"), out pointRow, out pointCol); //显示指示找线方向的箭头 #region 测试箭头 HTuple arrowRow = null, arrowColumn = null; HOperatorSet.GenRegionLine(out drawLine, newExpectLineStartRow, newExpectLineStartCol, newExpectLineEndRow, newExpectLineEndCol); HOperatorSet.ReduceDomain(inputImage, drawLine, out imageReducedLine); HOperatorSet.GetRegionPoints(imageReducedLine, out arrowRow, out arrowColumn); if (arrowRow.Length < 200) { CommonMethods.CommonMethods.gen_arrow_contour_xld(out arrow, arrowRow[0], arrowColumn[0], arrowRow[arrowRow.Length - 1], arrowColumn[arrowRow.Length - 1], 20, 20); } else { CommonMethods.CommonMethods.gen_arrow_contour_xld(out arrow, arrowRow[0], arrowColumn[0], arrowRow[200], arrowColumn[200], 20, 20); } HOperatorSet.VectorAngleToRigid(newExpectLineStartRow, newExpectLineStartCol, 0, (newExpectLineStartRow + newExpectLineEndRow) / 2, (newExpectLineStartCol + newExpectLineEndCol) / 2, new HTuple(-90).TupleRad(), out homMat2DArrow); HOperatorSet.AffineTransContourXld(arrow, out arrowDisp, homMat2DArrow); #endregion //把点显示出来 HOperatorSet.GenCrossContourXld(out crossDisp, pointRow, pointCol, new HTuple(12), new HTuple(0)); //得到所找到的线 HTuple parameter; HOperatorSet.GetMetrologyObjectResult(handleID, new HTuple("all"), new HTuple("all"), new HTuple("result_type"), new HTuple("all_param"), out parameter); HOperatorSet.GetMetrologyObjectResultContour(out LineDisp, handleID, new HTuple("all"), new HTuple("all"), new HTuple(1.5)); if (parameter.Length >= 4) { ResultLineStartRow = parameter[0]; ResultLineStartCol = parameter[1]; ResultLineEndRow = parameter[2]; ResultLineEndCol = parameter[3]; Point start = new Point() { Row = ResultLineStartRow, Col = ResultLineStartCol }; Point end = new Point() { Row = ResultLineEndRow, Col = ResultLineEndCol }; resultLine = new Line() { StartPoint = start, EndPoint = end }; } HOperatorSet.AngleLx(ResultLineStartRow, ResultLineStartCol, ResultLineEndRow, ResultLineEndCol, out _angle); if (softwareRunState == SoftwareRunState.Debug) { DispMainWindow(FormFindLine.Instance.myHwindow.DispHWindow); FormFindLine.Instance.tbx_resultStartRow.Text = ResultLineStartRow.ToString(); FormFindLine.Instance.tbx_resultStartCol.Text = ResultLineEndCol.ToString(); FormFindLine.Instance.tbx_resultEndRow.Text = ResultLineEndRow.ToString(); FormFindLine.Instance.tbx_resultEndCol.Text = ResultLineEndCol.ToString(); } HOperatorSet.ClearMetrologyModel(handleID); // 参数传递 ParamsTrans(); sw.Stop(); runTime = $"运行时间: {sw.ElapsedMilliseconds} ms"; FormFindLine.Instance.SetToolStatus("工具运行成功!", ToolRunStatu.Succeed); } catch (Exception ex) { FormFindLine.Instance.SetToolStatus($"工具运行异常,异常原因: {ex}", ToolRunStatu.Tool_Run_Error); } finally { //homMat2DArrow.Dispose(); //arrow.Dispose(); //arrowTrans.Dispose(); } } /// /// 将数据传递给FindlineToolInterface /// private void ParamsTrans() { FormFindLine.Instance.myToolInfo.toolOutput.Clear(); FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("outputXld", resultLine, DataType.Line)); FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("StartPoint.Row", ResultLineStartRow, DataType.IntValue)); FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("StartPoint.Column", ResultLineStartCol, DataType.IntValue)); FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("EndPoint.Row", ResultLineEndRow, DataType.IntValue)); FormFindLine.Instance.myToolInfo.toolOutput.Add(new ToolIO("EndPoint.Column", ResultLineEndCol, DataType.IntValue)); } public override void DispMainWindow(HWindow window) { // 显示矩形 if (dispRec) { window.SetColor("blue"); window.DispObj(contoursDisp); } // 显示交点 if (dispCross) { window.SetColor("orange"); window.DispObj(crossDisp); } //显示找到的线 window.SetColor("green"); window.DispObj(LineDisp); } } }