using HalconDotNet; using LB_VisionControls; using System.Data.Common; using LB_VisionProcesses.Alogrithms; using System.Windows.Forms; namespace LB_VisionProcesses.Alogrithms.Halcon { public partial class HFindEllipseToolEdit : TAlgorithmEdit { public HFindEllipseToolEdit(HFindEllipseTool subject = null) { if (subject != null && subject is HFindEllipseTool) Subject = subject; else Subject = new HFindEllipseTool(); if (!(Subject.Params.ROI is HEllipse)) Subject.Params.ROI = new HEllipse(0, 0, 0, 250, 250); this.Dock = DockStyle.Fill; InitializeComponent(); } /// /// 控件加载事件 /// /// /// private void HFindEllipseToolEdit_Load(object sender, EventArgs e) { pnlInputImage.Controls.Add(inputImageHSmartWindowControl); inputImageHSmartWindowControl.Dock = DockStyle.Fill; pnlRecordImage.Controls.Add(recordImageHSmartWindowControl); recordImageHSmartWindowControl.Dock = DockStyle.Fill; //遍历可以选择的Roi类型枚举 cmbTypeRoi.Items.Add(RoiType.None); cmbTypeRoi.Items.Add(RoiType.Ellipse); //遍历可以选择的极性类型枚举 foreach (var value in Enum.GetValues(typeof(Transition))) cmbTransition.Items.Add(value.ToString()); //遍历可以选择的边缘类型枚举 foreach (var value in Enum.GetValues(typeof(Selector))) cmbSelect.Items.Add(value.ToString()); //遍历可以选择的Fixture枚举 cmbFixture.Items.Add(""); foreach (string value in IProcess.dicFixtures.Keys) cmbFixture.Items.Add(value.ToString()); ckbDrawRoi.Checked = true; cmbTypeRoi.Text = RoiType.Ellipse.ToString(); cmbTransition.Text = Transition.Ignore.ToString(); cmbSelect.Text = Selector.Best.ToString(); LoadParas(); if (Subject.Result) { lblResult.BackColor = Color.Green; lblResult.Text = "True"; } else { lblResult.BackColor = Color.Red; lblResult.Text = "False"; } lblMsg.Text = Msg.Length > 50 ? Msg.Substring(0, 50) : Msg; lblMsgToolTip.SetToolTip(BtmStatusStrip, Msg); lblRunTime.Text = $"{Subject.RunTime}ms"; } /// /// 更新运行参数 /// public override void UpdataInputs() { //设置运行参数 double dResult = 0; int iResult = 0; Subject.Params.Inputs["卡尺数量"] = int.TryParse(itxtCaliperCount.Text, out iResult) ? iResult : Subject.Params.Inputs["卡尺数量"]; Subject.Params.Inputs["卡尺长度"] = double.TryParse(dtxtCaliperHeight.Text, out dResult) ? dResult : Subject.Params.Inputs["卡尺长度"]; Subject.Params.Inputs["卡尺宽度"] = double.TryParse(dtxtCaliperWidth.Text, out dResult) ? dResult : Subject.Params.Inputs["卡尺宽度"]; Subject.Params.Inputs["过滤一半像素"] = int.TryParse(itxtSigma.Text, out iResult) ? iResult : Subject.Params.Inputs["过滤一半像素"]; Subject.Params.Inputs["对比度阈值"] = int.TryParse(itxtThreshold.Text, out iResult) ? iResult : Subject.Params.Inputs["对比度阈值"]; Subject.Params.Inputs["忽略点数"] = int.TryParse(itxtIgnoreCount.Text, out iResult) ? iResult : Subject.Params.Inputs["忽略点数"]; Subject.Params.Inputs["极性"] = cmbTransition.SelectedItem?.ToString(); Subject.Params.Inputs["边缘位置"] = cmbSelect.SelectedItem?.ToString(); if (cmbFixture.Text == "") Subject.Params.Fixture = new Fixture(); else if (IProcess.dicFixtures.ContainsKey(cmbFixture.Text)) Subject.Params.Fixture = IProcess.dicFixtures[cmbFixture.Text]; base.UpdataInputs(); } /// /// 加载运行参数 /// public override void LoadParas() { this.BeginInvoke(new Action(() => { itxtCaliperCount.Text = Subject.Params.Inputs["卡尺数量"].ToString(); dtxtCaliperHeight.Text = Subject.Params.Inputs["卡尺长度"].ToString(); dtxtCaliperWidth.Text = Subject.Params.Inputs["卡尺宽度"].ToString(); itxtSigma.Text = Subject.Params.Inputs["过滤一半像素"].ToString(); itxtThreshold.Text = Subject.Params.Inputs["对比度阈值"].ToString(); itxtIgnoreCount.Text = Subject.Params.Inputs["忽略点数"].ToString(); cmbTransition.Text = Subject.Params.Inputs["极性"].ToString(); cmbSelect.Text = Subject.Params.Inputs["边缘位置"].ToString(); if (Subject.InputImage != null && Subject.InputImage is HObject) inputImageHSmartWindowControl.ShowHoImage((HObject)Subject.InputImage); Type type = Subject.Params.ROI?.GetType(); if (Subject.Params.ROI != null) { switch (type) { case Type t when t == typeof(HEllipse): cmbTypeRoi.Text = RoiType.Ellipse.ToString(); break; default: cmbTypeRoi.Text = RoiType.None.ToString(); break; } if (cmbTypeRoi.Text.ToString() != "None") ckbDrawRoi.Checked = true; else ckbDrawRoi.Checked = false; inputImageHSmartWindowControl.oRoi = Subject.Params.ROI; } if (Subject.Params.Fixture != null) cmbFixture.Text = Subject.Params.Fixture.strName; else cmbFixture.Text = ""; switch (type) { case Type t when t == typeof(HEllipse): inputImageHSmartWindowControl.oRoi = new HEllipse(Subject.Params.ROI.X + Subject.Params.Fixture.X , Subject.Params.ROI.Y + Subject.Params.Fixture.Y , ((HEllipse)Subject.Params.ROI).Phi , ((HEllipse)Subject.Params.ROI).Radius1, ((HEllipse)Subject.Params.ROI).Radius2 , ((HEllipse)Subject.Params.ROI).StartPhi, ((HEllipse)Subject.Params.ROI).EndPhi); break; default: inputImageHSmartWindowControl.oRoi = null; break; } })); } /// /// 更新输出结果 /// public override void UpdataOutputs() { this.BeginInvoke(new Action(() => { //存在反序列化错乱的情况需要使用自定义的转换器 dtxtCenterX.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["CenterX"]); dtxtCenterY.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["CenterY"]); dtxtAngle.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["Angle"]); dtxtStartAngle.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["StartAngle"]); dtxtEndAngle.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["EndAngle"]); dtxtCount.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["Count"]); dtxtRadius.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["Radius"]); })); } /// /// 点击运行 /// /// /// public override void btnRun_Click(object sender, EventArgs e) { if (Subject.InputImage != null) InputImage = Subject.InputImage; DateTime StartTime = DateTime.Now; Run(); //更新日志与结果 this.BeginInvoke(new Action(() => { if (Subject.Result) { lblResult.BackColor = Color.Green; lblResult.Text = "True"; recordImageHSmartWindowControl.SetColor("green"); } else { lblResult.BackColor = Color.Red; lblResult.Text = "False"; recordImageHSmartWindowControl.SetColor("red"); } lblMsg.Text = Msg.Length > 50 ? Msg.Substring(0, 50) : Msg; lblMsgToolTip.SetToolTip(BtmStatusStrip, Msg); lblRunTime.Text = $"{(DateTime.Now - StartTime).TotalMilliseconds}ms"; UpdataOutputs(); imgTabControl.SelectedTab = tabPageRecordImage; if (Subject.InputImage != null && Subject.InputImage is HObject) { HOperatorSet.GetImageSize((HObject)Subject.InputImage, out HTuple ho_ImageWidth, out HTuple ho_ImageHeight); recordImageHSmartWindowControl.ShowHoImage((HObject)Subject.InputImage); } //先判断子类再判断父类 if (Subject.Record != null && Subject.Record is MsgRecord msgRecord) { recordImageHSmartWindowControl.DispObj(msgRecord.RecordObject_OK, true); recordImageHSmartWindowControl.DispObj(msgRecord.RecordObject_NG, false); for (int i = 0; i < msgRecord.Msg.Length; i++) recordImageHSmartWindowControl.ShowMsg(msgRecord.Msg[i] , 1 == msgRecord.Result[i] ? true : false, msgRecord.Column[i], msgRecord.Row[i]); } else if (Subject.Record != null && Subject.Record is ObjectRecord objRecord) { recordImageHSmartWindowControl.DispObj(objRecord.RecordObject_OK, true); recordImageHSmartWindowControl.DispObj(objRecord.RecordObject_NG, false); } GC.Collect(); })); } public override void btnLoadImage_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); // 设置文件对话框的属性 openFileDialog.Multiselect = false; // 不允许多选 // 设置文件过滤器,支持多种文件类型 openFileDialog.Filter = "Image Files (*.png;*.jpg;*.jpeg;*.bmp)|*.png;*.jpg;*.jpeg;*.bmp|All Files (*.*)|*.*"; // 显示文件对话框 DialogResult result = openFileDialog.ShowDialog(); // 处理对话框返回结果 if (result == DialogResult.OK) { // 获取用户选择的文件名 string[] selectedFiles = openFileDialog.FileNames; if (selectedFiles.Length > 0) { HOperatorSet.ReadImage(out HObject ho_Image, selectedFiles[0]); //判断是否为灰度图 using (HDevDisposeHelper dh = new HDevDisposeHelper()) { HOperatorSet.CountChannels(ho_Image, out HTuple hv_Channels); if (hv_Channels.TupleInt() != 1) { if (hv_Channels.TupleInt() == 4) { HOperatorSet.Decompose4(ho_Image, out HObject R, out HObject G, out HObject B, out _); HOperatorSet.Compose3(R, G, B, out ho_Image); } HOperatorSet.Rgb1ToGray(ho_Image, out ho_Image); //更新日志与结果 this.BeginInvoke(new Action(() => { lblMsg.Text = "导入图片非灰度图,自动转换为灰度图"; })); } InputImage = ho_Image; imgTabControl.SelectedTab = tabPageInputImage; inputImageHSmartWindowControl.oRoi = inputImageHSmartWindowControl.oRoi; } } } } public override void btnSaveParas_Click(object sender, EventArgs e) { base.btnSaveParas_Click(sender, e); } public override void ckbDrawRoi_CheckedChanged(object sender, EventArgs e) { if (ckbDrawRoi.Checked) { inputImageHSmartWindowControl.bAollowDraw = true; imgTabControl.SelectedTab = tabPageInputImage; } else { inputImageHSmartWindowControl.bAollowDraw = false; Subject.Params.ROI = new ROI(); } } public override void cmbTypeRoi_SelectedIndexChanged(object sender, EventArgs e) { try { if (Enum.TryParse(cmbTypeRoi.Text.ToString(), out RoiType type)) { HTuple hv_imageWidth = 0; HTuple hv_imageHeight = 0; if (InputImage != null && InputImage is HObject) HOperatorSet.GetImageSize((HObject)InputImage, out hv_imageWidth, out hv_imageHeight); switch (type) { case RoiType.Ellipse: inputImageHSmartWindowControl.oRoi = new HEllipse(hv_imageWidth.TupleReal() / 2, hv_imageHeight.TupleReal() / 2 , 0 , hv_imageWidth.TupleReal() / 4, hv_imageWidth.TupleReal() / 4 , 0, Math.PI / 2.0 * 3.0); break; case RoiType.None: default: inputImageHSmartWindowControl.oRoi = null; break; } } } catch { } } public override void cmbFixture_SelectedIndexChanged(object sender, EventArgs e) { try { if (IProcess.dicFixtures.ContainsKey(cmbFixture.Text)) Subject.Params.Fixture = IProcess.dicFixtures[cmbFixture.Text]; else Subject.Params.Fixture = new Fixture(); } catch { } } private void btnShowROI_Click(object sender, EventArgs e) { this.BeginInvoke(new Action(() => { try { imgTabControl.SelectedTab = tabPageInputImage; inputImageHSmartWindowControl.ClearObj(); if (Subject.InputImage != null && Subject.InputImage is HObject) inputImageHSmartWindowControl.ShowHoImage((HObject)Subject.InputImage); int hv_Elements = Convert.ToInt16(itxtCaliperCount.Text); double hv_DetectHeight = Convert.ToDouble(dtxtCaliperHeight.Text); double hv_DetectWidth = Convert.ToDouble(dtxtCaliperWidth.Text); double hv_CenterRow = Convert.ToDouble(((HEllipse)inputImageHSmartWindowControl.oRoi).Y); double hv_CenterCol = Convert.ToDouble(((HEllipse)inputImageHSmartWindowControl.oRoi).X); double hv_Radius1 = Convert.ToDouble(((HEllipse)inputImageHSmartWindowControl.oRoi).Radius1); double hv_Radius2 = Convert.ToDouble(((HEllipse)inputImageHSmartWindowControl.oRoi).Radius2); double hv_StartPhi = Convert.ToDouble(((HEllipse)inputImageHSmartWindowControl.oRoi).StartPhi); double hv_EndPhi = Convert.ToDouble(((HEllipse)inputImageHSmartWindowControl.oRoi).EndPhi); TAlgorithm.GetRakeEllipseRegions(null, out HObject ho_Regions, hv_Elements, hv_DetectHeight, hv_DetectWidth , new HTuple(), new HTuple(), new HTuple(), new HTuple() , hv_CenterRow, hv_CenterCol, hv_Radius1, hv_Radius2, hv_StartPhi, hv_EndPhi , out HTuple hv_ResultRow, out HTuple hv_ResultColumn); inputImageHSmartWindowControl.DispObj(ho_Regions); } catch { } })); } } }