using HalconDotNet;
|
using LB_SmartVisionCommon;
|
using LB_VisionControl;
|
using Newtonsoft.Json;
|
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;
|
|
namespace LB_VisionProcesses.Alogrithms.Halcon
|
{
|
public partial class HFilterToolEdit : TAlgorithmEdit
|
{
|
List<RecordFilterData> recordFilterDatas = new List<RecordFilterData>();
|
private int rowriginalHeight;
|
public HFilterToolEdit(HFilterTool subject = null)
|
{
|
if (subject != null && subject is HFilterTool)
|
Subject = subject;
|
else
|
Subject = new HFilterTool();
|
|
//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; //45;
|
recordFilterDatas = FilterManager.Instance.GetAllUsers();
|
|
InitializeComboBox();
|
InitializeDataGridView();
|
|
|
|
this.dataGridViewFi.DataSource = recordFilterDatas;
|
this.dataGridViewFi.AutoGenerateColumns = true;
|
}
|
|
private void InitializeComboBox()
|
{
|
// 添加权限选项
|
foreach (var item in Enum.GetValues(typeof(FilterType)))
|
{
|
cmbFilterType.Items.Add(item.ToString());
|
}
|
|
// 设置默认选择项
|
cmbFilterType.SelectedIndex = 0;
|
}
|
|
private void InitializeDataGridView()
|
{
|
this.dataGridViewFi.DataSource = recordFilterDatas;
|
|
// 设置DataGridView列宽
|
dataGridViewFi.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
|
}
|
|
/// <summary>
|
/// 控件加载事件
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void HFilterToolEdit_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(FilterType)))
|
// cmbFilterType.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();
|
cmbFilterType.Text = FilterType.均值滤波_MeanImage.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();
|
txtGuassSize.Clear();
|
cmbFilterType.SelectedIndex = 0;
|
}
|
|
/// <summary>
|
/// 添加算子
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void btnAdd_Click(object sender, EventArgs e)
|
{
|
// 验证输入
|
switch (cmbFilterType.SelectedIndex)
|
{
|
case 0:
|
if (string.IsNullOrWhiteSpace(txtMaskWidth.Text) || string.IsNullOrWhiteSpace(txtMaskHeight.Text))
|
{
|
MessageBox.Show("请填写所有必填字段!", "提示",
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
return;
|
}
|
break;
|
case 1:
|
if (string.IsNullOrWhiteSpace(txtGuassSize.Text))
|
{
|
MessageBox.Show("请填写所有必填字段!", "提示",
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
return;
|
}
|
break;
|
case 2:
|
if (string.IsNullOrWhiteSpace(txtMaskWidth.Text) || string.IsNullOrWhiteSpace(txtMaskHeight.Text))
|
{
|
MessageBox.Show("请填写所有必填字段!", "提示",
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
return;
|
}
|
break;
|
}
|
|
RecordFilterData filter = new RecordFilterData();
|
filter.MaskWidth = this.txtMaskWidth.Text;
|
filter.MaskHight = this.txtMaskHeight.Text;
|
filter.GaussSize = this.txtGuassSize.Text;
|
filter.FilterName = (FilterType)this.cmbFilterType.SelectedIndex;
|
// 添加到 UserManager
|
bool success = FilterManager.Instance.AddFilter(filter);
|
if (success)
|
{
|
recordFilterDatas.Add(filter);
|
//MessageBox.Show("用户添加成功!", "提示",
|
// MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
// 清空输入框
|
ClearInputFields();
|
}
|
else
|
{
|
MessageBox.Show("添加用户失败!", "错误",
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
}
|
recordFilterDatas = FilterManager.Instance.GetAllUsers();
|
this.dataGridViewFi.DataSource = recordFilterDatas;
|
this.dataGridViewFi.AutoGenerateColumns = true;
|
}
|
|
private void btnDel_Click(object sender, EventArgs e)
|
{
|
// 检查是否有选中的滤波类型
|
if (cmbFilterType.SelectedIndex < 0)
|
{
|
MessageBox.Show("请选择要删除的滤波类型!", "提示",
|
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
return;
|
}
|
|
try
|
{
|
DataGridViewRow selectedRow = dataGridViewFi.SelectedRows[0];
|
string filterToDel = selectedRow.Cells[0].Value?.ToString();
|
|
|
FilterType filterToDelete = (FilterType)cmbFilterType.SelectedIndex;
|
|
// 查找对应的记录
|
RecordFilterData filterToRemove = null;
|
|
// 从本地列表中查找
|
foreach (var filter in recordFilterDatas)
|
{
|
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 = FilterManager.Instance.DeleteUser(filterToRemove);
|
|
if (success)
|
{
|
// 从本地列表中删除
|
recordFilterDatas.Remove(filterToRemove);
|
|
MessageBox.Show("删除成功!", "提示",
|
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
}
|
else
|
{
|
MessageBox.Show("删除失败!", "错误",
|
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
}
|
recordFilterDatas = FilterManager.Instance.GetAllUsers();
|
this.dataGridViewFi.DataSource = recordFilterDatas;
|
this.dataGridViewFi.AutoGenerateColumns = true;
|
}
|
catch (Exception ex)
|
{
|
MessageBox.Show("请选择要删除的算子");
|
}
|
}
|
#region 算法选择下拉框
|
private void cmbFilterType_SelectedIndexChanged(object sender, EventArgs e)
|
{
|
ComboBox cb = sender as ComboBox;
|
|
if (cb.SelectedIndex == 0)
|
{
|
ShowRow1();
|
}
|
else if (cb.SelectedIndex == 1)
|
{
|
ShowRow2();
|
}
|
else
|
{
|
ShowRow1();
|
}
|
}
|
private void ShowRow1()
|
{
|
// 显示Row2(恢复高度)
|
tableLayoutPanel4.RowStyles[1].SizeType = SizeType.Absolute;
|
tableLayoutPanel4.RowStyles[1].Height = rowriginalHeight;
|
tableLayoutPanel4.RowStyles[2].SizeType = SizeType.Absolute;
|
tableLayoutPanel4.RowStyles[2].Height = 0;
|
|
// 显示Row2中的控件
|
foreach (Control ctrl in tableLayoutPanel4.Controls)
|
{
|
int row = tableLayoutPanel4.GetRow(ctrl);
|
if (row == 1)
|
ctrl.Visible = true;
|
if (row == 2)
|
ctrl.Visible = false;
|
}
|
}
|
|
private void ShowRow2()
|
{
|
// 显示Row2(恢复高度)
|
tableLayoutPanel4.RowStyles[1].SizeType = SizeType.Absolute;
|
tableLayoutPanel4.RowStyles[1].Height = 0;
|
tableLayoutPanel4.RowStyles[2].SizeType = SizeType.Absolute;
|
tableLayoutPanel4.RowStyles[2].Height = rowriginalHeight;
|
|
// 显示Row2中的控件
|
foreach (Control ctrl in tableLayoutPanel4.Controls)
|
{
|
int row = tableLayoutPanel4.GetRow(ctrl);
|
if (row == 1)
|
ctrl.Visible = false;
|
if (row == 2)
|
ctrl.Visible = true;
|
}
|
}
|
#endregion
|
|
#region ROI
|
/// <summary>
|
/// 更新运行参数
|
/// </summary>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 加载运行参数
|
/// </summary>
|
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;
|
}
|
base.LoadParas();
|
}));
|
}
|
#endregion
|
|
#region 工具栏按钮事件
|
/// <summary>
|
/// 点击运行
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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();
|
}));
|
}
|
|
/// <summary>
|
/// 工具栏“导图”
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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;
|
}
|
}
|
}
|
}
|
/// <summary>
|
/// 工具栏“保存”
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
public override void btnSaveParas_Click(object sender, EventArgs e) { base.btnSaveParas_Click(sender, e); }
|
#endregion
|
|
#region ROI功能
|
/// <summary>
|
/// 是否启用ROI
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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();
|
}
|
}
|
/// <summary>
|
/// ROI下拉框改变事件
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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
|
|
|
}
|
}
|