using HalconDotNet;
using LB_VisionControl;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using static LB_VisionProcesses.Alogrithms.Halcon.HFindModelTool;
namespace LB_VisionProcesses.Alogrithms.Halcon
{
public partial class HFindModelToolEdit : TAlgorithmEdit
{
public HFindModelToolEdit(HFindModelTool subject = null)
{
if (subject != null && subject is HFindModelTool)
Subject = subject;
else
Subject = new HFindModelTool();
this.Dock = DockStyle.Fill;
InitializeComponent();
}
public HWindowControl modelImageHWindowControl = new HWindowControl();
public UserHSmartWindowControl createModelImageHSmartWindowControl = new UserHSmartWindowControl();
private bool isLeftDown = false;
private int MaskSize
{
get
{
if (int.TryParse(txtMaskSize.Text, out int size))
return size;
else
return 10;
}
}
private HObject Mask = new HObject();
private HObject FirstModelImage = new HObject();
private HObject TempModelImage = new HObject();
///
/// 控件加载事件
///
///
///
private void HFindModelToolEdit_Load(object sender, EventArgs e)
{
pnlInputImage.Controls.Add(inputImageHSmartWindowControl);
inputImageHSmartWindowControl.Dock = DockStyle.Fill;
pnlRecordImage.Controls.Add(recordImageHSmartWindowControl);
recordImageHSmartWindowControl.Dock = DockStyle.Fill;
pnlCreateModelImage.Controls.Add(createModelImageHSmartWindowControl);
createModelImageHSmartWindowControl.Dock = DockStyle.Fill;
grpModel.Controls.Add(modelImageHWindowControl);
modelImageHWindowControl.Dock = DockStyle.Fill;
// 设置轮廓默认为绿色
HOperatorSet.SetColor(modelImageHWindowControl.HalconWindow, "red");
HOperatorSet.SetLineWidth(modelImageHWindowControl.HalconWindow, 5);
modelImageHWindowControl.MouseDown += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
isLeftDown = true;
};
modelImageHWindowControl.MouseUp += (sender, e) =>
{
if (e.Button == MouseButtons.Left)
isLeftDown = true;
};
modelImageHWindowControl.MouseMove += (sender, e) =>
{
if (e.Button == MouseButtons.Left && isLeftDown && ckbStartMask.Checked)
{
// 点击鼠标
if (TempModelImage != null && TempModelImage.IsInitialized())
{
try
{
HOperatorSet.GetMposition(modelImageHWindowControl.HalconWindow, out HTuple row, out HTuple col, out HTuple button_state);
if (row.Length != 0 && col.Length != 0)
{
HTuple hv_color = new HTuple();
hv_color[0] = 0;
hv_color[1] = 0;
hv_color[2] = 255;
HOperatorSet.GenCircle(out HObject ho_Circle, row, col, MaskSize);
if (!Mask.IsInitialized())
Mask = ho_Circle;
else
HOperatorSet.Union2(ho_Circle, Mask, out Mask);
HOperatorSet.GetImageSize(TempModelImage, out HTuple width, out HTuple height);
HOperatorSet.GenRectangle1(out HObject allROI, 0, 0, height, width);
HOperatorSet.Difference(allROI, Mask, out HObject subROI);
HOperatorSet.ReduceDomain(TempModelImage, subROI, out HObject ModelImage);
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispImage(ModelImage, modelImageHWindowControl.HalconWindow);
}
}
catch { }
}
}
};
ckbStartMask.CheckedChanged += (sender, e) =>
{
try
{
if (ckbStartMask.Checked)
{
// 点击鼠标
if (FirstModelImage == null || !FirstModelImage.IsInitialized())
FirstModelImage = ((HFindModelTool)Subject).ModelID.hoImage.CopyObj(1, -1); ;
TempModelImage = FirstModelImage.CopyObj(1, -1);
Mask.Dispose();
Mask = new HObject();
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispImage(FirstModelImage, modelImageHWindowControl.HalconWindow);
}
else
{
DialogResult res = MessageBox.Show("是否使用掩膜图片保存模板?", "提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); //保存结果信息
/// 参数1:显示文本,参数2:标题,参数3:按键类型,参数4:显示图标
if (res == DialogResult.Yes) //保存
{
try
{
if (TempModelImage != null && TempModelImage is HObject)
{
if (Enum.TryParse(cmbModelType.Text, out ModelType modelType))
{
string NumLevels = this.dtxtModelParam1.Text;
string AngleStep = this.dtxtModelParam2.Text;
double AngleStart = Convert.ToDouble(this.dtxtModelParam3.Text);
double AngleExtent = Convert.ToDouble(this.dtxtModelParam4.Text);
double ScaleRMin = Convert.ToDouble(this.dtxtModelParam5.Text);
double ScaleRMax = Convert.ToDouble(this.dtxtModelParam6.Text);
double ScaleCMin = Convert.ToDouble(this.dtxtModelParam7.Text);
double ScaleCMax = Convert.ToDouble(this.dtxtModelParam8.Text);
string Optimization = this.dtxtModelParam9.Text;
string Metric = this.dtxtModelParam10.Text;
string Contrast = this.dtxtModelParam11.Text;
int MinContrast = Convert.ToInt16(this.dtxtModelParam12.Text);
//HRectangle2 ROI = (HRectangle2)createModelImageHSmartWindowControl.oRoi;
//HOperatorSet.GenRectangle2(out HObject hRectangle, ROI.Row, ROI.Column, ROI.Phi
// , ROI.SemiLength1, ROI.SemiLength2);
HObject hoDomainImage = FirstModelImage as HObject;
HTuple hv_Channels = new HTuple();
//判断是否为灰度图
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
try
{
HOperatorSet.CountChannels(hoDomainImage, out hv_Channels);
if (hv_Channels.TupleInt() != 1)
HOperatorSet.Rgb1ToGray(hoDomainImage, out hoDomainImage);
//转换后再次检查是否为灰度图
HOperatorSet.CountChannels(hoDomainImage, out hv_Channels);
if (hv_Channels.TupleInt() != 1)
HOperatorSet.Rgb1ToGray(hoDomainImage, out hoDomainImage);
}
catch { }
}
HOperatorSet.GetImageSize(FirstModelImage, out HTuple width, out HTuple height);
HOperatorSet.GenRectangle1(out HObject allROI, 0, 0, height, width);
HOperatorSet.Difference(allROI, Mask, out HObject subROI);
HOperatorSet.ReduceDomain(FirstModelImage, subROI, out HObject ModelImage);
bool bCreateModel = false;
switch (modelType)
{
case ModelType.局部变形模板:
bCreateModel = ((HFindModelTool)Subject).CreateModel
(ModelImage, modelType, NumLevels
, AngleStart, AngleExtent, AngleStep
, ScaleRMin, ScaleRMax, "auto"
, ScaleCMin, ScaleCMax, "auto"
, Optimization, Metric, Contrast, MinContrast);
break;
case ModelType.各向异形模板:
default:
bCreateModel = ((HFindModelTool)Subject).CreateModel
(ModelImage, modelType, NumLevels
, AngleStart, AngleExtent, AngleStep
, ScaleRMin, ScaleRMax, "auto"
, ScaleCMin, ScaleCMax, "auto"
, Optimization, Metric, Contrast, MinContrast);
break;
}
if (bCreateModel)
{
HObject ho_ModelContours = new HObject();
switch (((HFindModelTool)Subject).ModelID.Type)
{
case ModelType.局部变形模板:
HOperatorSet.GetDeformableModelContours(out ho_ModelContours, ((HFindModelTool)Subject).ModelID.hvModel, 1);
break;
case ModelType.各向异形模板:
default:
HOperatorSet.GetShapeModelContours(out ho_ModelContours, ((HFindModelTool)Subject).ModelID.hvModel, 1);
break;
}
HOperatorSet.GetImageSize(((HFindModelTool)Subject).ModelID.hoImage, out HTuple hv_Width, out HTuple hv_Height);
HOperatorSet.VectorAngleToRigid(-hv_Height / 2, -hv_Width / 2, 0, 0, 0, 0, out HTuple hv_HomMat2D);
HOperatorSet.AffineTransContourXld(ho_ModelContours, out ho_ModelContours, hv_HomMat2D);
//建模成功导航到子页
parasTabControl.SelectedTab = tabPageRunParas;
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispImage(((HFindModelTool)Subject).ModelID.hoImage, modelImageHWindowControl.HalconWindow);
TAlgorithm.SetColor(modelImageHWindowControl.HalconWindow, "red");
TAlgorithm.DispObj(ho_ModelContours, modelImageHWindowControl.HalconWindow);
TAlgorithm.DispMsg("创建模板成功", modelImageHWindowControl.HalconWindow, true);
}
else
{
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispMsg("创建模板失败", modelImageHWindowControl.HalconWindow, false);
}
}
}
TempModelImage.Dispose();
}
catch
{
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispMsg("创建模板失败", modelImageHWindowControl.HalconWindow, false);
}
}
}
}
catch { }
};
//cmbModelType.SelectedIndex = cmbModelType.FindString("形状");
UpdataInputsUI();
// 设置显示样式
toolTip.AutoPopDelay = 5000;//提示信息的可见时间
toolTip.InitialDelay = 500;//事件触发多久后出现提示
toolTip.ReshowDelay = 500;//指针从一个控件移向另一个控件时,经过多久才会显示下一个提示框
toolTip.ShowAlways = true;//是否显示提示框
//遍历可以选择的Roi类型枚举
foreach (var value in Enum.GetValues(typeof(RoiType)))
cmbTypeRoi.Items.Add(value.ToString());
//遍历可以选择的Fixture枚举
cmbFixture.Items.Add("");
foreach (string value in IProcess.dicFixtures.Keys)
cmbFixture.Items.Add(value.ToString());
//遍历可以选择的Model类型枚举
foreach (var value in Enum.GetValues(typeof(ModelType)))
cmbModelType.Items.Add(value.ToString());
cmbTypeRoi.Text = RoiType.None.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;
cmbModelType.Text = ((HFindModelTool)Subject).ModelID.Type.ToString();
if (Enum.TryParse(cmbModelType.SelectedItem.ToString(), out ModelType modelType))
{
switch (modelType)
{
case ModelType.局部变形模板:
//, AngleStart / 180.0 * Math.PI, AngleExtent / 180.0 * Math.PI
//, ScaleRMin, ScaleRMax
//, ScaleCMin, ScaleCMax
//, MinScore, NumMatches, MaxOverlap
//, NumLevels == "auto" ? NumLevels : Convert.ToInt32(NumLevels)
//, Greediness, ResultType, new HTuple(), new HTuple()
//, out hv_Score, out hv_CenterRow, out hv_CenterColumn);
#region 输入参数
Subject.Params.Inputs["AngleStart"] = dtxtInputParam1.Text;
Subject.Params.Inputs["AngleExtent"] = dtxtInputParam2.Text;
Subject.Params.Inputs["ScaleRMin"] = dtxtInputParam3.Text;
Subject.Params.Inputs["ScaleRMax"] = dtxtInputParam4.Text;
Subject.Params.Inputs["ScaleCMin"] = dtxtInputParam5.Text;
Subject.Params.Inputs["ScaleCMax"] = dtxtInputParam6.Text;
Subject.Params.Inputs["MinScore"] = dtxtInputParam7.Text;
Subject.Params.Inputs["NumMatches"] = dtxtInputParam8.Text;
Subject.Params.Inputs["MaxOverlap"] = dtxtInputParam9.Text;
Subject.Params.Inputs["ResultType"] = dtxtInputParam10.Text;
Subject.Params.Inputs["NumLevels"] = dtxtInputParam11.Text;
Subject.Params.Inputs["Greediness"] = dtxtInputParam12.Text;
Subject.Params.Inputs["MinCount"] = dtxtInputParam13.Text;
Subject.Params.Inputs["MaxCount"] = dtxtInputParam14.Text;
#endregion
break;
case ModelType.各向异形模板:
default:
//, AngleStart / 180.0 * Math.PI, AngleExtent / 180.0 * Math.PI
//, ScaleRMin, ScaleRMax
//, ScaleCMin, ScaleCMax
//, MinScore, NumMatches, MaxOverlap, SubPixel
//, NumLevels == "auto" ? NumLevels : Convert.ToInt32(NumLevels)
//, Greediness
#region 输入参数
Subject.Params.Inputs["AngleStart"] = dtxtInputParam1.Text;
Subject.Params.Inputs["AngleExtent"] = dtxtInputParam2.Text;
Subject.Params.Inputs["ScaleRMin"] = dtxtInputParam3.Text;
Subject.Params.Inputs["ScaleRMax"] = dtxtInputParam4.Text;
Subject.Params.Inputs["ScaleCMin"] = dtxtInputParam5.Text;
Subject.Params.Inputs["ScaleCMax"] = dtxtInputParam6.Text;
Subject.Params.Inputs["MinScore"] = dtxtInputParam7.Text;
Subject.Params.Inputs["NumMatches"] = dtxtInputParam8.Text;
Subject.Params.Inputs["MaxOverlap"] = dtxtInputParam9.Text;
Subject.Params.Inputs["SubPixel"] = dtxtInputParam10.Text;
Subject.Params.Inputs["NumLevels"] = dtxtInputParam11.Text;
Subject.Params.Inputs["Greediness"] = dtxtInputParam12.Text;
Subject.Params.Inputs["MinCount"] = dtxtInputParam13.Text;
Subject.Params.Inputs["MaxCount"] = dtxtInputParam14.Text;
#endregion
break;
}
//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(() =>
{
cmbModelType.Text = ((HFindModelTool)Subject).ModelID.Type.ToString();
if (Enum.TryParse(cmbModelType.Text, out ModelType modelType))
{
switch (modelType)
{
case ModelType.局部变形模板:
//, AngleStart / 180.0 * Math.PI, AngleExtent / 180.0 * Math.PI
//, ScaleRMin, ScaleRMax
//, ScaleCMin, ScaleCMax
//, MinScore, NumMatches, MaxOverlap
//, NumLevels == "auto" ? NumLevels : Convert.ToInt32(NumLevels)
//, Greediness, ResultType, new HTuple(), new HTuple()
#region 输入参数
dtxtInputParam1.Text = Subject.Params.Inputs["AngleStart"].ToString();
dtxtInputParam2.Text = Subject.Params.Inputs["AngleExtent"].ToString();
dtxtInputParam3.Text = Subject.Params.Inputs["ScaleRMin"].ToString();
dtxtInputParam4.Text = Subject.Params.Inputs["ScaleRMax"].ToString();
dtxtInputParam5.Text = Subject.Params.Inputs["ScaleCMin"].ToString();
dtxtInputParam6.Text = Subject.Params.Inputs["ScaleCMax"].ToString();
dtxtInputParam7.Text = Subject.Params.Inputs["MinScore"].ToString();
dtxtInputParam8.Text = Subject.Params.Inputs["NumMatches"].ToString();
dtxtInputParam9.Text = Subject.Params.Inputs["MaxOverlap"].ToString();
dtxtInputParam10.Text = Subject.Params.Inputs["ResultType"].ToString();
dtxtInputParam11.Text = Subject.Params.Inputs["NumLevels"].ToString();
dtxtInputParam12.Text = Subject.Params.Inputs["Greediness"].ToString();
dtxtInputParam13.Text = Subject.Params.Inputs["MinCount"].ToString();
dtxtInputParam14.Text = Subject.Params.Inputs["MaxCount"].ToString();
#endregion
break;
case ModelType.各向异形模板:
default:
#region 输入参数
dtxtInputParam1.Text = Subject.Params.Inputs["AngleStart"].ToString();
dtxtInputParam2.Text = Subject.Params.Inputs["AngleExtent"].ToString();
dtxtInputParam3.Text = Subject.Params.Inputs["ScaleRMin"].ToString();
dtxtInputParam4.Text = Subject.Params.Inputs["ScaleRMax"].ToString();
dtxtInputParam5.Text = Subject.Params.Inputs["ScaleCMin"].ToString();
dtxtInputParam6.Text = Subject.Params.Inputs["ScaleCMax"].ToString();
dtxtInputParam7.Text = Subject.Params.Inputs["MinScore"].ToString();
dtxtInputParam8.Text = Subject.Params.Inputs["NumMatches"].ToString();
dtxtInputParam9.Text = Subject.Params.Inputs["MaxOverlap"].ToString();
dtxtInputParam10.Text = Subject.Params.Inputs["ResultType"].ToString();
dtxtInputParam11.Text = Subject.Params.Inputs["NumLevels"].ToString();
dtxtInputParam12.Text = Subject.Params.Inputs["Greediness"].ToString();
dtxtInputParam13.Text = Subject.Params.Inputs["MinCount"].ToString();
dtxtInputParam14.Text = Subject.Params.Inputs["MaxCount"].ToString();
#endregion
break;
}
}
if (Subject.InputImage != null && Subject.InputImage is HImage)
{
using (HImage hImage = (HImage)Subject.InputImage)
{
hImage.GetImageSize(out HTuple ho_ImageWidth, out HTuple ho_ImageHeight);
inputImageHSmartWindowControl.ShowHoImage(hImage);
}
}
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;
}
parasTabControl.SelectedTab = tabPageRunParas;
ShowModel(((HFindModelTool)Subject).ModelID);
parasTabControl.SelectedTab = tabPageInputParas;
}));
}
///
/// 更新输出结果
///
public override void UpdataOutputs()
{
this.BeginInvoke(new Action(() =>
{
//存在反序列化错乱的情况需要使用自定义的转换器
dtxtCenterX.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["CenterX"]);
dtxtCenterY.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["CenterY"]);
dtxtPhi.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["Phi"]);
dtxtScore.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["Score"]);
dtxtCount.Text = ProcessParams.ConvertToString(Subject.Params.Outputs["Count"]);
}));
}
///
/// 点击运行
///
///
///
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 HImage)
{
using (HImage hImage = (HImage)Subject.InputImage)
{
hImage.GetImageSize(out HTuple ho_ImageWidth, out HTuple ho_ImageHeight);
recordImageHSmartWindowControl.ShowHoImage(hImage);
}
}
//先判断子类再判断父类
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)
{
//保存前需要更新输入参数Inputs
UpdataInputs();
// 创建 SaveFileDialog 实例
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
// 设置对话框标题
saveFileDialog.Title = "保存文件";
// 设置默认路径
saveFileDialog.InitialDirectory = System.Windows.Forms.Application.StartupPath;
// 设置文件类型过滤器
saveFileDialog.Filter = "文本文件 (*.json)|*.json|所有文件 (*.*)|*.*";
// 设置默认文件名
saveFileDialog.FileName = Subject.strProcessName + ".json";
// 显示对话框并检查用户是否点击了保存按钮
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
// 获取用户选择的文件路径
string fullPath = saveFileDialog.FileName;
Debug.WriteLine("选择的文件路径是: " + fullPath);
Subject.strProcessName = Path.GetFileNameWithoutExtension(fullPath);
((HFindModelTool)Subject).Save(Path.GetDirectoryName(fullPath));
}
}
}
public override void btnLoadParas_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
// 设置文件对话框的属性
openFileDialog.Multiselect = false; // 不允许多选
// 设置文件过滤器,支持多种文件类型
openFileDialog.Filter = "Ini Files (*.json)|*.json|All Files (*.*)|*.*";
// 显示文件对话框
DialogResult result = openFileDialog.ShowDialog();
// 处理对话框返回结果
if (result == DialogResult.OK)
{
// 获取用户选择的文件名
string[] selectedFiles = openFileDialog.FileNames;
if (selectedFiles.Length > 0)
{
((HFindModelTool)Subject).Load(selectedFiles[0]);
LoadParas();
}
}
}
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.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 { }
}
private System.Windows.Forms.ToolTip toolTip = new System.Windows.Forms.ToolTip();
private void ShowToolTip(Control control, string message) => toolTip.SetToolTip(control, message);
// 通过反射清除所有事件处理程序
public void ClearAllEventHandlers()
{
// 获取事件字段
FieldInfo field = typeof(Label).GetField("MouseHover", BindingFlags.NonPublic | BindingFlags.Instance);
if (field != null)
{
// 将事件字段设为 null,移除所有事件处理程序
field.SetValue(this, null);
}
}
private void cmbModelType_SelectedIndexChanged(object sender, EventArgs e) => UpdataInputsUI();
void UpdataInputsUI()
{
this.BeginInvoke(() =>
{
#region 清空输入
this.lblInputParam1.Visible = false;
this.lblInputParam2.Visible = false;
this.lblInputParam3.Visible = false;
this.lblInputParam4.Visible = false;
this.lblInputParam5.Visible = false;
this.lblInputParam6.Visible = false;
this.lblInputParam7.Visible = false;
this.lblInputParam8.Visible = false;
this.lblInputParam9.Visible = false;
this.lblInputParam10.Visible = false;
this.lblInputParam11.Visible = false;
this.lblInputParam12.Visible = false;
this.lblInputParam13.Visible = false;
this.lblInputParam14.Visible = false;
this.lblInputParam15.Visible = false;
this.lblInputParam16.Visible = false;
this.lblInputParam17.Visible = false;
this.lblInputParam18.Visible = false;
this.dtxtInputParam1.Visible = false;
this.dtxtInputParam2.Visible = false;
this.dtxtInputParam3.Visible = false;
this.dtxtInputParam4.Visible = false;
this.dtxtInputParam5.Visible = false;
this.dtxtInputParam6.Visible = false;
this.dtxtInputParam7.Visible = false;
this.dtxtInputParam8.Visible = false;
this.dtxtInputParam9.Visible = false;
this.dtxtInputParam10.Visible = false;
this.dtxtInputParam11.Visible = false;
this.dtxtInputParam12.Visible = false;
this.dtxtInputParam13.Visible = false;
this.dtxtInputParam14.Visible = false;
this.dtxtInputParam15.Visible = false;
this.dtxtInputParam16.Visible = false;
this.dtxtInputParam17.Visible = false;
this.dtxtInputParam18.Visible = false;
#endregion
#region 清空模板
this.lblModelParam1.Visible = false;
this.lblModelParam2.Visible = false;
this.lblModelParam3.Visible = false;
this.lblModelParam4.Visible = false;
this.lblModelParam5.Visible = false;
this.lblModelParam6.Visible = false;
this.lblModelParam7.Visible = false;
this.lblModelParam8.Visible = false;
this.lblModelParam9.Visible = false;
this.lblModelParam10.Visible = false;
this.lblModelParam11.Visible = false;
this.lblModelParam12.Visible = false;
this.lblModelParam13.Visible = false;
this.lblModelParam14.Visible = false;
this.lblModelParam15.Visible = false;
this.lblModelParam16.Visible = false;
this.lblModelParam17.Visible = false;
this.lblModelParam18.Visible = false;
this.dtxtModelParam1.Visible = false;
this.dtxtModelParam2.Visible = false;
this.dtxtModelParam3.Visible = false;
this.dtxtModelParam4.Visible = false;
this.dtxtModelParam5.Visible = false;
this.dtxtModelParam6.Visible = false;
this.dtxtModelParam7.Visible = false;
this.dtxtModelParam8.Visible = false;
this.dtxtModelParam9.Visible = false;
this.dtxtModelParam10.Visible = false;
this.dtxtModelParam11.Visible = false;
this.dtxtModelParam12.Visible = false;
this.dtxtModelParam13.Visible = false;
this.dtxtModelParam14.Visible = false;
this.dtxtModelParam15.Visible = false;
this.dtxtModelParam16.Visible = false;
this.dtxtModelParam17.Visible = false;
this.dtxtModelParam18.Visible = false;
#endregion
ClearAllEventHandlers();
if (Enum.TryParse(cmbModelType.Text, out ModelType modelType))
{
switch (modelType)
{
case ModelType.局部变形模板:
//, AngleStart / 180.0 * Math.PI, AngleExtent / 180.0 * Math.PI
//, ScaleRMin, ScaleRMax
//, ScaleCMin, ScaleCMax
//, MinScore, NumMatches, MaxOverlap
//, NumLevels == "auto" ? NumLevels : Convert.ToInt32(NumLevels)
//, Greediness, ResultType, new HTuple(), new HTuple()
#region 输入参数
//, AngleStart / 180.0 * Math.PI, AngleExtent / 180.0 * Math.PI
this.lblInputParam1.Text = "起始角度";
this.dtxtInputParam1.Text = Subject.Params.Inputs["AngleStart"].ToString();
this.lblInputParam1.Visible = true;
this.dtxtInputParam1.Visible = true;
this.dtxtInputParam1.Enabled = true;
lblInputParam1.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的起始角度AngleStart");
this.lblInputParam2.Text = "角度范围";
this.dtxtInputParam2.Text = Subject.Params.Inputs["AngleExtent"].ToString();
this.lblInputParam2.Visible = true;
this.dtxtInputParam2.Visible = true;
this.dtxtInputParam2.Enabled = true;
lblInputParam2.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的角度范围AngleExtent,'0'表示无角度搜索");
//, ScaleRMin, ScaleRMax
this.lblInputParam3.Text = "纵向缩放最小值";
this.dtxtInputParam3.Text = Subject.Params.Inputs["ScaleRMin"].ToString();
this.lblInputParam3.Visible = true;
this.dtxtInputParam3.Visible = true;
this.dtxtInputParam3.Enabled = true;
lblInputParam3.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最小值ScaleRMin");
this.lblInputParam4.Text = "纵向缩放最大值";
this.dtxtInputParam4.Text = Subject.Params.Inputs["ScaleRMax"].ToString();
this.lblInputParam4.Visible = true;
this.dtxtInputParam4.Visible = true;
this.dtxtInputParam4.Enabled = true;
lblInputParam4.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最大值ScaleRMax");
//, ScaleCMin, ScaleCMax
this.lblInputParam5.Text = "横向缩放最小值";
this.dtxtInputParam5.Text = Subject.Params.Inputs["ScaleCMin"].ToString();
this.lblInputParam5.Visible = true;
this.dtxtInputParam5.Visible = true;
this.dtxtInputParam5.Enabled = true;
lblInputParam5.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最小值ScaleCMin");
this.lblInputParam6.Text = "横向缩放最大值";
this.dtxtInputParam6.Text = Subject.Params.Inputs["ScaleCMax"].ToString();
this.lblInputParam6.Visible = true;
this.dtxtInputParam6.Visible = true;
this.dtxtInputParam6.Enabled = true;
lblInputParam6.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最大值ScaleCMax");
//, MinScore, NumMatches, MaxOverlap, ResultType
this.lblInputParam7.Text = "最小分数";
this.dtxtInputParam7.Text = Subject.Params.Inputs["MinScore"].ToString();
this.lblInputParam7.Visible = true;
this.dtxtInputParam7.Visible = true;
this.dtxtInputParam7.Enabled = true;
lblInputParam7.MouseHover += (s, e) => ShowToolTip((Control)s, "被找到的模板最小分数MinScore");
this.lblInputParam8.Text = "期望个数";
this.dtxtInputParam8.Text = Subject.Params.Inputs["NumMatches"].ToString();
this.lblInputParam8.Visible = true;
this.dtxtInputParam8.Visible = true;
this.dtxtInputParam8.Enabled = true;
lblInputParam8.MouseHover += (s, e) => ShowToolTip((Control)s, "要找到的模板最多的实例数NumMatches,'0'则找到所有可能的匹配");
this.lblInputParam9.Text = "最大重叠比例";
this.dtxtInputParam9.Text = Subject.Params.Inputs["MaxOverlap"].ToString();
this.lblInputParam9.Visible = true;
this.dtxtInputParam9.Visible = true;
this.dtxtInputParam9.Enabled = true;
lblInputParam9.MouseHover += (s, e) => ShowToolTip((Control)s, "允许找到的模型实例的最大重叠比例MaxOverlap[较小的值会避免找到多个相似的匹配]");
this.lblInputParam10.Text = "ResultType";
this.dtxtInputParam10.Text = Subject.Params.Inputs["ResultType"]?.ToString();
this.lblInputParam10.Visible = true;
this.dtxtInputParam10.Visible = true;
this.dtxtInputParam10.Enabled = false;
lblInputParam10.MouseHover += (s, e) => ShowToolTip((Control)s, "计算精度的设置ResultType['1'得到亚像素精度]");
//, NumLevels == "auto" ? NumLevels : Convert.ToInt32(NumLevels)
//, Greediness, , new HTuple(), new HTuple()
this.lblInputParam11.Text = "搜索时金字塔的层级";
this.dtxtInputParam11.Text = "0";
this.lblInputParam11.Visible = true;
this.dtxtInputParam11.Visible = true;
this.dtxtInputParam11.Enabled = false;
lblInputParam11.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时金字塔的层级");
this.lblInputParam12.Text = "贪婪度";
this.dtxtInputParam12.Text = Subject.Params.Inputs["Greediness"]?.ToString();
this.lblInputParam12.Visible = true;
this.dtxtInputParam12.Visible = true;
this.dtxtInputParam12.Enabled = true;
lblInputParam12.MouseHover += (s, e) => ShowToolTip((Control)s, "贪婪度,越高速度越快[一般都设为0.8,太大容易出现找不到的情况]");
this.lblInputParam13.Text = "最小数量";
this.dtxtInputParam13.Text = Subject.Params.Inputs["MinCount"]?.ToString();
this.lblInputParam13.Visible = true;
this.dtxtInputParam13.Visible = true;
this.dtxtInputParam13.Enabled = true;
lblInputParam13.MouseHover += (s, e) => ShowToolTip((Control)s, "匹配结果要求的最小数量");
this.lblInputParam14.Text = "最大数量";
this.dtxtInputParam14.Text = Subject.Params.Inputs["MaxCount"]?.ToString();
this.lblInputParam14.Visible = true;
this.dtxtInputParam14.Visible = true;
this.dtxtInputParam14.Enabled = true;
lblInputParam14.MouseHover += (s, e) => ShowToolTip((Control)s, "匹配结果要求的最大数量");
#endregion
//UpdataInputs();
//NumLevels == "auto" ? NumLevels : Convert.ToInt16(NumLevels)
// , AngleStart, AngleExtent, AngleStep == "auto" ? AngleStep : Convert.ToDouble(AngleStep)
// , ScaleRMin, ScaleRMax, ScaleRStep == "auto" ? ScaleRStep : Convert.ToDouble(ScaleRStep)
// , ScaleCMin, ScaleCMax, ScaleCStep == "auto" ? ScaleCStep : Convert.ToDouble(ScaleCStep)
// , Optimization, Metric
// , Contrast, MinContrast
#region 模板参数
//NumLevels == "auto" ? NumLevels : Convert.ToInt16(NumLevels)
this.lblModelParam1.Text = "金字塔的层级";
this.dtxtModelParam1.Text = "auto";
this.lblModelParam1.Visible = true;
this.dtxtModelParam1.Visible = true;
this.dtxtModelParam1.Enabled = false;
lblModelParam1.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时金字塔的层级NumLevels,'0'表示不使用金字塔");
// , AngleStart, AngleExtent, AngleStep == "auto" ? AngleStep : Convert.ToDouble(AngleStep)
this.lblModelParam2.Text = "角度步长";
this.dtxtModelParam2.Text = "auto";
this.lblModelParam2.Visible = true;
this.dtxtModelParam2.Visible = true;
this.dtxtModelParam2.Enabled = false;
lblModelParam2.MouseHover += (s, e) => ShowToolTip((Control)s, "角度范围内进行旋转的步长AngleStep,'auto'表示由系统自动选择合适的步长");
this.lblModelParam3.Text = "起始角度";
this.dtxtModelParam3.Text = "-5";
this.lblModelParam3.Visible = true;
this.dtxtModelParam3.Visible = true;
this.dtxtModelParam3.Enabled = true;
lblModelParam3.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的起始角度AngleStart");
this.lblModelParam4.Text = "角度范围";
this.dtxtModelParam4.Text = "10";
this.lblModelParam4.Visible = true;
this.dtxtModelParam4.Visible = true;
this.dtxtModelParam4.Enabled = true;
lblModelParam4.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的角度范围AngleExtent,'0'表示无角度搜索");
//, double ScaleRMin = 0.9, double ScaleRMax = 1.1, string ScaleRStep = "auto"
this.lblModelParam5.Text = "纵向缩放最小值";
this.dtxtModelParam5.Text = "0.9";
this.lblModelParam5.Visible = true;
this.dtxtModelParam5.Visible = true;
this.dtxtModelParam5.Enabled = true;
lblModelParam5.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最小值ScaleRMin");
this.lblModelParam6.Text = "纵向缩放最大值";
this.dtxtModelParam6.Text = "1.1";
this.lblModelParam6.Visible = true;
this.dtxtModelParam6.Visible = true;
this.dtxtModelParam6.Enabled = true;
lblModelParam6.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最大值ScaleRMax");
//, double ScaleCMin = 1.1, double ScaleCMax = 0.9, string ScaleCStep = "auto"
this.lblModelParam7.Text = "横向缩放最小值";
this.dtxtModelParam7.Text = "0.9";
this.lblModelParam7.Visible = true;
this.dtxtModelParam7.Visible = true;
this.dtxtModelParam7.Enabled = true;
lblModelParam7.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最小值ScaleCMin");
this.lblModelParam8.Text = "横向缩放最大值";
this.dtxtModelParam8.Text = "1.1";
this.lblModelParam8.Visible = true;
this.dtxtModelParam8.Visible = true;
this.dtxtModelParam8.Enabled = true;
lblModelParam8.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最大值ScaleCMax");
//, string Optimization = "auto", string Metric = "ignore_local_polarity"
this.lblModelParam9.Text = "优化";
this.dtxtModelParam9.Text = "none";
this.lblModelParam9.Visible = true;
this.dtxtModelParam9.Visible = true;
this.dtxtModelParam9.Enabled = false;
lblModelParam9.MouseHover += (s, e) => ShowToolTip((Control)s, "影响形状模型创建时的速度和精度的优化选项Optimization");
this.lblModelParam10.Text = "极性";
this.dtxtModelParam10.Text = "ignore_local_polarity";
this.lblModelParam10.Visible = true;
this.dtxtModelParam10.Visible = true;
this.dtxtModelParam10.Enabled = false;
lblModelParam10.MouseHover += (s, e) => ShowToolTip((Control)s, "极性信息的度量方法Metric");
//, string Contrast = "auto", int MinContrast = 10
this.lblModelParam11.Text = "对比度参数";
this.dtxtModelParam11.Text = "auto";
this.lblModelParam11.Visible = true;
this.dtxtModelParam11.Visible = true;
this.dtxtModelParam11.Enabled = false;
lblModelParam11.MouseHover += (s, e) => ShowToolTip((Control)s, "创建模板时的对比度Contrast");
this.lblModelParam12.Text = "最小对比度参数";
this.dtxtModelParam12.Text = "10";
this.lblModelParam12.Visible = true;
this.dtxtModelParam12.Visible = true;
this.dtxtModelParam12.Enabled = true;
lblModelParam8.MouseHover += (s, e) => ShowToolTip((Control)s, "模型匹配过程中考虑的最小对比度MinContrast");
#endregion
break;
case ModelType.各向异形模板:
default:
//, AngleStart / 180.0 * Math.PI, AngleExtent / 180.0 * Math.PI
//, ScaleRMin, ScaleRMax
//, ScaleCMin, ScaleCMax
//, MinScore, NumMatches, MaxOverlap, SubPixel
//, NumLevels == "auto" ? NumLevels : Convert.ToInt32(NumLevels)
//, Greediness
#region 输入参数
//, AngleStart / 180.0 * Math.PI, AngleExtent / 180.0 * Math.PI
this.lblInputParam1.Text = "起始角度";
this.dtxtInputParam1.Text = Subject.Params.Inputs["AngleStart"]?.ToString();
this.lblInputParam1.Visible = true;
this.dtxtInputParam1.Visible = true;
this.dtxtInputParam1.Enabled = true;
lblInputParam1.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的起始角度AngleStart");
this.lblInputParam2.Text = "角度范围";
this.dtxtInputParam2.Text = Subject.Params.Inputs["AngleExtent"]?.ToString();
this.lblInputParam2.Visible = true;
this.dtxtInputParam2.Visible = true;
this.dtxtInputParam2.Enabled = true;
lblInputParam2.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的角度范围AngleExtent,'0'表示无角度搜索");
//, ScaleRMin, ScaleRMax
this.lblInputParam3.Text = "纵向缩放最小值";
this.dtxtInputParam3.Text = Subject.Params.Inputs["ScaleRMin"]?.ToString();
this.lblInputParam3.Visible = true;
this.dtxtInputParam3.Visible = true;
this.dtxtInputParam3.Enabled = true;
lblInputParam3.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最小值ScaleRMin");
this.lblInputParam4.Text = "纵向缩放最大值";
this.dtxtInputParam4.Text = Subject.Params.Inputs["ScaleRMax"]?.ToString();
this.lblInputParam4.Visible = true;
this.dtxtInputParam4.Visible = true;
this.dtxtInputParam4.Enabled = true;
lblInputParam4.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最大值ScaleRMax");
//, ScaleCMin, ScaleCMax
this.lblInputParam5.Text = "横向缩放最小值";
this.dtxtInputParam5.Text = Subject.Params.Inputs["ScaleCMin"]?.ToString();
this.lblInputParam5.Visible = true;
this.dtxtInputParam5.Visible = true;
this.dtxtInputParam5.Enabled = true;
lblInputParam5.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最小值ScaleCMin");
this.lblInputParam6.Text = "横向缩放最大值";
this.dtxtInputParam6.Text = Subject.Params.Inputs["ScaleCMax"]?.ToString();
this.lblInputParam6.Visible = true;
this.dtxtInputParam6.Visible = true;
this.dtxtInputParam6.Enabled = true;
lblInputParam6.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最大值ScaleCMax");
//, MinScore, NumMatches, MaxOverlap, ResultType
this.lblInputParam7.Text = "最小分数";
this.dtxtInputParam7.Text = Subject.Params.Inputs["MinScore"]?.ToString();
this.lblInputParam7.Visible = true;
this.dtxtInputParam7.Visible = true;
this.dtxtInputParam7.Enabled = true;
lblInputParam7.MouseHover += (s, e) => ShowToolTip((Control)s, "被找到的模板最小分数MinScore");
this.lblInputParam8.Text = "期望个数";
this.dtxtInputParam8.Text = Subject.Params.Inputs["NumMatches"]?.ToString();
this.lblInputParam8.Visible = true;
this.dtxtInputParam8.Visible = true;
this.dtxtInputParam8.Enabled = true;
lblInputParam8.MouseHover += (s, e) => ShowToolTip((Control)s, "要找到的模板最多的实例数NumMatches,'0'则找到所有可能的匹配");
this.lblInputParam9.Text = "最大重叠比例";
this.dtxtInputParam9.Text = Subject.Params.Inputs["MaxOverlap"]?.ToString();
this.lblInputParam9.Visible = true;
this.dtxtInputParam9.Visible = true;
this.dtxtInputParam9.Enabled = true;
lblInputParam9.MouseHover += (s, e) => ShowToolTip((Control)s, "允许找到的模型实例的最大重叠比例MaxOverlap[较小的值会避免找到多个相似的匹配]");
this.lblInputParam10.Text = "计算精度";
this.dtxtInputParam10.Text = Subject.Params.Inputs["SubPixel"]?.ToString();
this.lblInputParam10.Visible = true;
this.dtxtInputParam10.Visible = true;
this.dtxtInputParam10.Enabled = false;
lblInputParam10.MouseHover += (s, e) => ShowToolTip((Control)s, "计算精度的设置SubPixel['none'最大误差为半个像素]");
//, NumLevels == "auto" ? NumLevels : Convert.ToInt32(NumLevels)
//, Greediness, , new HTuple(), new HTuple()
this.lblInputParam11.Text = "搜索时金字塔的层级";
this.dtxtInputParam11.Text = "0";
this.lblInputParam11.Visible = true;
this.dtxtInputParam11.Visible = true;
this.dtxtInputParam11.Enabled = false;
lblInputParam11.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时金字塔的层级");
this.lblInputParam12.Text = "贪婪度";
this.dtxtInputParam12.Text = Subject.Params.Inputs["Greediness"]?.ToString();
this.lblInputParam12.Visible = true;
this.dtxtInputParam12.Visible = true;
this.dtxtInputParam12.Enabled = true;
lblInputParam12.MouseHover += (s, e) => ShowToolTip((Control)s, "贪婪度,越高速度越快[一般都设为0.8,太大容易出现找不到的情况]");
this.lblInputParam13.Text = "最小数量";
this.dtxtInputParam13.Text = Subject.Params.Inputs["MinCount"]?.ToString();
this.lblInputParam13.Visible = true;
this.dtxtInputParam13.Visible = true;
this.dtxtInputParam13.Enabled = true;
lblInputParam13.MouseHover += (s, e) => ShowToolTip((Control)s, "匹配结果要求的最小数量");
this.lblInputParam14.Text = "最大数量";
this.dtxtInputParam14.Text = Subject.Params.Inputs["MaxCount"]?.ToString();
this.lblInputParam14.Visible = true;
this.dtxtInputParam14.Visible = true;
this.dtxtInputParam14.Enabled = true;
lblInputParam14.MouseHover += (s, e) => ShowToolTip((Control)s, "匹配结果要求的最大数量");
#endregion
//UpdataInputs();
//string NumLevels = "auto"
//, double AngleStart = -5, double AngleExtent = 10, string AngleStep = "auto"
//, double ScaleRMin = 0.9, double ScaleRMax = 1.1, string ScaleRStep = "auto"
//, double ScaleCMin = 1.1, double ScaleCMax = 0.9, string ScaleCStep = "auto"
//, string Optimization = "auto", string Metric = "ignore_local_polarity"
//, string Contrast = "auto", int MinContrast = 10
#region 模板参数
//NumLevels == "auto" ? NumLevels : Convert.ToInt16(NumLevels)
this.lblModelParam1.Text = "金字塔的层级";
this.dtxtModelParam1.Text = "auto";
this.lblModelParam1.Visible = true;
this.dtxtModelParam1.Visible = true;
this.dtxtModelParam1.Enabled = false;
lblModelParam1.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时金字塔的层级NumLevels,'0'表示不使用金字塔");
// , AngleStart, AngleExtent, AngleStep == "auto" ? AngleStep : Convert.ToDouble(AngleStep)
this.lblModelParam2.Text = "角度步长";
this.dtxtModelParam2.Text = "auto";
this.lblModelParam2.Visible = true;
this.dtxtModelParam2.Visible = true;
this.dtxtModelParam2.Enabled = false;
lblModelParam2.MouseHover += (s, e) => ShowToolTip((Control)s, "角度范围内进行旋转的步长AngleStep,'auto'表示由系统自动选择合适的步长");
this.lblModelParam3.Text = "起始角度";
this.dtxtModelParam3.Text = "-5";
this.lblModelParam3.Visible = true;
this.dtxtModelParam3.Visible = true;
this.dtxtModelParam3.Enabled = true;
lblModelParam3.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的起始角度AngleStart");
this.lblModelParam4.Text = "角度范围";
this.dtxtModelParam4.Text = "10";
this.lblModelParam4.Visible = true;
this.dtxtModelParam4.Visible = true;
this.dtxtModelParam4.Enabled = true;
lblModelParam4.MouseHover += (s, e) => ShowToolTip((Control)s, "搜索时的角度范围AngleExtent,'0'表示无角度搜索");
//, double ScaleRMin = 0.9, double ScaleRMax = 1.1, string ScaleRStep = "auto"
this.lblModelParam5.Text = "纵向缩放最小值";
this.dtxtModelParam5.Text = "0.9";
this.lblModelParam5.Visible = true;
this.dtxtModelParam5.Visible = true;
this.dtxtModelParam5.Enabled = true;
lblModelParam5.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最小值ScaleRMin");
this.lblModelParam6.Text = "纵向缩放最大值";
this.dtxtModelParam6.Text = "1.1";
this.lblModelParam6.Visible = true;
this.dtxtModelParam6.Visible = true;
this.dtxtModelParam6.Enabled = true;
lblModelParam6.MouseHover += (s, e) => ShowToolTip((Control)s, "纵向缩放最大值ScaleRMax");
//, double ScaleCMin = 1.1, double ScaleCMax = 0.9, string ScaleCStep = "auto"
this.lblModelParam7.Text = "横向缩放最小值";
this.dtxtModelParam7.Text = "0.9";
this.lblModelParam7.Visible = true;
this.dtxtModelParam7.Visible = true;
this.dtxtModelParam7.Enabled = true;
lblModelParam7.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最小值ScaleCMin");
this.lblModelParam8.Text = "横向缩放最大值";
this.dtxtModelParam8.Text = "1.1";
this.lblModelParam8.Visible = true;
this.dtxtModelParam8.Visible = true;
this.dtxtModelParam8.Enabled = true;
lblModelParam8.MouseHover += (s, e) => ShowToolTip((Control)s, "横向缩放最大值ScaleCMax");
//, string Optimization = "auto", string Metric = "ignore_local_polarity"
this.lblModelParam9.Text = "优化";
this.dtxtModelParam9.Text = "auto";
this.lblModelParam9.Visible = true;
this.dtxtModelParam9.Visible = true;
this.dtxtModelParam9.Enabled = false;
lblModelParam9.MouseHover += (s, e) => ShowToolTip((Control)s, "影响形状模型创建时的速度和精度的优化选项Optimization");
this.lblModelParam10.Text = "极性";
this.dtxtModelParam10.Text = "ignore_local_polarity";
this.lblModelParam10.Visible = true;
this.dtxtModelParam10.Visible = true;
this.dtxtModelParam10.Enabled = false;
lblModelParam10.MouseHover += (s, e) => ShowToolTip((Control)s, "极性信息的度量方法Metric");
//, string Contrast = "auto", int MinContrast = 10
this.lblModelParam11.Text = "对比度参数";
this.dtxtModelParam11.Text = "auto";
this.lblModelParam11.Visible = true;
this.dtxtModelParam11.Visible = true;
this.dtxtModelParam11.Enabled = false;
lblModelParam11.MouseHover += (s, e) => ShowToolTip((Control)s, "创建模板时的对比度Contrast");
this.lblModelParam12.Text = "最小对比度参数";
this.dtxtModelParam12.Text = "10";
this.lblModelParam12.Visible = true;
this.dtxtModelParam12.Visible = true;
this.dtxtModelParam12.Enabled = true;
lblModelParam8.MouseHover += (s, e) => ShowToolTip((Control)s, "模型匹配过程中考虑的最小对比度MinContrast");
#endregion
break;
}
}
});
}
private void btnCreateModel_Click(object sender, EventArgs e)
{
if (InputImage != null && InputImage is HImage)
{
imgTabControl.SelectedTab = tabPageModelImage;
using (HImage hImage = (HImage)Subject.InputImage)
{
hImage.GetImageSize(out HTuple hv_imageWidth, out HTuple hv_imageHeight);
createModelImageHSmartWindowControl.ShowHoImage(hImage);
createModelImageHSmartWindowControl.bAollowDraw = true;
createModelImageHSmartWindowControl.oRoi = new HRectangle2(hv_imageWidth.TupleReal() / 2, hv_imageHeight.TupleReal() / 2
, 0, hv_imageWidth.TupleReal() / 4, hv_imageHeight.TupleReal() / 4);
}
}
}
private void btnSaveModel_Click(object sender, EventArgs e)
{
try
{
if (InputImage != null && InputImage is HObject)
{
double result = 0;
if (Enum.TryParse(cmbModelType.Text, out ModelType modelType))
{
string NumLevels = this.dtxtModelParam1.Text;
string AngleStep = this.dtxtModelParam2.Text;
double AngleStart = Convert.ToDouble(this.dtxtModelParam3.Text);
double AngleExtent = Convert.ToDouble(this.dtxtModelParam4.Text);
double ScaleRMin = Convert.ToDouble(this.dtxtModelParam5.Text);
double ScaleRMax = Convert.ToDouble(this.dtxtModelParam6.Text);
double ScaleCMin = Convert.ToDouble(this.dtxtModelParam7.Text);
double ScaleCMax = Convert.ToDouble(this.dtxtModelParam8.Text);
string Optimization = this.dtxtModelParam9.Text;
string Metric = this.dtxtModelParam10.Text;
string Contrast = this.dtxtModelParam11.Text;
int MinContrast = Convert.ToInt16(this.dtxtModelParam12.Text);
HRectangle2 ROI = (HRectangle2)createModelImageHSmartWindowControl.oRoi;
HOperatorSet.GenRectangle2(out HObject hRectangle, ROI.Row, ROI.Column, ROI.Phi, ROI.SemiLength1, ROI.SemiLength2);
HObject hoDomainImage = InputImage as HObject;
HTuple hv_Channels = new HTuple();
//判断是否为灰度图
using (HDevDisposeHelper dh = new HDevDisposeHelper())
{
try
{
HOperatorSet.CountChannels(hoDomainImage, out hv_Channels);
if (hv_Channels.TupleInt() != 1)
HOperatorSet.Rgb1ToGray(hoDomainImage, out hoDomainImage);
//转换后再次检查是否为灰度图
HOperatorSet.CountChannels(hoDomainImage, out hv_Channels);
if (hv_Channels.TupleInt() != 1)
HOperatorSet.Rgb1ToGray(hoDomainImage, out hoDomainImage);
}
catch { }
}
HOperatorSet.ReduceDomain(hoDomainImage, hRectangle, out HObject hoImageReduced);
HOperatorSet.CropDomain(hoImageReduced, out HObject hoModelImage);
bool bCreateModel = false;
switch (modelType)
{
case ModelType.局部变形模板:
bCreateModel = ((HFindModelTool)Subject).CreateModel
(hoModelImage, modelType, NumLevels
, AngleStart, AngleExtent, AngleStep
, ScaleRMin, ScaleRMax, "auto"
, ScaleCMin, ScaleCMax, "auto"
, Optimization, Metric, Contrast, MinContrast);
break;
case ModelType.各向异形模板:
default:
bCreateModel = ((HFindModelTool)Subject).CreateModel
(hoModelImage, modelType, NumLevels
, AngleStart, AngleExtent, AngleStep
, ScaleRMin, ScaleRMax, "auto"
, ScaleCMin, ScaleCMax, "auto"
, Optimization, Metric, Contrast, MinContrast);
break;
}
if (bCreateModel)
{
HObject ho_ModelContours = new HObject();
switch (((HFindModelTool)Subject).ModelID.Type)
{
case ModelType.局部变形模板:
HOperatorSet.GetDeformableModelContours(out ho_ModelContours, ((HFindModelTool)Subject).ModelID.hvModel, 1);
break;
case ModelType.各向异形模板:
default:
HOperatorSet.GetShapeModelContours(out ho_ModelContours, ((HFindModelTool)Subject).ModelID.hvModel, 1);
break;
}
HOperatorSet.GetImageSize(((HFindModelTool)Subject).ModelID.hoImage, out HTuple hv_Width, out HTuple hv_Height);
HOperatorSet.VectorAngleToRigid(-hv_Height / 2, -hv_Width / 2, 0, 0, 0, 0, out HTuple hv_HomMat2D);
HOperatorSet.AffineTransContourXld(ho_ModelContours, out ho_ModelContours, hv_HomMat2D);
//建模成功导航到子页
parasTabControl.SelectedTab = tabPageRunParas;
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispImage(((HFindModelTool)Subject).ModelID.hoImage, modelImageHWindowControl.HalconWindow);
TAlgorithm.SetColor(modelImageHWindowControl.HalconWindow, "red");
TAlgorithm.DispObj(ho_ModelContours, modelImageHWindowControl.HalconWindow);
TAlgorithm.DispMsg("创建模板成功", modelImageHWindowControl.HalconWindow, true);
FirstModelImage = ((HFindModelTool)Subject).ModelID.hoImage.CopyObj(1, -1);
}
else
{
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispMsg("创建模板失败", modelImageHWindowControl.HalconWindow, false);
}
}
}
}
catch { }
}
public void ShowModel(HModel ModelID)
{
try
{
if (ModelID != null && ModelID.hvModel != null && ModelID.hvModel.Length > 0)
{
HOperatorSet.GenEmptyObj(out HObject ho_ModelContours);
switch (ModelID.Type)
{
case ModelType.局部变形模板:
HOperatorSet.GetDeformableModelContours(out ho_ModelContours, ModelID.hvModel, 1);
break;
case ModelType.各向异形模板:
default:
HOperatorSet.GetShapeModelContours(out ho_ModelContours, ModelID.hvModel, 1);
break;
}
HOperatorSet.GetImageSize(ModelID.hoImage, out HTuple hv_Width, out HTuple hv_Height);
HOperatorSet.VectorAngleToRigid(-hv_Height / 2, -hv_Width / 2, 0, 0, 0, 0, out HTuple hv_HomMat2D);
HOperatorSet.AffineTransContourXld(ho_ModelContours, out ho_ModelContours, hv_HomMat2D);
HOperatorSet.ClearWindow(modelImageHWindowControl.HalconWindow);
TAlgorithm.DispImage(ModelID.hoImage, modelImageHWindowControl.HalconWindow);
TAlgorithm.SetColor(modelImageHWindowControl.HalconWindow, "red");
TAlgorithm.DispObj(ho_ModelContours, modelImageHWindowControl.HalconWindow);
TAlgorithm.DispMsg("创建模板成功", modelImageHWindowControl.HalconWindow, true);
}
}
catch { }
}
private void HFindModelToolEdit_SizeChanged(object sender, EventArgs e) => ShowModel(((HFindModelTool)Subject).ModelID);
private void parasTabControl_SelectedIndexChanged(object sender, EventArgs e)
{
TabControl tabControl = sender as TabControl;
if (tabControl != null)
{
if (tabControl.SelectedTab == tabPageRunParas)
ShowModel(((HFindModelTool)Subject).ModelID);
}
}
}
}