添加项目文件。

This commit is contained in:
17860779768
2023-02-23 14:52:43 +08:00
parent 1db01eda58
commit 157613603c
508 changed files with 94132 additions and 0 deletions

View File

@ -0,0 +1,637 @@
using Bro.Common.Helper;
using Bro.UI.Config.Helper;
using Bro.UI.Config.MenuForms;
using Bro.UI.Model.Winform;
using HalconDotNet;
using HDisplay;
using HDisplay.ViewROI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Bro.UI.Config
{
[MenuNode("EditModel", "模板编辑", 4, "View2", true)]
public partial class FrmEditModel : MenuFrmBase
{
CanvasImage canvas = new CanvasImage();
HTuple modelId = null;
HalconDisplay hDisplay = new HalconDisplay();
CreateShapeModelConfig modelConfig = new CreateShapeModelConfig();
FindShapeModelConfig findConfig = new FindShapeModelConfig();
public FrmEditModel()
{
InitializeComponent();
//canvas.Dock = DockStyle.Fill;
//plImage.Controls.Clear();
//plImage.Controls.Add(canvas);
hDisplay.Dock = DockStyle.Fill;
plImage.Controls.Clear();
plImage.Controls.Add(hDisplay);
pgCreateModel.SelectedObject = modelConfig;
pgFindConfig.SelectedObject = findConfig;
dgvImages.AutoGenerateColumns = false;
}
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedIndex == 1)
{
canvas.Elements.Clear();
}
}
private void btnLoadImage_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = false;
ofd.Filter = "图片文件|*.bmp;*.png;*.jpg;*.jpeg;*.tif|所有文件|*.*";
if (ofd.ShowDialog() == DialogResult.OK)
{
//Bitmap map = (Bitmap)Bitmap.FromFile(ofd.FileName);
//canvas.LoadImage(map);
LoadImage(ofd.FileName);
}
}
private void LoadImage(string imgFileName)
{
hDisplay.ClearDisplay();
hDisplay.Image?.Dispose();
HImage hImage = new HImage();
hImage.ReadImage(imgFileName);
hDisplay.Image = hImage;
hDisplay.Refresh();
}
private void btnCreateModel_Click(object sender, EventArgs e)
{
if (hDisplay.Image == null)
{
MessageBox.Show("请先载入产品图片");
return;
}
if (hDisplay.ROIController.ROIList.Count != 1)
{
MessageBox.Show("请仅设置一个矩阵ROI");
return;
}
HOperatorSet.ClearAllShapeModels();
modelId = null;
HObject rectObj = null;
HOperatorSet.HomMat2dIdentity(out HTuple identityMatrix);
HTuple transformMatrix = null;
if (hDisplay.ROIController.ROIList[0] is ROIRectangle1 rect1)
{
HOperatorSet.GenRectangle1(out rectObj, rect1.Row1, rect1.Col1, rect1.Row2, rect1.Col2);
HOperatorSet.HomMat2dTranslate(identityMatrix, (rect1.Row1 + rect1.Row2) / 2.0, (rect1.Col1 + rect1.Col2) / 2.0, out transformMatrix);
}
else if (hDisplay.ROIController.ROIList[0] is ROIRectangle2 rect2)
{
HOperatorSet.GenRectangle2(out rectObj, rect2.MidR, rect2.MidC, rect2.Phi, rect2.Length1, rect2.Length2);
HOperatorSet.HomMat2dTranslate(identityMatrix, rect2.MidR, rect2.MidC, out transformMatrix);
}
else
{
MessageBox.Show("请仅设置一个矩阵ROI");
return;
}
HOperatorSet.ReduceDomain(hDisplay.Image, rectObj, out HObject imageReduced);
HTuple config = modelConfig.GetHTuple();
HOperatorSet.CreateShapeModel(imageReduced, config[0], config[1], config[2], config[3], config[4], config[5], config[6], config[7], out modelId);
HOperatorSet.GetShapeModelContours(out HObject modelContours, modelId, 1);
HOperatorSet.AffineTransContourXld(modelContours, out HObject countoursAffinTrans, transformMatrix);
hDisplay.ClearGraphicStack();
hDisplay.AddObjectToGraphicStack(hDisplay.Image);
hDisplay.AddObjectToGraphicStack(countoursAffinTrans);
hDisplay.Refresh();
MessageBox.Show("模板创建成功");
}
private void btnSaveModel_Click(object sender, EventArgs e)
{
if (modelId == null)
{
MessageBox.Show("模板句柄为空,无法保存");
return;
}
SaveFileDialog sfd = new SaveFileDialog();
sfd.SupportMultiDottedExtensions = false;
sfd.Filter = "模板文件|*.shm";
sfd.DefaultExt = "shm";
if (sfd.ShowDialog() == DialogResult.OK)
{
HOperatorSet.WriteShapeModel(modelId, sfd.FileName);
MessageBox.Show("模板保存完成");
}
}
private void btnLoadModel_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "模板文件|*.shm";
ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK)
{
lblModel.Text = "";
HOperatorSet.ReadShapeModel(ofd.FileName, out modelId);
lblModel.Text = ofd.FileName;
}
}
private void btnLoadImageFolder_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.ShowNewFolderButton = false;
if (fbd.ShowDialog() == DialogResult.OK)
{
lblImageFolder.Text = fbd.SelectedPath;
DirectoryInfo dir = new DirectoryInfo(fbd.SelectedPath);
List<string> suffixList = new List<string>() { "bmp", "png", "jpg", "jpeg", "tif" };
var imgFileNames = dir.GetFiles().ToList().Where(u => suffixList.Any(s => u.Name.ToLower().EndsWith(s)))
.Select(u =>
{
TestCase tc = new TestCase();
tc.Name = u.Name;
tc.FullName = u.FullName;
tc.ModelMatchNum = 0;
return tc;
}).ToList();
dgvImages.DataSource = imgFileNames;
}
}
private void dgvImages_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (dgvImages.Rows[e.RowIndex].DataBoundItem is TestCase tc)
{
LoadImage(tc.FullName);
}
}
private void btnTestCurrent_Click(object sender, EventArgs e)
{
if (!CheckBeforeTest())
{
return;
}
RunSelected();
}
private bool RunSelected(int step = 0)
{
int selectedIndex = dgvImages.SelectedRows[0].Index;
if (step != 0)
{
int afterIndex = selectedIndex + step;
if (afterIndex < 0)
{
//MessageBox.Show("当前已经是第一项");
return false;
}
if (afterIndex >= dgvImages.Rows.Count)
{
//MessageBox.Show("当前已经是最后一项");
return false;
}
dgvImages.Rows[selectedIndex].Selected = false;
dgvImages.Rows[afterIndex].Selected = true;
dgvImages.FirstDisplayedScrollingRowIndex = afterIndex;
}
TestCase tc = dgvImages.SelectedRows[0].DataBoundItem as TestCase;
LoadImage(tc.FullName);
HTuple findConfigTuple = findConfig.GetHTuple();
HOperatorSet.FindShapeModel(hDisplay.Image, modelId, findConfigTuple[0], findConfigTuple[1], findConfigTuple[2], findConfigTuple[3], findConfigTuple[4], findConfigTuple[5], findConfigTuple[6], findConfigTuple[7], out HTuple rows, out HTuple cols, out HTuple angles, out HTuple scores);
tc.ModelMatchNum = scores.Length;
HOperatorSet.GetShapeModelContours(out HObject modelContours, modelId, 1);
HOperatorSet.CountObj(modelContours, out HTuple objCount);
HOperatorSet.HomMat2dIdentity(out HTuple identityMatrix);
for (int i = 0; i < tc.ModelMatchNum; i++)
{
HOperatorSet.CopyObj(modelContours, out HObject model, 1, objCount);
HOperatorSet.HomMat2dRotate(identityMatrix, angles[i], 0, 0, out HTuple transformMatrix);
HOperatorSet.HomMat2dTranslate(transformMatrix, rows[i], cols[i], out transformMatrix);
HOperatorSet.AffineTransContourXld(model, out HObject affinedContour, transformMatrix);
hDisplay.AddObjectToGraphicStack(affinedContour);
}
hDisplay.Refresh();
dgvImages.Invalidate();
return true;
}
private bool CheckBeforeTest()
{
if (modelId == null)
{
MessageBox.Show("当前未编辑或者载入模板,请创建模板或者选择模板文件载入");
return false;
}
if (dgvImages.SelectedRows.Count == 0)
{
MessageBox.Show("当前图片列表未选择测试项,请选择需要测试的图片");
return false;
}
return true;
}
private void btnTestNext_Click(object sender, EventArgs e)
{
if (!CheckBeforeTest())
{
return;
}
if (!RunSelected(1))
{
MessageBox.Show("当前已经是最后一项");
}
}
private void btnTestAll_Click(object sender, EventArgs e)
{
if (dgvImages.Rows.Count <= 0)
{
MessageBox.Show("当前无待检测图片");
return;
}
dgvImages.FirstDisplayedScrollingRowIndex = 0;
dgvImages.Rows[0].Selected = true;
bool flag = RunSelected(0);
while (flag)
{
flag = RunSelected(1);
}
MessageBox.Show("检测完成");
}
}
public class TestCase
{
public string Name { get; set; }
public string FullName { get; set; }
public int ModelMatchNum { get; set; } = 0;
}
#region Halcon Model
public abstract class StrictedListConvert : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
List<string> portNames = GetSupportedValueList();
return new StandardValuesCollection(portNames);
}
protected abstract List<string> GetSupportedValueList();
}
public abstract class ModelConfig
{
public abstract HTuple GetHTuple();
protected void IntCheck(ref ArrayList list, string desc)
{
if (int.TryParse(desc, out int convertValue))
{
list.Add(convertValue);
}
else
{
list.Add(desc);
}
}
protected void DoubleCheck(ref ArrayList list, string desc)
{
if (double.TryParse(desc, out double convertValue))
{
list.Add(convertValue);
}
else
{
list.Add(desc);
}
}
}
#region Create Model
public class NumLevelsConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "auto", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
}
}
public class AngleStartConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "-3.14", "-1.57", "-0.79", "-0.39", "-0.20", "0.0" };
}
}
public class AngleExtentConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "6.29", "3.14", "1.57", "0.79", "0.39" };
}
}
public class AngleStepConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "auto", "0.0175", "0.0349", "0.0524", "0.0698", "0.0873" };
}
}
public enum Optimization
{
auto,
no_pregeneration,
none,
point_reduction_high,
point_reduction_low,
point_reduction_medium,
pregeneration,
}
public enum Metric
{
use_polarity,
ignore_color_polarity,
ignore_global_polarity,
ignore_local_polarity,
}
public class ContrastConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "auto", "auto_contrast", "auto_contrast_hyst", "auto_min_size", "10", "20", "30", "40", "60", "80", "100", "120", "140", "160" };
}
}
public class MinContrastConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "auto", "1", "2", "3", "5", "7", "10", "20", "30", "40" };
}
}
public class CreateShapeModelConfig : ModelConfig
{
[Category("建立模板配置")]
[DisplayName("层次数量")]
[TypeConverter(typeof(NumLevelsConvert))]
public string NumLevles { get; set; } = "auto";
[Category("建立模板配置")]
[DisplayName("起始角度")]
[TypeConverter(typeof(AngleStartConvert))]
public string AngleStart { get; set; } = "-0.39";
[Category("建立模板配置")]
[DisplayName("角度范围")]
[TypeConverter(typeof(AngleExtentConvert))]
public string AngleExtent { get; set; } = "0.79";
[Category("建立模板配置")]
[DisplayName("角度步长")]
[TypeConverter(typeof(AngleStepConvert))]
public string AngleStep { get; set; } = "auto";
[Category("建立模板配置")]
[DisplayName("最优化选择")]
public Optimization Optimization { get; set; } = Optimization.auto;
[Category("建立模板配置")]
[DisplayName("极性")]
public Metric Metric { get; set; } = Metric.use_polarity;
[Category("建立模板配置")]
[DisplayName("对比度")]
[TypeConverter(typeof(ContrastConvert))]
public string Contrast { get; set; } = "auto";
[Category("建立模板配置")]
[DisplayName("最小对比度")]
[TypeConverter(typeof(MinContrastConvert))]
public string MinContrast { get; set; } = "auto";
public override HTuple GetHTuple()
{
ArrayList list = new ArrayList();
IntCheck(ref list, NumLevles);
DoubleCheck(ref list, AngleStart);
DoubleCheck(ref list, AngleExtent);
DoubleCheck(ref list, AngleStep);
list.Add(Optimization.ToString());
list.Add(Metric.ToString());
IntCheck(ref list, Contrast);
IntCheck(ref list, MinContrast);
HTuple hTuple = new HTuple(list.ToArray());
return hTuple;
}
}
#endregion
#region Find Model
public class AngleStartConvert_Find : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "-3.14", "-1.57", "-0.78", "-0.39", "-0.20", "0.0" };
}
}
public class AngleExtentConvert_Find : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "6.29", "3.14", "1.57", "0.78", "0.39", "0.0" };
}
}
public class MinScoreConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1.0" };
}
}
public class NumMatchesConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "0", "1", "2", "3", "4", "5", "10", "20" };
}
}
public class MaxOverlapConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "0.0", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1.0" };
}
}
public enum SubPixel
{
interpolation,
least_squares,
least_squares_high,
least_squares_very_high,
[Description("max_deformation 1")]
max_deformation_1,
[Description("max_deformation 2")]
max_deformation_2,
[Description("max_deformation 3")]
max_deformation_3,
[Description("max_deformation 4")]
max_deformation_4,
[Description("max_deformation 5")]
max_deformation_5,
[Description("max_deformation 6")]
max_deformation_6,
none,
}
public class NumLevelsConvert_Find : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" };
}
}
public class GreedinessConvert : StrictedListConvert
{
protected override List<string> GetSupportedValueList()
{
return new List<string>() { "0.0", "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1.0" };
}
}
public class FindShapeModelConfig : ModelConfig
{
[Category("定位模板配置")]
[DisplayName("起始角度")]
[TypeConverter(typeof(AngleStartConvert_Find))]
public string AngleStart { get; set; } = "-0.39";
[Category("定位模板配置")]
[DisplayName("角度范围")]
[TypeConverter(typeof(AngleExtentConvert_Find))]
public string AngleExtent { get; set; } = "0.78";
[Category("定位模板配置")]
[DisplayName("最小得分")]
[TypeConverter(typeof(MinScoreConvert))]
public string MinScore { get; set; } = "0.7";
[Category("定位模板配置")]
[DisplayName("匹配数量")]
[TypeConverter(typeof(NumMatchesConvert))]
public string NumMatches { get; set; } = "0";
[Category("定位模板配置")]
[DisplayName("最大重叠设置")]
[TypeConverter(typeof(MaxOverlapConvert))]
public string MaxOverlap { get; set; } = "0.5";
[Category("定位模板配置")]
[DisplayName("亚像素设置")]
public SubPixel SubPixel { get; set; } = SubPixel.least_squares;
[Category("定位模板配置")]
[DisplayName("层次数量")]
[TypeConverter(typeof(NumLevelsConvert_Find))]
public string NumLevles { get; set; } = "0";
[Category("定位模板配置")]
[DisplayName("Greediness")]
[TypeConverter(typeof(GreedinessConvert))]
public string Greediness { get; set; } = "0.9";
public override HTuple GetHTuple()
{
ArrayList list = new ArrayList();
DoubleCheck(ref list, AngleStart);
DoubleCheck(ref list, AngleExtent);
DoubleCheck(ref list, MinScore);
IntCheck(ref list, NumMatches);
DoubleCheck(ref list, MaxOverlap);
list.Add(SubPixel.GetEnumDescription());
IntCheck(ref list, NumLevles);
DoubleCheck(ref list, Greediness);
HTuple hTuple = new HTuple(list.ToArray());
return hTuple;
}
}
#endregion
#endregion
}