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();
|
}
|
|
/// <summary>
|
/// 控件加载事件
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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";
|
}
|
|
/// <summary>
|
/// 更新运行参数
|
/// </summary>
|
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();
|
}
|
|
/// <summary>
|
/// 加载运行参数
|
/// </summary>
|
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;
|
}
|
}));
|
}
|
|
/// <summary>
|
/// 更新输出结果
|
/// </summary>
|
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"]);
|
}));
|
}
|
|
/// <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();
|
}));
|
}
|
|
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 { }
|
}));
|
}
|
}
|
}
|