using System; using HalconDotNet; using static DataStruct.DataStructClass; using ToolBase; using CommonMethods; using System.Diagnostics; using ViewROI; namespace FindLineTool { [Serializable] public class FindLine:IToolBase { public bool toolEnable = true; /// /// 输入姿态 /// public HTuple inputPoseHomMat2D = new HTuple(); /// /// 位置修正姿态 /// public HTuple changePoseHomMat2D = new HTuple(); /// /// 修改的位姿 /// public HTuple changedPose = new HTuple(); /// /// 卡尺 /// 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; /// /// 新的跟随姿态变化后的预期线信息 /// public HTuple modelStartRow = new HTuple(200), modelStartCol = new HTuple(200), modelEndRow = new HTuple(200), modelEndCol = new HTuple(600); /// /// 新的跟随姿态变化后的预期线信息 /// public 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 void UpdateModelLineLocation() { // 计算新的位置线和转换之后位置线之间的差异,再将差异补偿到模板位置线中 if(newExpectLineStartRow.Type != HTupleType.EMPTY) { HOperatorSet.VectorToSimilarity(new HTuple(newExpectLineStartRow, newExpectLineEndRow), new HTuple(newExpectLineStartCol, newExpectLineEndCol), new HTuple(expectLineStartRow, expectLineEndRow), new HTuple(expectLineStartCol, expectLineEndCol), out changePoseHomMat2D); // 更新位置 HOperatorSet.AffineTransPixel(changePoseHomMat2D, modelStartRow, modelStartCol, out modelStartRow, out modelStartCol); HOperatorSet.AffineTransPixel(changePoseHomMat2D, modelEndRow, modelEndCol, out modelEndRow, out modelEndCol); } } 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 (inputPoseHomMat2D.Type != HTupleType.EMPTY) { //对预期线的起始点做放射变换 HOperatorSet.AffineTransPixel(inputPoseHomMat2D, modelStartRow, modelStartCol, out newExpectLineStartRow, out newExpectLineStartCol); HOperatorSet.AffineTransPixel(inputPoseHomMat2D, modelEndRow, modelEndCol, 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); 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(); } runMessage = "工具运行成功,已找到线!"; toolRunStatu = ToolRunStatu.Succeed; } else { runMessage = "工具运行失败,未找到线"; toolRunStatu = ToolRunStatu.Tool_Run_Error; } // 参数传递 ParamsTrans(); sw.Stop(); runTime = $"运行时间: {sw.ElapsedMilliseconds} ms"; FormFindLine.Instance.SetToolStatus(runMessage, toolRunStatu); HOperatorSet.ClearMetrologyModel(handleID); } 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(HWindowTool_Smart window) { // 显示矩形 if (dispRec) { window.DispHWindow.SetColor("blue"); window.DispHWindow.DispObj(contoursDisp); } // 显示交点 if (dispCross) { window.DispHWindow.SetColor("orange"); window.DispHWindow.DispObj(crossDisp); } //显示找到的线 window.DispHWindow.SetColor("green"); window.DispHWindow.DispObj(LineDisp); } } }