using HalconDotNet; using LB_SmartVisionCommon; using LB_VisionControls; using LB_VisionProcesses.Alogrithms.Halcon; using Microsoft.VisualBasic.ApplicationServices; using OpenCvSharp; using Sunny.UI.Win32; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using static System.Windows.Forms.VisualStyles.VisualStyleElement; namespace LB_VisionProcesses.Alogrithms.Halcon { public partial class HImageEnhancementToolEdit : TAlgorithmEdit { List recordImageEnhancementDatas = new List(); private int rowriginalHeight; public HImageEnhancementToolEdit(HImageEnhancementTool subject = null) { if (subject != null && subject is HImageEnhancementTool) Subject = subject; else Subject = new HImageEnhancementTool(); //if (!(Subject.Params.ROI is HSegment)) // Subject.Params.ROI = new HSegment(0, 0, 250, 250); this.Dock = DockStyle.Fill; InitializeComponent(); // 保存原始行高度 rowriginalHeight = (int)tableLayoutPanel4.RowStyles[1].Height; InitializeComboBox(); InitializeDataGridView(); recordImageEnhancementDatas = ImageEnhancementManager.Instance.GetAllUsers(); this.dataGridViewIE.DataSource = recordImageEnhancementDatas; this.dataGridViewIE.AutoGenerateColumns = true; } private void InitializeComboBox() { // 添加权限选项 foreach (var item in Enum.GetValues(typeof(ImageEnhancementDataType))) { cmbImageEnhancement.Items.Add(item.ToString()); } // 设置默认选择项 cmbImageEnhancement.SelectedIndex = 2; } #region 算法选择下拉框 private void cmbImageEnhancement_SelectedIndexChanged(object sender, EventArgs e) { System.Windows.Forms.ComboBox cb = sender as System.Windows.Forms.ComboBox; if (cb.SelectedIndex == 0) { ShowRow(); } else if (cb.SelectedIndex == 1) { HideRow(); } else { HideRow(); } } private void ShowRow() { // 显示Row2(恢复高度) tableLayoutPanel4.RowStyles[1].SizeType = SizeType.Absolute; tableLayoutPanel4.RowStyles[1].Height = rowriginalHeight; // 显示Row2中的控件 foreach (Control ctrl in tableLayoutPanel4.Controls) { int row = tableLayoutPanel4.GetRow(ctrl); if (row == 1) ctrl.Visible = true; } } private void HideRow() { // 显示Row2(恢复高度) tableLayoutPanel4.RowStyles[1].SizeType = SizeType.Absolute; tableLayoutPanel4.RowStyles[1].Height = 0; // 显示Row2中的控件 foreach (Control ctrl in tableLayoutPanel4.Controls) { int row = tableLayoutPanel4.GetRow(ctrl); if (row == 1) ctrl.Visible = false; } } #endregion private void InitializeDataGridView() { this.dataGridViewIE.DataSource = recordImageEnhancementDatas; // 设置DataGridView列宽 dataGridViewIE.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; } /// /// 控件加载事件 /// /// /// private void HImageEnhancementToolEdit_Load(object sender, EventArgs e) { pnlInputImage.Controls.Add(inputImageHSmartWindowControl); inputImageHSmartWindowControl.Dock = DockStyle.Fill; pnlRecordImage.Controls.Add(recordImageHSmartWindowControl); recordImageHSmartWindowControl.Dock = DockStyle.Fill; //遍历可以选择的Roi类型枚举 foreach (var value in Enum.GetValues(typeof(RoiType))) cmbTypeRoi.Items.Add(value.ToString()); //遍历可以选择的图像增强类型枚举 //foreach (var value in Enum.GetValues(typeof(ImageEnhancementType))) // cmbImageEnhancement.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.Segment.ToString(); cmbImageEnhancement.Text = ImageEnhancementType.ScaleMax.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"; } private void ClearInputFields() { txtMaskWidth.Clear(); txtMaskHeight.Clear(); txtFactor.Clear(); cmbImageEnhancement.SelectedIndex = 0; } private void btnAdd_Click(object sender, EventArgs e) { // 验证输入 if (cmbImageEnhancement.SelectedIndex == 0) { if (string.IsNullOrWhiteSpace(txtMaskWidth.Text) || string.IsNullOrWhiteSpace(txtMaskHeight.Text) || string.IsNullOrWhiteSpace(txtFactor.Text)) { MessageBox.Show("请填写所有必填字段!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } } RecordImageEnhancementData filter = new RecordImageEnhancementData(); filter.MaskWidth = this.txtMaskWidth.Text; filter.MaskHight = this.txtMaskHeight.Text; filter.Factor = this.txtFactor.Text; filter.FilterName = (ImageEnhancementDataType)this.cmbImageEnhancement.SelectedIndex; // 添加到 UserManager bool success = ImageEnhancementManager.Instance.AddUser(filter); if (success) { recordImageEnhancementDatas.Add(filter); //MessageBox.Show("用户添加成功!", "提示", // MessageBoxButtons.OK, MessageBoxIcon.Information); // 清空输入框 ClearInputFields(); } else { MessageBox.Show("添加用户失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } recordImageEnhancementDatas = ImageEnhancementManager.Instance.GetAllUsers(); this.dataGridViewIE.DataSource = recordImageEnhancementDatas; this.dataGridViewIE.AutoGenerateColumns = true; } private void btnDel_Click(object sender, EventArgs e) { // 检查是否有选中的滤波类型 if (cmbImageEnhancement.SelectedIndex < 0) { MessageBox.Show("请选择要删除的滤波类型!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } try { DataGridViewRow selectedRow = dataGridViewIE.SelectedRows[0]; string filterToDel = selectedRow.Cells[0].Value?.ToString(); ImageEnhancementDataType filterToDelete = (ImageEnhancementDataType)cmbImageEnhancement.SelectedIndex; // 查找对应的记录 RecordImageEnhancementData filterToRemove = null; // 从本地列表中查找 foreach (var filter in recordImageEnhancementDatas) { if (filter.FilterName.ToString() == filterToDel) { filterToRemove = filter; break; } } if (filterToRemove == null) { MessageBox.Show("未找到对应的记录!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 确认删除 DialogResult result = MessageBox.Show( $"确定要删除 '{filterToDel}' 记录吗?", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); // 默认选择"否" if (result == DialogResult.No) return; // 从管理器中删除 bool success = ImageEnhancementManager.Instance.DeleteUser(filterToRemove); if (success) { // 从本地列表中删除 recordImageEnhancementDatas.Remove(filterToRemove); MessageBox.Show("删除成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("删除失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } recordImageEnhancementDatas = ImageEnhancementManager.Instance.GetAllUsers(); this.dataGridViewIE.DataSource = recordImageEnhancementDatas; this.dataGridViewIE.AutoGenerateColumns = true; } catch (Exception ex) { MessageBox.Show("请选择要删除的算子"); } } /// /// 更新运行参数 /// public override void UpdataInputs() { //设置运行参数 double dResult = 0; int iResult = 0; if (cmbFixture.Text == "") Subject.Params.Fixture = new Fixture(); else if (IProcess.dicFixtures.ContainsKey(cmbFixture.Text)) Subject.Params.Fixture = IProcess.dicFixtures[cmbFixture.Text]; Type type = inputImageHSmartWindowControl.oRoi?.GetType(); switch (type) { case Type t when t == typeof(HRectangle2): HRectangle2 hRectangle2 = (HRectangle2)inputImageHSmartWindowControl.oRoi; Subject.Params.ROI = new HRectangle2(hRectangle2.X - Subject.Params.Fixture.X, hRectangle2.Y - Subject.Params.Fixture.Y , hRectangle2.Phi - Subject.Params.Fixture.Phi, hRectangle2.Width, hRectangle2.Height); break; case Type t when t == typeof(HCircle): HCircle hCircle = (HCircle)inputImageHSmartWindowControl.oRoi; Subject.Params.ROI = new HCircle(hCircle.X - Subject.Params.Fixture.X, hCircle.Y - Subject.Params.Fixture.Y, hCircle.Radius); break; case Type t when t == typeof(HSegment): HSegment hSegment = (HSegment)inputImageHSmartWindowControl.oRoi; Subject.Params.ROI = new HSegment(hSegment.StartX - Subject.Params.Fixture.X, hSegment.StartY - Subject.Params.Fixture.Y , hSegment.EndX - Subject.Params.Fixture.X, hSegment.EndY - Subject.Params.Fixture.Y); break; default: Subject.Params.ROI = new ROI(); break; } } /// /// 加载运行参数 /// public override void LoadParas() { this.BeginInvoke(new Action(() => { 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(HRectangle2): cmbTypeRoi.Text = RoiType.Rectangle2.ToString(); break; case Type t when t == typeof(HCircle): cmbTypeRoi.Text = RoiType.Circle.ToString(); break; case Type t when t == typeof(HSegment): cmbTypeRoi.Text = RoiType.Segment.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(HRectangle2): inputImageHSmartWindowControl.oRoi = new HRectangle2(Subject.Params.ROI.X + Subject.Params.Fixture.X, Subject.Params.ROI.Y + Subject.Params.Fixture.Y , Subject.Params.ROI.Phi + Subject.Params.Fixture.Phi, ((HRectangle2)Subject.Params.ROI).Width, ((HRectangle2)Subject.Params.ROI).Height); break; case Type t when t == typeof(HCircle): inputImageHSmartWindowControl.oRoi = new HCircle(Subject.Params.ROI.X + Subject.Params.Fixture.X, Subject.Params.ROI.Y + Subject.Params.Fixture.Y , ((HCircle)Subject.Params.ROI).Radius); break; case Type t when t == typeof(HSegment): inputImageHSmartWindowControl.oRoi = new HSegment(((HSegment)Subject.Params.ROI).StartX + Subject.Params.Fixture.X, ((HSegment)Subject.Params.ROI).StartY + Subject.Params.Fixture.Y , ((HSegment)Subject.Params.ROI).EndX + Subject.Params.Fixture.X, ((HSegment)Subject.Params.ROI).EndY + Subject.Params.Fixture.Y); break; default: inputImageHSmartWindowControl.oRoi = null; break; } })); } #region 工具栏按钮事件 /// /// 点击运行 /// /// /// 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) { 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); } #endregion #region ROI功能 /// /// 是否启用ROI /// /// /// 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(); } } /// /// 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.Rectangle2: inputImageHSmartWindowControl.oRoi = new HRectangle2(hv_imageWidth.TupleReal() / 2, hv_imageHeight.TupleReal() / 2, 0 , hv_imageWidth.TupleReal() / 4, hv_imageHeight.TupleReal() / 4); break; case RoiType.Circle: inputImageHSmartWindowControl.oRoi = new HCircle(hv_imageWidth.TupleReal() / 2, hv_imageHeight.TupleReal() / 2, hv_imageWidth.TupleReal() / 4); break; case RoiType.Segment: inputImageHSmartWindowControl.oRoi = new HSegment(0, 0, hv_imageWidth.TupleReal() / 4, hv_imageHeight.TupleReal() / 4); 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 { } } #endregion } }