diff --git a/CanFly/UI/GuidePanel/GuideHeightCtrl.resx b/CanFly/UI/GuidePanel/GuideHeightCtrl.resx
index ad76d1e..71e5e93 100644
--- a/CanFly/UI/GuidePanel/GuideHeightCtrl.resx
+++ b/CanFly/UI/GuidePanel/GuideHeightCtrl.resx
@@ -142,4 +142,7 @@
17, 17
+
+ 25
+
\ No newline at end of file
diff --git a/CanFly/UI/SizePanel/SizeBaseGuideControl.cs b/CanFly/UI/SizePanel/SizeBaseGuideControl.cs
new file mode 100644
index 0000000..3a0fefa
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeBaseGuideControl.cs
@@ -0,0 +1,160 @@
+using CanFly.Canvas.Shape;
+using CanFly.Canvas.UI;
+using CanFly.Helper;
+using DH.Commons.Base;
+using HalconDotNet;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+
+
+namespace CanFly.UI.SizePanel
+{
+
+ public class SizeBaseGuideControl : UserControl
+ {
+ public Action? OnControlCloseEvent;
+
+ public event Action OnDataPassed;
+
+
+ private string _currentImageFile;
+
+ public string CurrentImageFile;
+
+ public CameraBase cameraBase;
+
+ protected string _hScriptsDir = Path.Combine(Environment.CurrentDirectory, "hscripts");
+
+ protected HObject? hImage = null;
+
+ protected FlyCanvas _canvas;
+
+ private HDevEngineTool? tool = null;
+
+
+
+ public void DataToTriggerEvent(string input,string output)
+ {
+
+ OnDataPassed?.Invoke(input, output);
+ }
+
+ protected virtual void UpdateShape(FlyShape shape)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected virtual string GetScriptFileName()
+ {
+ throw new NotImplementedException();
+ }
+
+
+
+ ///
+ /// 执行Halcon脚本
+ ///
+ /// 输入图像
+ /// 输入参数
+ /// 输出参数
+ protected void ExecuteHScript(
+ Dictionary inputImg,
+ Dictionary inputDic,
+ List outputParamKeys,
+ Action? exceptionHandler = null)
+ {
+
+ string filePath = Path.Combine(_hScriptsDir, GetScriptFileName());
+ if (!File.Exists(filePath))
+ {
+ MessageBox.Show($"文件 {filePath} 不存在");
+ return;
+ }
+
+ try
+ {
+ if (tool == null)
+ {
+ tool = new HDevEngineTool(_hScriptsDir);
+ tool.LoadProcedure(Path.GetFileNameWithoutExtension(GetScriptFileName()));
+ }
+
+
+
+ //tool.InputImageDic["INPUT_Image"] = hImage;
+ //tool.InputTupleDic["XCenter"] = _x;
+ //tool.InputTupleDic["YCenter"] = _y;
+ //tool.InputTupleDic["Radius"] = _r;
+
+ tool.InputImageDic = inputImg;
+ tool.InputTupleDic = inputDic;
+
+
+ Dictionary outputParams = new Dictionary();
+
+
+ if (!tool.RunProcedure(out string error, out int timeElasped))
+ {
+ OnExecuteHScriptResult(false, outputParams, timeElasped);
+ return;
+ }
+
+ for (int i = 0; i < outputParamKeys.Count; i++)
+ {
+ string k = outputParamKeys[i];
+ outputParams[k] = tool.GetResultTuple(k);
+ }
+
+ OnExecuteHScriptResult(true, outputParams, timeElasped);
+ }
+ catch (Exception ex)
+ {
+ exceptionHandler?.Invoke(ex);
+ }
+ finally
+ {
+ hImage?.Dispose();
+ hImage = null;
+ }
+
+ }
+
+
+
+ ///
+ /// Halcon脚本执行结果回调函数,重写该方法以自行处理算法执行结果
+ ///
+ /// 算法执行是否成功
+ /// 算法输出结果
+ /// 算法耗时,单位:ms
+ protected virtual void OnExecuteHScriptResult(bool success, Dictionary resultDic, int timeElasped)
+ {
+ throw new NotImplementedException();
+ }
+
+
+ protected void OpenImageFile(Action callback)
+ {
+ OpenFileDialog ofd = new OpenFileDialog();
+ ofd.Filter = "图像文件|*.jpg;*.jpeg;*.png";
+ ofd.Multiselect = false;
+ if (ofd.ShowDialog() == DialogResult.OK)
+ {
+ CurrentImageFile = ofd.FileName;
+ Bitmap bitmap = (Bitmap)Image.FromFile(CurrentImageFile);
+ callback?.Invoke(bitmap);
+ }
+ }
+
+
+ protected void OnControlClose()
+ {
+ OnControlCloseEvent?.Invoke();
+ }
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeBaseGuideControl.resx b/CanFly/UI/SizePanel/SizeBaseGuideControl.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeBaseGuideControl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/CanFly/UI/SizePanel/SizeCtrlTitleBar.Designer.cs b/CanFly/UI/SizePanel/SizeCtrlTitleBar.Designer.cs
new file mode 100644
index 0000000..ae8db9b
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeCtrlTitleBar.Designer.cs
@@ -0,0 +1,77 @@
+namespace CanFly.UI.SizePanel
+{
+ partial class SizeCtrlTitleBar
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ btnClose = new PictureBox();
+ j = new Label();
+ ((System.ComponentModel.ISupportInitialize)btnClose).BeginInit();
+ SuspendLayout();
+ //
+ // btnClose
+ //
+ btnClose.Dock = DockStyle.Right;
+ btnClose.Image = XKRS.CanFly.Properties.Resources.Close;
+ btnClose.Location = new Point(516, 3);
+ btnClose.Name = "btnClose";
+ btnClose.Size = new Size(30, 30);
+ btnClose.SizeMode = PictureBoxSizeMode.StretchImage;
+ btnClose.TabIndex = 1;
+ btnClose.TabStop = false;
+ btnClose.Click += btnClose_Click;
+ //
+ // j
+ //
+ j.Dock = DockStyle.Fill;
+ j.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Bold);
+ j.Location = new Point(3, 3);
+ j.Name = "j";
+ j.Size = new Size(513, 30);
+ j.TabIndex = 2;
+ j.Text = "标题";
+ j.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // SizeCtrlTitleBar
+ //
+ AutoScaleDimensions = new SizeF(7F, 17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ Controls.Add(j);
+ Controls.Add(btnClose);
+ MinimumSize = new Size(0, 36);
+ Name = "SizeCtrlTitleBar";
+ Padding = new Padding(3);
+ Size = new Size(549, 36);
+ ((System.ComponentModel.ISupportInitialize)btnClose).EndInit();
+ ResumeLayout(false);
+ }
+
+ #endregion
+ private PictureBox btnClose;
+ private Label j;
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeCtrlTitleBar.cs b/CanFly/UI/SizePanel/SizeCtrlTitleBar.cs
new file mode 100644
index 0000000..08294ca
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeCtrlTitleBar.cs
@@ -0,0 +1,38 @@
+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 CanFly.UI.SizePanel
+{
+ public partial class SizeCtrlTitleBar : UserControl
+ {
+ public event Action? OnCloseClicked;
+
+
+
+ [DisplayName("Title")]
+ public string Title
+ {
+ get { return this.j.Text; }
+ set { this.j.Text = value; }
+ }
+
+
+ public SizeCtrlTitleBar()
+ {
+ InitializeComponent();
+ this.Dock = DockStyle.Top;
+ }
+
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ OnCloseClicked?.Invoke();
+ }
+ }
+}
diff --git a/DHSoftware/Views/DetectConfigControl.resx b/CanFly/UI/SizePanel/SizeCtrlTitleBar.resx
similarity index 100%
rename from DHSoftware/Views/DetectConfigControl.resx
rename to CanFly/UI/SizePanel/SizeCtrlTitleBar.resx
diff --git a/CanFly/UI/SizePanel/SizeGuideCircleCtrl.Designer.cs b/CanFly/UI/SizePanel/SizeGuideCircleCtrl.Designer.cs
new file mode 100644
index 0000000..5a4c543
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideCircleCtrl.Designer.cs
@@ -0,0 +1,364 @@
+namespace CanFly.UI.SizePanel
+{
+ partial class SizeGuideCircleCtrl
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SizeGuideCircleCtrl));
+ splitContainer = new SplitContainer();
+ panel1 = new Panel();
+ canvas = new Canvas.UI.FlyCanvas();
+ statusStrip1 = new StatusStrip();
+ lblStatus = new ToolStripStatusLabel();
+ btnClose = new PictureBox();
+ label4 = new Label();
+ btnExecute = new Button();
+ lblElapsed = new Label();
+ ctrlTitleBar = new SizeCtrlTitleBar();
+ groupBox1 = new GroupBox();
+ label1 = new Label();
+ label2 = new Label();
+ label3 = new Label();
+ tbR = new TextBox();
+ tbY = new TextBox();
+ tbX = new TextBox();
+ btnLoadImage = new Button();
+ btnCreateCircle = new Button();
+ btnSave = new Button();
+ label6 = new Label();
+ lblResult = new Label();
+ panelGuide = new Panel();
+ ((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
+ splitContainer.Panel1.SuspendLayout();
+ splitContainer.Panel2.SuspendLayout();
+ splitContainer.SuspendLayout();
+ panel1.SuspendLayout();
+ statusStrip1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)btnClose).BeginInit();
+ groupBox1.SuspendLayout();
+ panelGuide.SuspendLayout();
+ SuspendLayout();
+ //
+ // splitContainer
+ //
+ splitContainer.Dock = DockStyle.Fill;
+ splitContainer.Location = new Point(0, 0);
+ splitContainer.Name = "splitContainer";
+ //
+ // splitContainer.Panel1
+ //
+ splitContainer.Panel1.Controls.Add(panelGuide);
+ splitContainer.Panel1MinSize = 150;
+ //
+ // splitContainer.Panel2
+ //
+ splitContainer.Panel2.Controls.Add(panel1);
+ splitContainer.Size = new Size(1280, 640);
+ splitContainer.SplitterDistance = 200;
+ splitContainer.TabIndex = 12;
+ //
+ // panel1
+ //
+ panel1.BorderStyle = BorderStyle.FixedSingle;
+ panel1.Controls.Add(canvas);
+ panel1.Controls.Add(statusStrip1);
+ panel1.Dock = DockStyle.Fill;
+ panel1.Location = new Point(0, 0);
+ panel1.Name = "panel1";
+ panel1.Size = new Size(1076, 640);
+ panel1.TabIndex = 1;
+ //
+ // canvas
+ //
+ canvas.AllowMultiSelect = false;
+ canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
+ canvas.Dock = DockStyle.Fill;
+ canvas.Enabled = false;
+ canvas.FillDrawing = false;
+ canvas.Location = new Point(0, 0);
+ canvas.Margin = new Padding(2);
+ canvas.Name = "canvas";
+ canvas.OutsideShapes = (List)resources.GetObject("canvas.OutsideShapes");
+ canvas.Scale = 1F;
+ canvas.Shapes = (List)resources.GetObject("canvas.Shapes");
+ canvas.Size = new Size(1074, 616);
+ canvas.TabIndex = 2;
+ //
+ // statusStrip1
+ //
+ statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
+ statusStrip1.Location = new Point(0, 616);
+ statusStrip1.Name = "statusStrip1";
+ statusStrip1.Size = new Size(1074, 22);
+ statusStrip1.TabIndex = 1;
+ statusStrip1.Text = "statusStrip1";
+ //
+ // lblStatus
+ //
+ lblStatus.Name = "lblStatus";
+ lblStatus.Size = new Size(44, 17);
+ lblStatus.Text = " ";
+ //
+ // btnClose
+ //
+ btnClose.Anchor = AnchorStyles.Top | AnchorStyles.Right;
+ btnClose.Image = XKRS.CanFly.Properties.Resources.Close;
+ btnClose.InitialImage = XKRS.CanFly.Properties.Resources.Close;
+ btnClose.Location = new Point(1102, 3);
+ btnClose.Name = "btnClose";
+ btnClose.Size = new Size(33, 33);
+ btnClose.SizeMode = PictureBoxSizeMode.StretchImage;
+ btnClose.TabIndex = 5;
+ btnClose.TabStop = false;
+ btnClose.Click += btnClose_Click;
+ //
+ // label4
+ //
+ label4.AutoSize = true;
+ label4.Location = new Point(6, 307);
+ label4.Name = "label4";
+ label4.Size = new Size(44, 17);
+ label4.TabIndex = 3;
+ label4.Text = "耗时:";
+ //
+ // btnExecute
+ //
+ btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnExecute.Location = new Point(6, 272);
+ btnExecute.Name = "btnExecute";
+ btnExecute.Size = new Size(186, 32);
+ btnExecute.TabIndex = 2;
+ btnExecute.Text = "执行";
+ btnExecute.UseVisualStyleBackColor = true;
+ btnExecute.Click += btnExecute_Click;
+ //
+ // lblElapsed
+ //
+ lblElapsed.AutoSize = true;
+ lblElapsed.Location = new Point(56, 307);
+ lblElapsed.Name = "lblElapsed";
+ lblElapsed.Size = new Size(32, 17);
+ lblElapsed.TabIndex = 4;
+ lblElapsed.Text = "0ms";
+ //
+ // ctrlTitleBar
+ //
+ ctrlTitleBar.Dock = DockStyle.Top;
+ ctrlTitleBar.Location = new Point(0, 0);
+ ctrlTitleBar.MinimumSize = new Size(0, 36);
+ ctrlTitleBar.Name = "ctrlTitleBar";
+ ctrlTitleBar.Padding = new Padding(3);
+ ctrlTitleBar.Size = new Size(198, 36);
+ ctrlTitleBar.TabIndex = 11;
+ ctrlTitleBar.Title = "圆形测量";
+ //
+ // groupBox1
+ //
+ groupBox1.Controls.Add(tbX);
+ groupBox1.Controls.Add(tbY);
+ groupBox1.Controls.Add(tbR);
+ groupBox1.Controls.Add(label3);
+ groupBox1.Controls.Add(label2);
+ groupBox1.Controls.Add(label1);
+ groupBox1.Dock = DockStyle.Top;
+ groupBox1.Location = new Point(0, 36);
+ groupBox1.Name = "groupBox1";
+ groupBox1.Size = new Size(198, 116);
+ groupBox1.TabIndex = 12;
+ groupBox1.TabStop = false;
+ groupBox1.Text = "圆参数";
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new Point(6, 25);
+ label1.Name = "label1";
+ label1.Size = new Size(19, 17);
+ label1.TabIndex = 0;
+ label1.Text = "X:";
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ label2.Location = new Point(6, 54);
+ label2.Name = "label2";
+ label2.Size = new Size(18, 17);
+ label2.TabIndex = 1;
+ label2.Text = "Y:";
+ //
+ // label3
+ //
+ label3.AutoSize = true;
+ label3.Location = new Point(3, 83);
+ label3.Name = "label3";
+ label3.Size = new Size(44, 17);
+ label3.TabIndex = 2;
+ label3.Text = "半径:";
+ //
+ // tbR
+ //
+ tbR.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbR.Location = new Point(56, 80);
+ tbR.Name = "tbR";
+ tbR.Size = new Size(136, 23);
+ tbR.TabIndex = 3;
+ //
+ // tbY
+ //
+ tbY.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbY.Location = new Point(56, 51);
+ tbY.Name = "tbY";
+ tbY.Size = new Size(136, 23);
+ tbY.TabIndex = 4;
+ //
+ // tbX
+ //
+ tbX.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbX.Location = new Point(56, 22);
+ tbX.Name = "tbX";
+ tbX.Size = new Size(136, 23);
+ tbX.TabIndex = 5;
+ //
+ // btnLoadImage
+ //
+ btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnLoadImage.Location = new Point(6, 158);
+ btnLoadImage.Name = "btnLoadImage";
+ btnLoadImage.Size = new Size(186, 32);
+ btnLoadImage.TabIndex = 13;
+ btnLoadImage.Text = "打开图片";
+ btnLoadImage.UseVisualStyleBackColor = true;
+ btnLoadImage.Click += btnLoadImage_Click;
+ //
+ // btnCreateCircle
+ //
+ btnCreateCircle.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnCreateCircle.Location = new Point(6, 196);
+ btnCreateCircle.Name = "btnCreateCircle";
+ btnCreateCircle.Size = new Size(186, 32);
+ btnCreateCircle.TabIndex = 14;
+ btnCreateCircle.Text = "创建圆形";
+ btnCreateCircle.UseVisualStyleBackColor = true;
+ btnCreateCircle.Click += btnCreateCircle_Click;
+ //
+ // btnSave
+ //
+ btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnSave.Location = new Point(9, 397);
+ btnSave.Name = "btnSave";
+ btnSave.Size = new Size(186, 32);
+ btnSave.TabIndex = 15;
+ btnSave.Text = "保存数据";
+ btnSave.UseVisualStyleBackColor = true;
+ btnSave.Click += btnSave_Click;
+ //
+ // label6
+ //
+ label6.AutoSize = true;
+ label6.Location = new Point(6, 338);
+ label6.Name = "label6";
+ label6.Size = new Size(44, 17);
+ label6.TabIndex = 16;
+ label6.Text = "结果:";
+ //
+ // lblResult
+ //
+ lblResult.AutoSize = true;
+ lblResult.Location = new Point(56, 338);
+ lblResult.Name = "lblResult";
+ lblResult.Size = new Size(20, 17);
+ lblResult.TabIndex = 17;
+ lblResult.Text = "无";
+ //
+ // panelGuide
+ //
+ panelGuide.BorderStyle = BorderStyle.FixedSingle;
+ panelGuide.Controls.Add(lblResult);
+ panelGuide.Controls.Add(label6);
+ panelGuide.Controls.Add(btnSave);
+ panelGuide.Controls.Add(btnCreateCircle);
+ panelGuide.Controls.Add(btnLoadImage);
+ panelGuide.Controls.Add(groupBox1);
+ panelGuide.Controls.Add(ctrlTitleBar);
+ panelGuide.Controls.Add(lblElapsed);
+ panelGuide.Controls.Add(btnExecute);
+ panelGuide.Controls.Add(label4);
+ panelGuide.Dock = DockStyle.Fill;
+ panelGuide.Location = new Point(0, 0);
+ panelGuide.Name = "panelGuide";
+ panelGuide.Size = new Size(200, 640);
+ panelGuide.TabIndex = 0;
+ //
+ // GuideCircleCtrl
+ //
+ Controls.Add(splitContainer);
+ Controls.Add(btnClose);
+ Name = "GuideCircleCtrl";
+ Size = new Size(1280, 640);
+ splitContainer.Panel1.ResumeLayout(false);
+ splitContainer.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
+ splitContainer.ResumeLayout(false);
+ panel1.ResumeLayout(false);
+ panel1.PerformLayout();
+ statusStrip1.ResumeLayout(false);
+ statusStrip1.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)btnClose).EndInit();
+ groupBox1.ResumeLayout(false);
+ groupBox1.PerformLayout();
+ panelGuide.ResumeLayout(false);
+ panelGuide.PerformLayout();
+ ResumeLayout(false);
+ }
+
+ #endregion
+
+ private SplitContainer splitContainer;
+ private Panel panel1;
+ private Canvas.UI.FlyCanvas canvas;
+ private StatusStrip statusStrip1;
+ private ToolStripStatusLabel lblStatus;
+ private PictureBox btnClose;
+ private Panel panelGuide;
+ private Label lblResult;
+ private Label label6;
+ private Button btnSave;
+ private Button btnCreateCircle;
+ private Button btnLoadImage;
+ private GroupBox groupBox1;
+ private TextBox tbX;
+ private TextBox tbY;
+ private TextBox tbR;
+ private Label label3;
+ private Label label2;
+ private Label label1;
+ private SizeCtrlTitleBar ctrlTitleBar;
+ private Label lblElapsed;
+ private Button btnExecute;
+ private Label label4;
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideCircleCtrl.cs b/CanFly/UI/SizePanel/SizeGuideCircleCtrl.cs
new file mode 100644
index 0000000..9135a88
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideCircleCtrl.cs
@@ -0,0 +1,361 @@
+using CanFly.Canvas.Shape;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using CanFly.Canvas.Helper;
+using CanFly.Helper;
+using HalconDotNet;
+using System.Diagnostics;
+using CanFly.Canvas.UI;
+
+
+namespace CanFly.UI.SizePanel
+{
+ public partial class SizeGuideCircleCtrl : SizeBaseGuideControl
+ {
+
+ private float _x;
+ private float _y;
+ private float _r;
+ private FlyShape? _circle;
+
+
+ protected override string GetScriptFileName() => "CircleMeasure.hdvp";
+
+
+
+
+ public SizeGuideCircleCtrl()
+ {
+ InitializeComponent();
+
+
+ this.canvas.mouseMoved += Canvas_mouseMoved;
+ this.canvas.OnShapeUpdateEvent += UpdateShape;
+ this.canvas.selectionChanged += Canvas_selectionChanged;
+
+ this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
+ this.canvas.newShape += Canvas_newShape;
+
+ this.ctrlTitleBar.OnCloseClicked += OnControlClose;
+ }
+
+
+
+ protected override void UpdateShape(FlyShape shape)
+ {
+ this._circle = shape;
+
+ _x = shape.Points[0].X;
+ _y = shape.Points[0].Y;
+ _r = PointHelper.Distance(shape.Points[0], shape.Points[1]);
+
+ this.tbX.Text = shape.Points[0].X.ToString("F3");
+ this.tbY.Text = shape.Points[0].Y.ToString("F3");
+ this.tbR.Text = _r.ToString("F3");
+ }
+
+
+
+
+ private void btnExecute_Click(object sender, EventArgs e)
+ {
+
+
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ if(this.tbX.Text.Trim().Length == 0)
+ {
+ MessageBox.Show("请先创建圆形");
+ return;
+ }
+
+
+ this.canvas.OutsideShapes.Clear();
+ this.canvas.Invalidate();
+
+ flag = new List();
+ x = new List();
+ y = new List();
+ r = new List();
+ Dictionary inputImg = new Dictionary();
+
+ if (hImage == null)
+ {
+ HOperatorSet.ReadImage(out hImage, CurrentImageFile);
+ }
+ inputImg["INPUT_Image"] = hImage;
+
+ Dictionary inputPara = new Dictionary();
+
+
+ inputPara["XCenter"] = _x;
+ inputPara["YCenter"] = _y;
+ inputPara["Radius"] = _r;
+
+
+ List outputKeys = new List()
+ {
+ "OUTPUT_PreTreatedImage",
+ "OUTPUT_Flag",
+ "RXCenter",
+ "RYCenter",
+ "RRadius"
+ };
+
+ ExecuteHScript(
+ inputImg,
+ inputPara,
+ outputKeys);
+
+ }
+ List flag = new List(), x=new List(),y=new List(),r=new List();
+
+ protected override void OnExecuteHScriptResult(
+ bool success,
+ Dictionary resultDic,
+ int timeElasped)
+ {
+ if (!success)
+ {
+ return;
+ }
+
+
+ /*
+ "OUTPUT_Flag",
+ "RXCenter",
+ "RYCenter",
+ "RRadius"
+ */
+
+ //取图?????
+
+
+
+ flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
+ x = resultDic["RXCenter"].HTupleToDouble();
+ y = resultDic["RYCenter"].HTupleToDouble();
+ r = resultDic["RRadius"].HTupleToDouble();
+
+
+
+
+
+
+
+
+
+ if (flag.Count > 0)
+ {
+ lblResult.Text = flag[0].ToString();
+
+ }
+ else
+ {
+ lblResult.Text = "无";
+ }
+ if (flag.Count > 0 && x.Count > 0 && y.Count > 0 && r.Count > 0)
+ {
+
+ //detectResult.VisionImageSet.MLImage = resultDic["RRadius"].GetResultObject("OUTPUT_PreTreatedImage");
+ this.canvas.DrawCircle(new PointF((float)x[0], (float)y[0]), (float)r[0]);
+ lblElapsed.Text = $"{timeElasped} ms";
+ }
+ }
+
+
+
+
+ private void Test()
+ {
+ string filePath = Path.Combine(_hScriptsDir, GetScriptFileName());
+ if (!File.Exists(filePath))
+ {
+ MessageBox.Show($"文件 {filePath} 不存在");
+ return;
+ }
+
+
+ try
+ {
+ HDevEngineTool tool = new HDevEngineTool(_hScriptsDir);
+ tool.LoadProcedure(Path.GetFileNameWithoutExtension(GetScriptFileName()));
+
+
+ if (hImage == null)
+ {
+ HOperatorSet.ReadImage(out hImage, CurrentImageFile);
+ }
+
+ tool.InputImageDic["INPUT_Image"] = hImage;
+ tool.InputTupleDic["XCenter"] = _x;
+ tool.InputTupleDic["YCenter"] = _y;
+ tool.InputTupleDic["Radius"] = _r;
+
+
+
+ if (!tool.RunProcedure(out string error, out int timeElasped))
+ {
+ throw new Exception();
+ }
+
+ HTuple hFlag = tool.GetResultTuple("OUTPUT_Flag");
+
+ var flag = tool.GetResultTuple("OUTPUT_Flag").HTupleToDouble();
+ List x = tool.GetResultTuple("RXCenter").HTupleToDouble();
+ var y = tool.GetResultTuple("RYCenter").HTupleToDouble();
+ var r = tool.GetResultTuple("RRadius").HTupleToDouble();
+ if (flag.Count > 0)
+ {
+ lblResult.Text = flag[0].ToString();
+
+ }
+ else
+ {
+ lblResult.Text = "无";
+ }
+ if (flag.Count > 0 && x.Count > 0 && y.Count > 0 && r.Count > 0)
+ {
+ this.canvas.DrawCircle(new PointF((float)x[0], (float)y[0]), (float)r[0]);
+ lblElapsed.Text = $"{timeElasped} ms";
+ }
+
+ //
+ Debug.WriteLine("");
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ finally
+ {
+ hImage?.Dispose();
+ hImage = null;
+ }
+
+
+ }
+
+
+
+ private void btnClose_Click(object sender, EventArgs e)
+ {
+ OnControlCloseEvent?.Invoke();
+ }
+
+ private void btnLoadImage_Click(object sender, EventArgs e)
+ {
+ OpenImageFile(bitmap =>
+ {
+ this.canvas.LoadPixmap(bitmap);
+ this.canvas.Enabled = true;
+ });
+ }
+
+
+
+
+ private void Canvas_mouseMoved(PointF pos)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(Canvas_mouseMoved, pos);
+ return;
+ }
+
+ lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
+
+ }
+
+
+
+
+ private void Canvas_selectionChanged(List shapes)
+ {
+ //if (shapes.Count != 1)
+ //{
+ // // panelGuide.Controls.Clear();
+ // return;
+ //}
+ //SwitchGuideForm(shapes[0].ShapeType);
+ // Canvas_OnShapeUpdateEvent(shapes[0]);
+
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+ UpdateShape(shapes[0]);
+
+ }
+
+
+ private void Canvas_OnShapeMoving(List shapes)
+ {
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+
+ UpdateShape(shapes[0]);
+ }
+
+ private void btnCreateCircle_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ this.tbX.Text = string.Empty;
+ this.tbY.Text = string.Empty;
+ this.tbR.Text = string.Empty;
+ this.canvas.Shapes.Clear();
+ this.canvas.Invalidate();
+ this.canvas.StartDraw(ShapeTypeEnum.Circle);
+ this.canvas.Enabled = true;
+ }
+
+
+
+ private void Canvas_newShape()
+ {
+
+ this.canvas.StopDraw();
+ }
+
+ private void btnSave_Click(object sender, EventArgs e)
+ {
+ if (lblResult.Text.Equals("无"))
+ {
+ MessageBox.Show("请先进行绘制");
+ return;
+ }
+ if(lblResult.Text != "0")
+ {
+ MessageBox.Show("测量计算错误,无法保存");
+ return;
+ }
+
+ //List x = tool.GetResultTuple("RXCenter").HTupleToDouble();
+ //var y = tool.GetResultTuple("RYCenter").HTupleToDouble();
+ //var r = tool.GetResultTuple("RRadius").HTupleToDouble();
+ //tool.InputTupleDic["XCenter"] = _x;
+ //tool.InputTupleDic["YCenter"] = _y;
+ //tool.InputTupleDic["Radius"] = _r;
+ string inputput = $"XCenter:{string.Join(";", _x)};YCenter:{string.Join(";", _y)};RRadius:{string.Join(";", _r)}";
+ string output = $"RXCenter:{string.Join(";", x[0])};RYCenter:{string.Join(";", y[0])};RRadius:{string.Join(";", r[0])}";
+
+ DataToTriggerEvent(inputput,output);
+ }
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideCircleCtrl.resx b/CanFly/UI/SizePanel/SizeGuideCircleCtrl.resx
new file mode 100644
index 0000000..097e294
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideCircleCtrl.resx
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/CanFly/UI/SizePanel/SizeGuideHeightCtrl.Designer.cs b/CanFly/UI/SizePanel/SizeGuideHeightCtrl.Designer.cs
new file mode 100644
index 0000000..3b2ffde
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideHeightCtrl.Designer.cs
@@ -0,0 +1,471 @@
+namespace CanFly.UI.SizePanel
+{
+ partial class SizeGuideHeightCtrl
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SizeGuideHeightCtrl));
+ splitter1 = new AntdUI.Splitter();
+ panel1 = new AntdUI.Panel();
+ canvas = new Canvas.UI.FlyCanvas();
+ panel2 = new AntdUI.Panel();
+ ctrlTitleBar = new GuidePanel.CtrlTitleBar();
+ statusStrip1 = new StatusStrip();
+ lblStatus = new ToolStripStatusLabel();
+ groupBox2 = new GroupBox();
+ tbLineX1 = new AntdUI.Input();
+ label1 = new AntdUI.Label();
+ label4 = new AntdUI.Label();
+ tbLineY1 = new AntdUI.Input();
+ label3 = new AntdUI.Label();
+ tbLineY2 = new AntdUI.Input();
+ label5 = new AntdUI.Label();
+ tbLineX2 = new AntdUI.Input();
+ label6 = new AntdUI.Label();
+ label7 = new AntdUI.Label();
+ tbwidth = new AntdUI.Input();
+ tbheight = new AntdUI.Input();
+ label2 = new AntdUI.Label();
+ CamName = new AntdUI.Input();
+ groupBox1 = new GroupBox();
+ switch1 = new AntdUI.Switch();
+ label8 = new AntdUI.Label();
+ button1 = new AntdUI.Button();
+ button2 = new AntdUI.Button();
+ button3 = new AntdUI.Button();
+ label9 = new AntdUI.Label();
+ lblElapsed = new AntdUI.Label();
+ lblResult = new AntdUI.Label();
+ label12 = new AntdUI.Label();
+ btnSave = new AntdUI.Button();
+ ((System.ComponentModel.ISupportInitialize)splitter1).BeginInit();
+ splitter1.Panel1.SuspendLayout();
+ splitter1.Panel2.SuspendLayout();
+ splitter1.SuspendLayout();
+ panel1.SuspendLayout();
+ panel2.SuspendLayout();
+ statusStrip1.SuspendLayout();
+ groupBox2.SuspendLayout();
+ groupBox1.SuspendLayout();
+ SuspendLayout();
+ //
+ // splitter1
+ //
+ splitter1.Dock = DockStyle.Fill;
+ splitter1.Location = new Point(0, 0);
+ splitter1.Name = "splitter1";
+ //
+ // splitter1.Panel1
+ //
+ splitter1.Panel1.Controls.Add(panel2);
+ //
+ // splitter1.Panel2
+ //
+ splitter1.Panel2.Controls.Add(panel1);
+ splitter1.Size = new Size(1280, 640);
+ splitter1.SplitterDistance = 286;
+ splitter1.TabIndex = 0;
+ //
+ // panel1
+ //
+ panel1.Controls.Add(statusStrip1);
+ panel1.Controls.Add(canvas);
+ panel1.Dock = DockStyle.Fill;
+ panel1.Location = new Point(0, 0);
+ panel1.Name = "panel1";
+ panel1.Size = new Size(990, 640);
+ panel1.TabIndex = 0;
+ panel1.Text = "panel1";
+ //
+ // canvas
+ //
+ canvas.AllowMultiSelect = false;
+ canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
+ canvas.Dock = DockStyle.Fill;
+ canvas.FillDrawing = false;
+ canvas.Location = new Point(0, 0);
+ canvas.Margin = new Padding(2);
+ canvas.Name = "canvas";
+ canvas.OutsideShapes = (List)resources.GetObject("canvas.OutsideShapes");
+ canvas.Scale = 1F;
+ canvas.Shapes = (List)resources.GetObject("canvas.Shapes");
+ canvas.Size = new Size(990, 640);
+ canvas.TabIndex = 0;
+ //
+ // panel2
+ //
+ panel2.Controls.Add(btnSave);
+ panel2.Controls.Add(lblResult);
+ panel2.Controls.Add(label12);
+ panel2.Controls.Add(lblElapsed);
+ panel2.Controls.Add(label9);
+ panel2.Controls.Add(button3);
+ panel2.Controls.Add(button2);
+ panel2.Controls.Add(groupBox1);
+ panel2.Controls.Add(groupBox2);
+ panel2.Controls.Add(ctrlTitleBar);
+ panel2.Dock = DockStyle.Fill;
+ panel2.Location = new Point(0, 0);
+ panel2.Name = "panel2";
+ panel2.Size = new Size(286, 640);
+ panel2.TabIndex = 0;
+ panel2.Text = "panel2";
+ //
+ // ctrlTitleBar
+ //
+ ctrlTitleBar.Dock = DockStyle.Top;
+ ctrlTitleBar.Location = new Point(0, 0);
+ ctrlTitleBar.MinimumSize = new Size(0, 36);
+ ctrlTitleBar.Name = "ctrlTitleBar";
+ ctrlTitleBar.Padding = new Padding(3);
+ ctrlTitleBar.Size = new Size(286, 36);
+ ctrlTitleBar.TabIndex = 12;
+ ctrlTitleBar.Title = "高度测量";
+ //
+ // statusStrip1
+ //
+ statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
+ statusStrip1.Location = new Point(0, 618);
+ statusStrip1.Name = "statusStrip1";
+ statusStrip1.Size = new Size(990, 22);
+ statusStrip1.TabIndex = 2;
+ statusStrip1.Text = "statusStrip1";
+ //
+ // lblStatus
+ //
+ lblStatus.Name = "lblStatus";
+ lblStatus.Size = new Size(44, 17);
+ lblStatus.Text = " ";
+ //
+ // groupBox2
+ //
+ groupBox2.Controls.Add(tbheight);
+ groupBox2.Controls.Add(tbwidth);
+ groupBox2.Controls.Add(label7);
+ groupBox2.Controls.Add(label6);
+ groupBox2.Controls.Add(label3);
+ groupBox2.Controls.Add(tbLineY2);
+ groupBox2.Controls.Add(label5);
+ groupBox2.Controls.Add(tbLineX2);
+ groupBox2.Controls.Add(label4);
+ groupBox2.Controls.Add(tbLineY1);
+ groupBox2.Controls.Add(label1);
+ groupBox2.Controls.Add(tbLineX1);
+ groupBox2.Dock = DockStyle.Top;
+ groupBox2.Location = new Point(0, 36);
+ groupBox2.Name = "groupBox2";
+ groupBox2.Size = new Size(286, 229);
+ groupBox2.TabIndex = 14;
+ groupBox2.TabStop = false;
+ groupBox2.Text = "线参数";
+ //
+ // tbLineX1
+ //
+ tbLineX1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineX1.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ tbLineX1.Location = new Point(62, 22);
+ tbLineX1.Name = "tbLineX1";
+ tbLineX1.Radius = 3;
+ tbLineX1.Size = new Size(214, 32);
+ tbLineX1.TabIndex = 17;
+ //
+ // label1
+ //
+ label1.Location = new Point(6, 22);
+ label1.Name = "label1";
+ label1.Size = new Size(38, 32);
+ label1.TabIndex = 19;
+ label1.Text = " X1:";
+ //
+ // label4
+ //
+ label4.Location = new Point(6, 60);
+ label4.Name = "label4";
+ label4.Size = new Size(38, 32);
+ label4.TabIndex = 23;
+ label4.Text = " Y1:";
+ //
+ // tbLineY1
+ //
+ tbLineY1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineY1.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ tbLineY1.Location = new Point(62, 60);
+ tbLineY1.Name = "tbLineY1";
+ tbLineY1.Radius = 3;
+ tbLineY1.Size = new Size(214, 32);
+ tbLineY1.TabIndex = 22;
+ //
+ // label3
+ //
+ label3.Location = new Point(6, 136);
+ label3.Name = "label3";
+ label3.Size = new Size(38, 32);
+ label3.TabIndex = 27;
+ label3.Text = " Y2:";
+ //
+ // tbLineY2
+ //
+ tbLineY2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineY2.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ tbLineY2.Location = new Point(62, 136);
+ tbLineY2.Name = "tbLineY2";
+ tbLineY2.Radius = 3;
+ tbLineY2.Size = new Size(214, 32);
+ tbLineY2.TabIndex = 26;
+ //
+ // label5
+ //
+ label5.Location = new Point(6, 98);
+ label5.Name = "label5";
+ label5.Size = new Size(38, 32);
+ label5.TabIndex = 25;
+ label5.Text = " X2:";
+ //
+ // tbLineX2
+ //
+ tbLineX2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineX2.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ tbLineX2.Location = new Point(62, 98);
+ tbLineX2.Name = "tbLineX2";
+ tbLineX2.Radius = 3;
+ tbLineX2.Size = new Size(214, 32);
+ tbLineX2.TabIndex = 24;
+ //
+ // label6
+ //
+ label6.Location = new Point(6, 174);
+ label6.Name = "label6";
+ label6.Size = new Size(50, 32);
+ label6.TabIndex = 28;
+ label6.Text = " 宽:";
+ //
+ // label7
+ //
+ label7.Location = new Point(145, 177);
+ label7.Name = "label7";
+ label7.Size = new Size(29, 32);
+ label7.TabIndex = 29;
+ label7.Text = "高:";
+ //
+ // tbwidth
+ //
+ tbwidth.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbwidth.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ tbwidth.Location = new Point(62, 177);
+ tbwidth.Name = "tbwidth";
+ tbwidth.Radius = 3;
+ tbwidth.Size = new Size(77, 32);
+ tbwidth.TabIndex = 30;
+ //
+ // tbheight
+ //
+ tbheight.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbheight.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ tbheight.Location = new Point(180, 177);
+ tbheight.Name = "tbheight";
+ tbheight.Radius = 3;
+ tbheight.Size = new Size(96, 32);
+ tbheight.TabIndex = 31;
+ //
+ // label2
+ //
+ label2.Location = new Point(6, 22);
+ label2.Name = "label2";
+ label2.Size = new Size(55, 32);
+ label2.TabIndex = 1;
+ label2.Text = "相机名:";
+ //
+ // CamName
+ //
+ CamName.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ CamName.Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ CamName.Location = new Point(64, 22);
+ CamName.Name = "CamName";
+ CamName.Radius = 3;
+ CamName.ReadOnly = true;
+ CamName.Size = new Size(212, 32);
+ CamName.TabIndex = 18;
+ //
+ // groupBox1
+ //
+ groupBox1.Controls.Add(button1);
+ groupBox1.Controls.Add(label8);
+ groupBox1.Controls.Add(switch1);
+ groupBox1.Controls.Add(label2);
+ groupBox1.Controls.Add(CamName);
+ groupBox1.Dock = DockStyle.Top;
+ groupBox1.Location = new Point(0, 265);
+ groupBox1.Name = "groupBox1";
+ groupBox1.Size = new Size(286, 105);
+ groupBox1.TabIndex = 19;
+ groupBox1.TabStop = false;
+ groupBox1.Text = "相机控制";
+ //
+ // switch1
+ //
+ switch1.Location = new Point(67, 60);
+ switch1.Name = "switch1";
+ switch1.Size = new Size(72, 32);
+ switch1.TabIndex = 19;
+ switch1.Text = "switch1";
+ //
+ // label8
+ //
+ label8.Location = new Point(6, 60);
+ label8.Name = "label8";
+ label8.Size = new Size(55, 32);
+ label8.TabIndex = 20;
+ label8.Text = "硬触发:";
+ //
+ // button1
+ //
+ button1.Location = new Point(145, 60);
+ button1.Name = "button1";
+ button1.Size = new Size(131, 32);
+ button1.TabIndex = 21;
+ button1.Text = "软触发一次";
+ //
+ // button2
+ //
+ button2.Location = new Point(0, 376);
+ button2.Name = "button2";
+ button2.Size = new Size(276, 37);
+ button2.TabIndex = 22;
+ button2.Text = "创建矩形";
+ button2.Type = AntdUI.TTypeMini.Primary;
+ //
+ // button3
+ //
+ button3.Location = new Point(0, 419);
+ button3.Name = "button3";
+ button3.Size = new Size(276, 36);
+ button3.TabIndex = 23;
+ button3.Text = "执行";
+ button3.Type = AntdUI.TTypeMini.Primary;
+ //
+ // label9
+ //
+ label9.Location = new Point(6, 461);
+ label9.Name = "label9";
+ label9.Size = new Size(50, 23);
+ label9.TabIndex = 24;
+ label9.Text = "耗时:";
+ //
+ // lblElapsed
+ //
+ lblElapsed.Location = new Point(67, 461);
+ lblElapsed.Name = "lblElapsed";
+ lblElapsed.Size = new Size(72, 23);
+ lblElapsed.TabIndex = 25;
+ lblElapsed.Text = "0 ms";
+ //
+ // lblResult
+ //
+ lblResult.Location = new Point(67, 490);
+ lblResult.Name = "lblResult";
+ lblResult.Size = new Size(72, 23);
+ lblResult.TabIndex = 27;
+ lblResult.Text = "无";
+ //
+ // label12
+ //
+ label12.Location = new Point(6, 490);
+ label12.Name = "label12";
+ label12.Size = new Size(50, 23);
+ label12.TabIndex = 26;
+ label12.Text = "结果:";
+ //
+ // btnSave
+ //
+ btnSave.Location = new Point(0, 519);
+ btnSave.Name = "btnSave";
+ btnSave.Size = new Size(276, 36);
+ btnSave.TabIndex = 28;
+ btnSave.Text = "保存数据";
+ btnSave.Type = AntdUI.TTypeMini.Primary;
+ //
+ // SizeGuideHeightCtrl
+ //
+ AutoScaleDimensions = new SizeF(7F, 17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ Controls.Add(splitter1);
+ Name = "SizeGuideHeightCtrl";
+ Size = new Size(1280, 640);
+ Load += GuideLineCircleCtrl_Load;
+ splitter1.Panel1.ResumeLayout(false);
+ splitter1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)splitter1).EndInit();
+ splitter1.ResumeLayout(false);
+ panel1.ResumeLayout(false);
+ panel1.PerformLayout();
+ panel2.ResumeLayout(false);
+ statusStrip1.ResumeLayout(false);
+ statusStrip1.PerformLayout();
+ groupBox2.ResumeLayout(false);
+ groupBox1.ResumeLayout(false);
+ ResumeLayout(false);
+ }
+
+ #endregion
+ private TextBox tbRectWidth1;
+ private AntdUI.Splitter splitter1;
+ private AntdUI.Panel panel1;
+ private Canvas.UI.FlyCanvas canvas;
+ private AntdUI.Panel panel2;
+ private GuidePanel.CtrlTitleBar ctrlTitleBar;
+ private StatusStrip statusStrip1;
+ private ToolStripStatusLabel lblStatus;
+ private GroupBox groupBox2;
+
+ private Canvas.UI.FlyCanvas flyCanvas1;
+ private AntdUI.Input tbLineX1;
+ private AntdUI.Label label1;
+ private AntdUI.Label label3;
+ private AntdUI.Input tbLineY2;
+ private AntdUI.Label label5;
+ private AntdUI.Input tbLineX2;
+ private AntdUI.Label label4;
+ private AntdUI.Input tbLineY1;
+ private AntdUI.Label label7;
+ private AntdUI.Label label6;
+ private AntdUI.Input tbwidth;
+ private AntdUI.Input tbheight;
+ private GroupBox groupBox1;
+ private AntdUI.Label label2;
+ private AntdUI.Input CamName;
+ private AntdUI.Button button1;
+ private AntdUI.Label label8;
+ private AntdUI.Switch switch1;
+ private AntdUI.Button button2;
+ private AntdUI.Button button3;
+ private AntdUI.Label lblElapsed;
+ private AntdUI.Label label9;
+ private AntdUI.Label lblResult;
+ private AntdUI.Label label12;
+ private AntdUI.Button btnSave;
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideHeightCtrl.cs b/CanFly/UI/SizePanel/SizeGuideHeightCtrl.cs
new file mode 100644
index 0000000..a93f9f3
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideHeightCtrl.cs
@@ -0,0 +1,346 @@
+using CanFly.Canvas.Helper;
+using CanFly.Canvas.Shape;
+using CanFly.Canvas.UI;
+using CanFly.Helper;
+using HalconDotNet;
+using OpenCvSharp;
+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 CanFly.UI.SizePanel
+{
+ public partial class SizeGuideHeightCtrl : SizeBaseGuideControl
+ {
+
+
+
+ private FlyShape? _line;
+
+
+ private float _lineX1;
+ private float _lineY1;
+ private float _lineX2;
+ private float _lineY2;
+ float width, height;
+ private float _lineWidth;
+ private PointF[] _rectPoints = new PointF[4];
+ //private float _LineLX=new float();
+ //private float _LineLY =new float();
+ //private float _LineRX =new float();
+ //private float _LineRY =new float();
+
+
+
+
+
+ protected override string GetScriptFileName() => "HeightMeasure.hdvp";
+
+
+
+ public SizeGuideHeightCtrl()
+ {
+ InitializeComponent();
+
+ this.canvas.mouseMoved += Canvas_mouseMoved;
+ this.canvas.OnShapeUpdateEvent += UpdateShape;
+ this.canvas.selectionChanged += Canvas_selectionChanged;
+
+ this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
+ this.canvas.newShape += Canvas_newShape;
+
+ this.ctrlTitleBar.OnCloseClicked += OnControlClose;
+
+
+
+ }
+
+
+
+ protected override void UpdateShape(FlyShape shape)
+ {
+ switch (shape.ShapeType)
+ {
+ case ShapeTypeEnum.Rectangle:
+ this._line = shape;
+
+ var pts = this._line.Points;
+
+ _lineX1 = pts[0].X;
+ _lineY1 = pts[0].Y;
+ _lineX2 = pts[1].X;
+ _lineY2 = pts[1].Y;
+ _lineWidth = shape.LineVirtualRectWidth;
+ _rectPoints = shape.LineVirtualRectPoints;
+ //_LineLX = (shape.LineVirtualRectPoints[0].X + shape.LineVirtualRectPoints[3].X) / 2;
+ //_LineLY = (shape.LineVirtualRectPoints[0].Y + shape.LineVirtualRectPoints[3].Y) / 2;
+ //_LineRX = (shape.LineVirtualRectPoints[1].X + shape.LineVirtualRectPoints[2].X) / 2;
+ //_LineRY = (shape.LineVirtualRectPoints[1].Y + shape.LineVirtualRectPoints[2].Y) / 2;
+
+ width = Math.Abs(_lineX2 - _lineX1);
+ height = Math.Abs(_lineY2 - _lineY1);
+
+
+ tbLineX1.Text = _lineX1.ToString("F3");
+ tbLineY1.Text = _lineY1.ToString("F3");
+ tbLineX2.Text = _lineX2.ToString("F3");
+ tbLineY2.Text = _lineY2.ToString("F3");
+ tbwidth.Text = width.ToString();
+ tbheight.Text = height.ToString();
+ // NumRectWidth1.Value = (decimal)_lineWidth;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+
+
+
+ private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
+ {
+
+
+
+ }
+
+
+
+
+ private void Canvas_mouseMoved(PointF pos)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(Canvas_mouseMoved, pos);
+ return;
+ }
+
+ lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
+
+ }
+
+
+
+
+ private void Canvas_selectionChanged(List shapes)
+ {
+ //if (shapes.Count != 1)
+ //{
+ // // panelGuide.Controls.Clear();
+ // return;
+ //}
+ //SwitchGuideForm(shapes[0].ShapeType);
+ // Canvas_OnShapeUpdateEvent(shapes[0]);
+
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+ UpdateShape(shapes[0]);
+
+ }
+
+
+
+ private void Canvas_OnShapeMoving(List shapes)
+ {
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+
+ UpdateShape(shapes[0]);
+ }
+
+
+
+
+
+
+
+ private void btnCreateLine_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ tbLineX1.Text = string.Empty;
+ tbLineY1.Text = string.Empty;
+ tbLineX2.Text = string.Empty;
+ tbLineY2.Text = string.Empty; ;
+ tbwidth.Text = string.Empty; ;
+ tbheight.Text = string.Empty; ;
+ this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Rectangle);
+ this.canvas.Invalidate();
+ this.canvas.StartDraw(ShapeTypeEnum.Rectangle);
+
+ }
+
+
+
+ private void btnLoadImage_Click(object sender, EventArgs e)
+ {
+ OpenImageFile(bitmap =>
+ {
+ this.canvas.LoadPixmap(bitmap);
+ this.canvas.Enabled = true;
+
+
+ });
+ }
+
+
+ private void Canvas_newShape()
+ {
+ this.canvas.StopDraw();
+ }
+
+ private void btnExecute_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ if (this.tbLineX1.Text.Trim().Length == 0)
+ {
+ MessageBox.Show("请先创建矩形");
+ return;
+ }
+ this.canvas.OutsideShapes.Clear();
+ this.canvas.Invalidate();
+
+
+ flag = new List();
+
+ Line1Para = new List();
+ Line2Para = new List();
+ iHeight = new List();
+ Dictionary inputImg = new Dictionary();
+
+ if (hImage == null)
+ {
+ HOperatorSet.ReadImage(out hImage, CurrentImageFile);
+ }
+ inputImg["INPUT_Image"] = hImage;
+
+
+ Dictionary inputPara = new Dictionary();
+
+
+ inputPara["row"] = _lineY1;
+ inputPara["column"] = _lineX1;
+ inputPara["Width"] = width;
+ inputPara["Height"] = height;
+
+
+
+ List outputKeys = new List()
+ {
+ "OUTPUT_PreTreatedImage",
+ "OUTPUT_Flag",
+
+ "Line1Para",
+ "Line2Para",
+ "iHeight"
+ };
+
+ ExecuteHScript(
+ inputImg,
+ inputPara,
+ outputKeys);
+
+ }
+
+
+ List flag = new List();
+ List Line1Para = new List();
+ List Line2Para = new List();
+
+ List iHeight = new List();
+
+
+ protected override void OnExecuteHScriptResult(
+ bool success,
+ Dictionary resultDic,
+ int timeElasped)
+ {
+ if (!success)
+ {
+ return;
+ }
+
+
+ /*
+ "OUTPUT_Flag",
+ "RXCenter",
+ "RYCenter",
+ "RRadius"
+ */
+
+ flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
+
+ Line1Para = resultDic["Line1Para"].HTupleToDouble();
+ Line2Para = resultDic["Line2Para"].HTupleToDouble();
+ // EndRow = resultDic["EndRow"].HTupleToDouble();
+ //EndCloumn = resultDic["EndColumn"].HTupleToDouble();
+ iHeight = resultDic["iHeight"].HTupleToDouble();
+
+ if (flag.Count > 0)
+ {
+ lblResult.Text = flag[0].ToString();
+
+ }
+ else
+ {
+ lblResult.Text = "无";
+ }
+ if (flag.Count > 0 && Line1Para.Count == 4 && Line2Para.Count == 4 && iHeight.Count > 0)
+ {
+ float width = 0;
+ this.canvas.DrawLine(new PointF((float)Line1Para[1], (float)Line1Para[0]), new PointF((float)Line1Para[3], (float)Line1Para[2]), 0);
+ this.canvas.DrawLine(new PointF((float)Line2Para[1], (float)Line2Para[0]), new PointF((float)Line2Para[3], (float)Line2Para[2]), 0);
+ this.canvas.Invalidate();
+ lblElapsed.Text = $"{timeElasped} ms";
+ }
+ }
+
+
+
+ private void btnSave_Click(object sender, EventArgs e)
+ {
+ if (lblResult.Text.Equals("无"))
+ {
+ MessageBox.Show("请先进行绘制");
+ return;
+ }
+ if (lblResult.Text != "0")
+ {
+ MessageBox.Show("测量计算错误,无法保存");
+ return;
+ }
+
+
+
+ string input = $"row:{string.Join(";", _lineY1)};column:{string.Join(";", _lineX1)};" +
+ $"Width:{string.Join(";", width)};Height:{string.Join(";", height)}";
+
+ string output = $"iHeight:{string.Join(";", iHeight[0])}";
+ DataToTriggerEvent(input, output);
+ }
+
+ private void tbLineX1_TextChanged(object sender, EventArgs e)
+ {
+
+ }
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideHeightCtrl.resx b/CanFly/UI/SizePanel/SizeGuideHeightCtrl.resx
new file mode 100644
index 0000000..ccbe56c
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideHeightCtrl.resx
@@ -0,0 +1,148 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.Designer.cs b/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.Designer.cs
new file mode 100644
index 0000000..c0f603e
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.Designer.cs
@@ -0,0 +1,550 @@
+namespace CanFly.UI.SizePanel
+{
+ partial class SizeGuideLineCircleCtrl
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SizeGuideLineCircleCtrl));
+ lblElapsed = new Label();
+ label4 = new Label();
+ splitContainer = new SplitContainer();
+ panelGuide = new Panel();
+ lblDistance = new Label();
+ label17 = new Label();
+ lblResult = new Label();
+ label15 = new Label();
+ btnCreateLine = new Button();
+ btnCreateCircle = new Button();
+ btnLoadImage = new Button();
+ label9 = new Label();
+ btnExecute = new Button();
+ label10 = new Label();
+ groupBox2 = new GroupBox();
+ NumRectWidth1 = new NumericUpDown();
+ label11 = new Label();
+ tbLineX2 = new TextBox();
+ label8 = new Label();
+ tbLineY2 = new TextBox();
+ label5 = new Label();
+ tbLineX1 = new TextBox();
+ tbLineY1 = new TextBox();
+ label6 = new Label();
+ label7 = new Label();
+ groupBox1 = new GroupBox();
+ tbCircleX = new TextBox();
+ tbCircleY = new TextBox();
+ tbCircleR = new TextBox();
+ label3 = new Label();
+ label2 = new Label();
+ label1 = new Label();
+ ctrlTitleBar = new SizeCtrlTitleBar();
+ panel1 = new Panel();
+ canvas = new Canvas.UI.FlyCanvas();
+ statusStrip1 = new StatusStrip();
+ lblStatus = new ToolStripStatusLabel();
+ btnSave = new Button();
+ ((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
+ splitContainer.Panel1.SuspendLayout();
+ splitContainer.Panel2.SuspendLayout();
+ splitContainer.SuspendLayout();
+ panelGuide.SuspendLayout();
+ groupBox2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth1).BeginInit();
+ groupBox1.SuspendLayout();
+ panel1.SuspendLayout();
+ statusStrip1.SuspendLayout();
+ SuspendLayout();
+ //
+ // lblElapsed
+ //
+ lblElapsed.AutoSize = true;
+ lblElapsed.Location = new Point(50, 328);
+ lblElapsed.Name = "lblElapsed";
+ lblElapsed.Size = new Size(32, 17);
+ lblElapsed.TabIndex = 9;
+ lblElapsed.Text = "0ms";
+ //
+ // label4
+ //
+ label4.AutoSize = true;
+ label4.Location = new Point(0, 328);
+ label4.Name = "label4";
+ label4.Size = new Size(44, 17);
+ label4.TabIndex = 8;
+ label4.Text = "耗时:";
+ //
+ // splitContainer
+ //
+ splitContainer.Dock = DockStyle.Fill;
+ splitContainer.Location = new Point(0, 0);
+ splitContainer.Name = "splitContainer";
+ //
+ // splitContainer.Panel1
+ //
+ splitContainer.Panel1.Controls.Add(panelGuide);
+ splitContainer.Panel1MinSize = 150;
+ //
+ // splitContainer.Panel2
+ //
+ splitContainer.Panel2.Controls.Add(panel1);
+ splitContainer.Size = new Size(1280, 640);
+ splitContainer.SplitterDistance = 200;
+ splitContainer.TabIndex = 11;
+ //
+ // panelGuide
+ //
+ panelGuide.BorderStyle = BorderStyle.FixedSingle;
+ panelGuide.Controls.Add(btnSave);
+ panelGuide.Controls.Add(lblDistance);
+ panelGuide.Controls.Add(label17);
+ panelGuide.Controls.Add(lblResult);
+ panelGuide.Controls.Add(label15);
+ panelGuide.Controls.Add(btnCreateLine);
+ panelGuide.Controls.Add(btnCreateCircle);
+ panelGuide.Controls.Add(btnLoadImage);
+ panelGuide.Controls.Add(label9);
+ panelGuide.Controls.Add(btnExecute);
+ panelGuide.Controls.Add(label10);
+ panelGuide.Controls.Add(groupBox2);
+ panelGuide.Controls.Add(groupBox1);
+ panelGuide.Controls.Add(ctrlTitleBar);
+ panelGuide.Dock = DockStyle.Fill;
+ panelGuide.Location = new Point(0, 0);
+ panelGuide.Name = "panelGuide";
+ panelGuide.Size = new Size(200, 640);
+ panelGuide.TabIndex = 0;
+ //
+ // lblDistance
+ //
+ lblDistance.AutoSize = true;
+ lblDistance.Location = new Point(54, 505);
+ lblDistance.Name = "lblDistance";
+ lblDistance.Size = new Size(15, 17);
+ lblDistance.TabIndex = 29;
+ lblDistance.Text = "0";
+ //
+ // label17
+ //
+ label17.AutoSize = true;
+ label17.Location = new Point(6, 505);
+ label17.Name = "label17";
+ label17.Size = new Size(44, 17);
+ label17.TabIndex = 28;
+ label17.Text = "距离:";
+ //
+ // lblResult
+ //
+ lblResult.AutoSize = true;
+ lblResult.Location = new Point(54, 479);
+ lblResult.Name = "lblResult";
+ lblResult.Size = new Size(20, 17);
+ lblResult.TabIndex = 27;
+ lblResult.Text = "无";
+ //
+ // label15
+ //
+ label15.AutoSize = true;
+ label15.Location = new Point(6, 479);
+ label15.Name = "label15";
+ label15.Size = new Size(44, 17);
+ label15.TabIndex = 26;
+ label15.Text = "结果:";
+ //
+ // btnCreateLine
+ //
+ btnCreateLine.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnCreateLine.Location = new Point(6, 406);
+ btnCreateLine.Name = "btnCreateLine";
+ btnCreateLine.Size = new Size(186, 32);
+ btnCreateLine.TabIndex = 20;
+ btnCreateLine.Text = "创建直线";
+ btnCreateLine.UseVisualStyleBackColor = true;
+ btnCreateLine.Click += btnCreateLine_Click;
+ //
+ // btnCreateCircle
+ //
+ btnCreateCircle.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnCreateCircle.Location = new Point(6, 368);
+ btnCreateCircle.Name = "btnCreateCircle";
+ btnCreateCircle.Size = new Size(186, 32);
+ btnCreateCircle.TabIndex = 19;
+ btnCreateCircle.Text = "创建圆形";
+ btnCreateCircle.UseVisualStyleBackColor = true;
+ btnCreateCircle.Click += btnCreateCircle_Click;
+ //
+ // btnLoadImage
+ //
+ btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnLoadImage.Location = new Point(6, 330);
+ btnLoadImage.Name = "btnLoadImage";
+ btnLoadImage.Size = new Size(186, 32);
+ btnLoadImage.TabIndex = 18;
+ btnLoadImage.Text = "打开图片";
+ btnLoadImage.UseVisualStyleBackColor = true;
+ btnLoadImage.Click += btnLoadImage_Click;
+ //
+ // label9
+ //
+ label9.AutoSize = true;
+ label9.Location = new Point(56, 525);
+ label9.Name = "label9";
+ label9.Size = new Size(32, 17);
+ label9.TabIndex = 17;
+ label9.Text = "0ms";
+ //
+ // btnExecute
+ //
+ btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnExecute.Location = new Point(6, 444);
+ btnExecute.Name = "btnExecute";
+ btnExecute.Size = new Size(186, 32);
+ btnExecute.TabIndex = 15;
+ btnExecute.Text = "执行";
+ btnExecute.UseVisualStyleBackColor = true;
+ btnExecute.Click += btnExecute_Click;
+ //
+ // label10
+ //
+ label10.AutoSize = true;
+ label10.Location = new Point(6, 525);
+ label10.Name = "label10";
+ label10.Size = new Size(44, 17);
+ label10.TabIndex = 16;
+ label10.Text = "耗时:";
+ //
+ // groupBox2
+ //
+ groupBox2.Controls.Add(NumRectWidth1);
+ groupBox2.Controls.Add(label11);
+ groupBox2.Controls.Add(tbLineX2);
+ groupBox2.Controls.Add(label8);
+ groupBox2.Controls.Add(tbLineY2);
+ groupBox2.Controls.Add(label5);
+ groupBox2.Controls.Add(tbLineX1);
+ groupBox2.Controls.Add(tbLineY1);
+ groupBox2.Controls.Add(label6);
+ groupBox2.Controls.Add(label7);
+ groupBox2.Dock = DockStyle.Top;
+ groupBox2.Location = new Point(0, 152);
+ groupBox2.Name = "groupBox2";
+ groupBox2.Size = new Size(198, 172);
+ groupBox2.TabIndex = 13;
+ groupBox2.TabStop = false;
+ groupBox2.Text = "线参数";
+ //
+ // NumRectWidth1
+ //
+ NumRectWidth1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ NumRectWidth1.Location = new Point(56, 138);
+ NumRectWidth1.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
+ NumRectWidth1.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
+ NumRectWidth1.Name = "NumRectWidth1";
+ NumRectWidth1.Size = new Size(136, 23);
+ NumRectWidth1.TabIndex = 13;
+ NumRectWidth1.Value = new decimal(new int[] { 1, 0, 0, 0 });
+ //
+ // label11
+ //
+ label11.AutoSize = true;
+ label11.Location = new Point(6, 140);
+ label11.Name = "label11";
+ label11.Size = new Size(35, 17);
+ label11.TabIndex = 12;
+ label11.Text = "宽度:";
+ //
+ // tbLineX2
+ //
+ tbLineX2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineX2.Location = new Point(56, 80);
+ tbLineX2.Name = "tbLineX2";
+ tbLineX2.Size = new Size(136, 23);
+ tbLineX2.TabIndex = 9;
+ //
+ // label8
+ //
+ label8.AutoSize = true;
+ label8.Location = new Point(6, 83);
+ label8.Name = "label8";
+ label8.Size = new Size(26, 17);
+ label8.TabIndex = 8;
+ label8.Text = "X2:";
+ //
+ // tbLineY2
+ //
+ tbLineY2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineY2.Location = new Point(56, 109);
+ tbLineY2.Name = "tbLineY2";
+ tbLineY2.Size = new Size(136, 23);
+ tbLineY2.TabIndex = 7;
+ //
+ // label5
+ //
+ label5.AutoSize = true;
+ label5.Location = new Point(6, 112);
+ label5.Name = "label5";
+ label5.Size = new Size(25, 17);
+ label5.TabIndex = 6;
+ label5.Text = "Y2:";
+ //
+ // tbLineX1
+ //
+ tbLineX1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineX1.Location = new Point(56, 22);
+ tbLineX1.Name = "tbLineX1";
+ tbLineX1.Size = new Size(136, 23);
+ tbLineX1.TabIndex = 5;
+ //
+ // tbLineY1
+ //
+ tbLineY1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineY1.Location = new Point(56, 51);
+ tbLineY1.Name = "tbLineY1";
+ tbLineY1.Size = new Size(136, 23);
+ tbLineY1.TabIndex = 4;
+ //
+ // label6
+ //
+ label6.AutoSize = true;
+ label6.Location = new Point(6, 54);
+ label6.Name = "label6";
+ label6.Size = new Size(25, 17);
+ label6.TabIndex = 1;
+ label6.Text = "Y1:";
+ //
+ // label7
+ //
+ label7.AutoSize = true;
+ label7.Location = new Point(6, 25);
+ label7.Name = "label7";
+ label7.Size = new Size(26, 17);
+ label7.TabIndex = 0;
+ label7.Text = "X1:";
+ //
+ // groupBox1
+ //
+ groupBox1.Controls.Add(tbCircleX);
+ groupBox1.Controls.Add(tbCircleY);
+ groupBox1.Controls.Add(tbCircleR);
+ groupBox1.Controls.Add(label3);
+ groupBox1.Controls.Add(label2);
+ groupBox1.Controls.Add(label1);
+ groupBox1.Dock = DockStyle.Top;
+ groupBox1.Location = new Point(0, 36);
+ groupBox1.Name = "groupBox1";
+ groupBox1.Size = new Size(198, 116);
+ groupBox1.TabIndex = 12;
+ groupBox1.TabStop = false;
+ groupBox1.Text = "圆参数";
+ //
+ // tbCircleX
+ //
+ tbCircleX.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbCircleX.Location = new Point(56, 22);
+ tbCircleX.Name = "tbCircleX";
+ tbCircleX.Size = new Size(136, 23);
+ tbCircleX.TabIndex = 5;
+ //
+ // tbCircleY
+ //
+ tbCircleY.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbCircleY.Location = new Point(56, 51);
+ tbCircleY.Name = "tbCircleY";
+ tbCircleY.Size = new Size(136, 23);
+ tbCircleY.TabIndex = 4;
+ //
+ // tbCircleR
+ //
+ tbCircleR.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbCircleR.Location = new Point(56, 80);
+ tbCircleR.Name = "tbCircleR";
+ tbCircleR.Size = new Size(136, 23);
+ tbCircleR.TabIndex = 3;
+ //
+ // label3
+ //
+ label3.AutoSize = true;
+ label3.Location = new Point(3, 83);
+ label3.Name = "label3";
+ label3.Size = new Size(44, 17);
+ label3.TabIndex = 2;
+ label3.Text = "半径:";
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ label2.Location = new Point(6, 54);
+ label2.Name = "label2";
+ label2.Size = new Size(18, 17);
+ label2.TabIndex = 1;
+ label2.Text = "Y:";
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new Point(6, 25);
+ label1.Name = "label1";
+ label1.Size = new Size(19, 17);
+ label1.TabIndex = 0;
+ label1.Text = "X:";
+ //
+ // ctrlTitleBar
+ //
+ ctrlTitleBar.Dock = DockStyle.Top;
+ ctrlTitleBar.Location = new Point(0, 0);
+ ctrlTitleBar.MinimumSize = new Size(0, 36);
+ ctrlTitleBar.Name = "ctrlTitleBar";
+ ctrlTitleBar.Padding = new Padding(3);
+ ctrlTitleBar.Size = new Size(198, 36);
+ ctrlTitleBar.TabIndex = 11;
+ ctrlTitleBar.Title = "线圆测量";
+ //
+ // panel1
+ //
+ panel1.BorderStyle = BorderStyle.FixedSingle;
+ panel1.Controls.Add(canvas);
+ panel1.Controls.Add(statusStrip1);
+ panel1.Dock = DockStyle.Fill;
+ panel1.Location = new Point(0, 0);
+ panel1.Name = "panel1";
+ panel1.Size = new Size(1076, 640);
+ panel1.TabIndex = 1;
+ //
+ // canvas
+ //
+ canvas.AllowMultiSelect = false;
+ canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
+ canvas.Dock = DockStyle.Fill;
+ canvas.Enabled = false;
+ canvas.FillDrawing = false;
+ canvas.Location = new Point(0, 0);
+ canvas.Margin = new Padding(2);
+ canvas.Name = "canvas";
+ canvas.OutsideShapes = (List)resources.GetObject("canvas.OutsideShapes");
+ canvas.Scale = 1F;
+ canvas.Shapes = (List)resources.GetObject("canvas.Shapes");
+ canvas.Size = new Size(1074, 616);
+ canvas.TabIndex = 2;
+ //
+ // statusStrip1
+ //
+ statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
+ statusStrip1.Location = new Point(0, 616);
+ statusStrip1.Name = "statusStrip1";
+ statusStrip1.Size = new Size(1074, 22);
+ statusStrip1.TabIndex = 1;
+ statusStrip1.Text = "statusStrip1";
+ //
+ // lblStatus
+ //
+ lblStatus.Name = "lblStatus";
+ lblStatus.Size = new Size(44, 17);
+ lblStatus.Text = " ";
+ //
+ // btnSave
+ //
+ btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnSave.Location = new Point(6, 545);
+ btnSave.Name = "btnSave";
+ btnSave.Size = new Size(186, 32);
+ btnSave.TabIndex = 30;
+ btnSave.Text = "保存数据";
+ btnSave.UseVisualStyleBackColor = true;
+ btnSave.Click += btnSave_Click;
+ //
+ // GuideLineCircleCtrl
+ //
+ AutoScaleDimensions = new SizeF(7F, 17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ Controls.Add(splitContainer);
+ Controls.Add(lblElapsed);
+ Controls.Add(label4);
+ Name = "GuideLineCircleCtrl";
+ Size = new Size(1280, 640);
+ Load += GuideLineCircleCtrl_Load;
+ splitContainer.Panel1.ResumeLayout(false);
+ splitContainer.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
+ splitContainer.ResumeLayout(false);
+ panelGuide.ResumeLayout(false);
+ panelGuide.PerformLayout();
+ groupBox2.ResumeLayout(false);
+ groupBox2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth1).EndInit();
+ groupBox1.ResumeLayout(false);
+ groupBox1.PerformLayout();
+ panel1.ResumeLayout(false);
+ panel1.PerformLayout();
+ statusStrip1.ResumeLayout(false);
+ statusStrip1.PerformLayout();
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private Label lblElapsed;
+ private Label label4;
+
+ private SplitContainer splitContainer;
+ private Panel panelGuide;
+ private Panel panel1;
+ private Canvas.UI.FlyCanvas canvas;
+ private StatusStrip statusStrip1;
+ private ToolStripStatusLabel lblStatus;
+ private GroupBox groupBox2;
+ private TextBox tbLineX2;
+ private Label label8;
+ private TextBox tbLineY2;
+ private Label label5;
+ private TextBox tbLineX1;
+ private TextBox tbLineY1;
+ private Label label6;
+ private Label label7;
+ private GroupBox groupBox1;
+ private TextBox tbCircleX;
+ private TextBox tbCircleY;
+ private TextBox tbCircleR;
+ private Label label3;
+ private Label label2;
+ private Label label1;
+ private SizeCtrlTitleBar ctrlTitleBar;
+ private Button btnCreateCircle;
+ private Button btnLoadImage;
+ private Label label9;
+ private Button btnExecute;
+ private Label label10;
+ private Button btnCreateLine;
+ private TextBox tbRectWidth1;
+ private Label label11;
+ private NumericUpDown NumRectWidth1;
+ private Label lblDistance;
+ private Label label17;
+ private Label lblResult;
+ private Label label15;
+ private Button btnSave;
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.cs b/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.cs
new file mode 100644
index 0000000..8a0d23c
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.cs
@@ -0,0 +1,449 @@
+using CanFly.Canvas.Helper;
+using CanFly.Canvas.Shape;
+using CanFly.Canvas.UI;
+using CanFly.Helper;
+using HalconDotNet;
+using OpenCvSharp;
+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 CanFly.UI.SizePanel
+{
+ public partial class SizeGuideLineCircleCtrl : SizeBaseGuideControl
+ {
+
+
+ private FlyShape? _circle;
+ private FlyShape? _line;
+
+
+ private float _lineX1;
+ private float _lineY1;
+ private float _lineX2;
+ private float _lineY2;
+ private float _lineWidth;
+
+
+ private float _circleX;
+ private float _circleY;
+ private float _circleR;
+
+
+
+
+ protected override string GetScriptFileName() => "LineToCircle.hdvp";
+
+
+
+ public SizeGuideLineCircleCtrl()
+ {
+ InitializeComponent();
+
+ this.canvas.mouseMoved += Canvas_mouseMoved;
+ this.canvas.OnShapeUpdateEvent += UpdateShape;
+ this.canvas.selectionChanged += Canvas_selectionChanged;
+
+ this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
+ this.canvas.newShape += Canvas_newShape;
+
+ this.ctrlTitleBar.OnCloseClicked += OnControlClose;
+
+ NumRectWidth1.ValueChanged -= NumRectWidth1_ValueChanged;
+ NumRectWidth1.Value = 40;
+ NumRectWidth1.ValueChanged += NumRectWidth1_ValueChanged;
+
+ }
+
+
+
+ protected override void UpdateShape(FlyShape shape)
+ {
+ switch (shape.ShapeType)
+ {
+ case ShapeTypeEnum.Line:
+ this._line = shape;
+ _line.IsDrawLineVirtualRect = true;
+ var pts = this._line.Points;
+
+ _lineX1 = pts[0].X;
+ _lineY1 = pts[0].Y;
+ _lineX2 = pts[1].X;
+ _lineY2 = pts[1].Y;
+ _lineWidth = shape.LineVirtualRectWidth;
+
+ tbLineX1.Text = _lineX1.ToString("F3");
+ tbLineY1.Text = _lineY1.ToString("F3");
+ tbLineX2.Text = _lineX2.ToString("F3");
+ tbLineY2.Text = _lineY2.ToString("F3");
+ // NumRectWidth1.Value = (decimal)_lineWidth;
+ break;
+ case ShapeTypeEnum.Circle:
+ this._circle = shape;
+
+ _circleX = shape.Points[0].X;
+ _circleY = shape.Points[0].Y;
+ _circleR = PointHelper.Distance(shape.Points[0], shape.Points[1]);
+
+ this.tbCircleX.Text = _circleX.ToString("F3");
+ this.tbCircleY.Text = _circleY.ToString("F3");
+ this.tbCircleR.Text = _circleR.ToString("F3");
+
+ break;
+ default:
+ break;
+ }
+ }
+
+
+
+
+
+ private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
+ {
+
+
+
+ }
+
+
+
+
+ private void Canvas_mouseMoved(PointF pos)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(Canvas_mouseMoved, pos);
+ return;
+ }
+
+ lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
+
+ }
+
+
+
+
+ private void Canvas_selectionChanged(List shapes)
+ {
+ //if (shapes.Count != 1)
+ //{
+ // // panelGuide.Controls.Clear();
+ // return;
+ //}
+ //SwitchGuideForm(shapes[0].ShapeType);
+ // Canvas_OnShapeUpdateEvent(shapes[0]);
+
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+ UpdateShape(shapes[0]);
+
+ }
+
+
+
+ private void Canvas_OnShapeMoving(List shapes)
+ {
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+
+ UpdateShape(shapes[0]);
+ }
+
+
+
+ private void btnCreateCircle_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ this.tbCircleX.Text = string.Empty;
+ this.tbCircleY.Text = string.Empty;
+ this.tbCircleR.Text = string.Empty;
+ this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Circle);
+
+ this.canvas.Invalidate();
+ this.canvas.StartDraw(ShapeTypeEnum.Circle);
+ }
+
+
+
+ private void btnCreateLine_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ tbLineX1.Text = string.Empty;
+ tbLineY1.Text = string.Empty;
+ tbLineX2.Text = string.Empty;
+ tbLineY2.Text = string.Empty;
+
+ this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Line);
+ this.canvas.Invalidate();
+ this.canvas.StartDraw(ShapeTypeEnum.Line);
+
+ }
+
+
+
+ private void btnLoadImage_Click(object sender, EventArgs e)
+ {
+ OpenImageFile(bitmap =>
+ {
+ this.canvas.LoadPixmap(bitmap);
+ this.canvas.Enabled = true;
+
+
+ });
+ }
+
+
+ private void Canvas_newShape()
+ {
+ this.canvas.StopDraw();
+ }
+
+
+
+ string strarrayX=string.Empty;
+ string strarrayY=string.Empty;
+ private void btnExecute_Click(object sender, EventArgs e)
+ {
+
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ if (this.tbLineX1.Text.Trim().Length == 0)
+ {
+ MessageBox.Show("请先创建直线");
+ return;
+ }
+ if (this.tbLineX1.Text.Trim().Length == 0)
+ {
+ MessageBox.Show("请先创建圆形");
+ return;
+ }
+
+ this.canvas.OutsideShapes.Clear();
+ this.canvas.Invalidate();
+
+ flag = new List();
+ Distance = new List();
+ fRowCenter = new List();
+ fColCenter = new List();
+ fRadius = new List();
+ RowBegin = new List();
+ ColBegin = new List();
+ RowEnd = new List();
+ ColEnd = new List();
+ Dictionary inputImg = new Dictionary();
+
+ if (hImage == null)
+ {
+ HOperatorSet.ReadImage(out hImage, CurrentImageFile);
+ }
+ inputImg["INPUT_Image"] = hImage;
+
+ Dictionary inputPara = new Dictionary();
+
+ PointF[] Points = this._line.LineVirtualRectPoints;
+ PointF Point1 = Points[0];
+ PointF Point2 = Points[1];
+ PointF Point3 = Points[2];
+ PointF Point4 = Points[3];
+ PointF Point5 = Points[0];
+
+ float x1 = Point1.X;
+ float y1 = Point1.Y;
+
+ float x2 = Point2.X;
+ float y2 = Point2.Y;
+
+ float x3 = Point3.X;
+ float y3 = Point3.Y;
+
+ float x4 = Point4.X;
+ float y4 = Point4.Y;
+
+ float x5 = Point5.X;
+ float y5 = Point5.Y;
+
+
+ float[] arrayX = new float[] { x1, x2, x3, x4, x5 };
+ HTuple hTupleArrayX = new HTuple(arrayX);
+
+ float[] arrayY = new float[] { y1, y2, y3, y4, y5 };
+ HTuple hTupleArrayY = new HTuple(arrayY);
+
+ strarrayX=string.Join(",", arrayX);
+ strarrayY=string.Join(",", arrayY);
+
+ inputPara["LX"] = _lineX1;
+ inputPara["LY"] = _lineY1;
+ inputPara["RX"] = _lineX2;
+ inputPara["RY"] = _lineY2;
+ inputPara["XCenter"] = _circleX;
+ inputPara["YCenter"] = _circleY;
+ inputPara["Radius"] = _circleR;
+ inputPara["Line_XRect"] = hTupleArrayX;
+ inputPara["Line_YRect"] = hTupleArrayY;
+
+
+
+ List outputKeys = new List()
+ {
+ "OUTPUT_Flag",
+ "distance",
+ "fRowCenter",
+ "fColCenter",
+ "fRadius",
+ "RowBegin",
+ "ColBegin",
+ "RowEnd",
+ "ColEnd"
+ };
+
+ ExecuteHScript(
+ inputImg,
+ inputPara,
+ outputKeys);
+
+ }
+ List flag = new List();
+ List Distance = new List();
+ List fRowCenter = new List();
+ List fColCenter = new List();
+ List fRadius = new List();
+ List RowBegin = new List();
+ List ColBegin = new List();
+ List RowEnd = new List();
+ List ColEnd = new List();
+ protected override void OnExecuteHScriptResult(
+ bool success,
+ Dictionary resultDic,
+ int timeElasped)
+ {
+ if (!success)
+ {
+ return;
+ }
+
+ //"OUTPUT_Flag",
+ // "distance",
+ // "fRowCenter",
+ // "fColCenter",
+ // "fRadius",
+ // "RowBegin",
+ // "ColBegin",
+ // "RowEnd",
+ // "ColEnd"
+
+ flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
+ Distance = resultDic["distance"].HTupleToDouble();
+ fRowCenter = resultDic["fRowCenter"].HTupleToDouble();
+ fColCenter = resultDic["fColCenter"].HTupleToDouble();
+ fRadius = resultDic["fRadius"].HTupleToDouble();
+ RowBegin = resultDic["RowBegin"].HTupleToDouble();
+ ColBegin = resultDic["ColBegin"].HTupleToDouble();
+ RowEnd = resultDic["RowEnd"].HTupleToDouble();
+ ColEnd = resultDic["ColEnd"].HTupleToDouble();
+
+
+ if (flag.Count > 0)
+ {
+ lblResult.Text = flag[0].ToString();
+
+ }
+ else
+ {
+ lblResult.Text = "无";
+ }
+ if (Distance.Count > 0)
+ {
+ lblDistance.Text = Distance[0].ToString();
+ }
+ else
+ {
+ lblDistance.Text = "0";
+ }
+
+ if (flag.Count > 0 && Distance.Count > 0 && fRowCenter.Count > 0 && fColCenter.Count > 0 && fRadius.Count > 0 && RowBegin.Count > 0 && ColBegin.Count > 0 && RowEnd.Count > 0 && ColEnd.Count > 0)
+ {
+ float width = 0;
+ this.canvas.DrawLine(new PointF((float)ColBegin[0], (float)RowBegin[0]), new PointF((float)ColEnd[0], (float)RowEnd[0]), width);
+ this.canvas.DrawCircle(new PointF((float)fColCenter[0], (float)fRowCenter[0]), (float)fRadius[0]);
+
+ this.canvas.Invalidate();
+ lblElapsed.Text = $"{timeElasped} ms";
+ }
+ }
+
+
+
+
+
+
+ private void NumRectWidth1_ValueChanged(object sender, EventArgs e)
+ {
+ if (_line != null)
+ {
+ //_line1.IsDrawLineVirtualRect = true;
+ _line.LineVirtualRectWidth = (float)NumRectWidth1.Value;
+ UpdateShape(_line);
+ this.canvas.Invalidate();
+ }
+ }
+
+ private void btnSave_Click(object sender, EventArgs e)
+ {
+ if (lblResult.Text.Equals("无"))
+ {
+ MessageBox.Show("请先进行绘制");
+ return;
+ }
+ if (lblResult.Text != "0")
+ {
+ MessageBox.Show("测量计算错误,无法保存");
+ return;
+ }
+
+
+
+
+
+ string input = $"LX:{_lineX1};" +
+ $"LY:{_lineY1};" +
+ $"RX:{_lineX2};" +
+ $"RY:{_lineY2};" +
+ $"XCenter:{_circleX};" +
+ $"YCenter:{_circleY};" +
+ $"Radius:{_circleR};" +
+ $"Line_XRect:{strarrayX};"+
+ $"Line_YRect:{strarrayY}";
+
+
+
+
+ string result = $"distance:{Distance[0]};";
+ DataToTriggerEvent(input, result);
+
+ }
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.resx b/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.resx
new file mode 100644
index 0000000..097e294
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineCircleCtrl.resx
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/CanFly/UI/SizePanel/SizeGuideLineCtrl.Designer.cs b/CanFly/UI/SizePanel/SizeGuideLineCtrl.Designer.cs
new file mode 100644
index 0000000..fb816ee
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineCtrl.Designer.cs
@@ -0,0 +1,427 @@
+namespace CanFly.UI.SizePanel
+{
+ partial class SizeGuideLineCtrl
+ {
+ ///
+ /// 必需的设计器变量。
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// 清理所有正在使用的资源。
+ ///
+ /// 如果应释放托管资源,为 true;否则为 false。
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 组件设计器生成的代码
+
+ ///
+ /// 设计器支持所需的方法 - 不要修改
+ /// 使用代码编辑器修改此方法的内容。
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SizeGuideLineCtrl));
+ lblElapsed = new Label();
+ label4 = new Label();
+ splitContainer = new SplitContainer();
+ panelGuide = new Panel();
+ btnSave = new Button();
+ lblResult = new Label();
+ label1 = new Label();
+ btnCreateLine = new Button();
+ btnLoadImage = new Button();
+ label9 = new Label();
+ btnExecute = new Button();
+ label10 = new Label();
+ groupBox2 = new GroupBox();
+ NumRectWidth1 = new NumericUpDown();
+ label11 = new Label();
+ tbLineX2 = new TextBox();
+ label8 = new Label();
+ tbLineY2 = new TextBox();
+ label5 = new Label();
+ tbLineX1 = new TextBox();
+ tbLineY1 = new TextBox();
+ label6 = new Label();
+ label7 = new Label();
+ ctrlTitleBar = new SizeCtrlTitleBar();
+ panel1 = new Panel();
+ canvas = new Canvas.UI.FlyCanvas();
+ statusStrip1 = new StatusStrip();
+ lblStatus = new ToolStripStatusLabel();
+ ((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
+ splitContainer.Panel1.SuspendLayout();
+ splitContainer.Panel2.SuspendLayout();
+ splitContainer.SuspendLayout();
+ panelGuide.SuspendLayout();
+ groupBox2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth1).BeginInit();
+ panel1.SuspendLayout();
+ statusStrip1.SuspendLayout();
+ SuspendLayout();
+ //
+ // lblElapsed
+ //
+ lblElapsed.AutoSize = true;
+ lblElapsed.Location = new Point(50, 328);
+ lblElapsed.Name = "lblElapsed";
+ lblElapsed.Size = new Size(32, 17);
+ lblElapsed.TabIndex = 9;
+ lblElapsed.Text = "0ms";
+ //
+ // label4
+ //
+ label4.AutoSize = true;
+ label4.Location = new Point(0, 328);
+ label4.Name = "label4";
+ label4.Size = new Size(44, 17);
+ label4.TabIndex = 8;
+ label4.Text = "耗时:";
+ //
+ // splitContainer
+ //
+ splitContainer.Dock = DockStyle.Fill;
+ splitContainer.Location = new Point(0, 0);
+ splitContainer.Name = "splitContainer";
+ //
+ // splitContainer.Panel1
+ //
+ splitContainer.Panel1.Controls.Add(panelGuide);
+ splitContainer.Panel1MinSize = 150;
+ //
+ // splitContainer.Panel2
+ //
+ splitContainer.Panel2.Controls.Add(panel1);
+ splitContainer.Size = new Size(1280, 640);
+ splitContainer.SplitterDistance = 200;
+ splitContainer.TabIndex = 11;
+ //
+ // panelGuide
+ //
+ panelGuide.BorderStyle = BorderStyle.FixedSingle;
+ panelGuide.Controls.Add(btnSave);
+ panelGuide.Controls.Add(lblResult);
+ panelGuide.Controls.Add(label1);
+ panelGuide.Controls.Add(btnCreateLine);
+ panelGuide.Controls.Add(btnLoadImage);
+ panelGuide.Controls.Add(label9);
+ panelGuide.Controls.Add(btnExecute);
+ panelGuide.Controls.Add(label10);
+ panelGuide.Controls.Add(groupBox2);
+ panelGuide.Controls.Add(ctrlTitleBar);
+ panelGuide.Dock = DockStyle.Fill;
+ panelGuide.Location = new Point(0, 0);
+ panelGuide.Name = "panelGuide";
+ panelGuide.Size = new Size(200, 640);
+ panelGuide.TabIndex = 0;
+ //
+ // btnSave
+ //
+ btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnSave.Location = new Point(6, 390);
+ btnSave.Name = "btnSave";
+ btnSave.Size = new Size(186, 32);
+ btnSave.TabIndex = 23;
+ btnSave.Text = "保存数据";
+ btnSave.UseVisualStyleBackColor = true;
+ btnSave.Click += btnSave_Click;
+ //
+ // lblResult
+ //
+ lblResult.AutoSize = true;
+ lblResult.Location = new Point(59, 354);
+ lblResult.Name = "lblResult";
+ lblResult.Size = new Size(20, 17);
+ lblResult.TabIndex = 22;
+ lblResult.Text = "无";
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new Point(9, 354);
+ label1.Name = "label1";
+ label1.Size = new Size(44, 17);
+ label1.TabIndex = 21;
+ label1.Text = "结果:";
+ //
+ // btnCreateLine
+ //
+ btnCreateLine.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnCreateLine.Location = new Point(9, 252);
+ btnCreateLine.Name = "btnCreateLine";
+ btnCreateLine.Size = new Size(186, 32);
+ btnCreateLine.TabIndex = 20;
+ btnCreateLine.Text = "创建直线";
+ btnCreateLine.UseVisualStyleBackColor = true;
+ btnCreateLine.Click += btnCreateLine_Click;
+ //
+ // btnLoadImage
+ //
+ btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnLoadImage.Location = new Point(6, 214);
+ btnLoadImage.Name = "btnLoadImage";
+ btnLoadImage.Size = new Size(186, 32);
+ btnLoadImage.TabIndex = 18;
+ btnLoadImage.Text = "打开图片";
+ btnLoadImage.UseVisualStyleBackColor = true;
+ btnLoadImage.Click += btnLoadImage_Click;
+ //
+ // label9
+ //
+ label9.AutoSize = true;
+ label9.Location = new Point(59, 325);
+ label9.Name = "label9";
+ label9.Size = new Size(32, 17);
+ label9.TabIndex = 17;
+ label9.Text = "0ms";
+ //
+ // btnExecute
+ //
+ btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnExecute.Location = new Point(9, 290);
+ btnExecute.Name = "btnExecute";
+ btnExecute.Size = new Size(186, 32);
+ btnExecute.TabIndex = 15;
+ btnExecute.Text = "执行";
+ btnExecute.UseVisualStyleBackColor = true;
+ btnExecute.Click += btnExecute_Click;
+ //
+ // label10
+ //
+ label10.AutoSize = true;
+ label10.Location = new Point(9, 325);
+ label10.Name = "label10";
+ label10.Size = new Size(44, 17);
+ label10.TabIndex = 16;
+ label10.Text = "耗时:";
+ //
+ // groupBox2
+ //
+ groupBox2.Controls.Add(NumRectWidth1);
+ groupBox2.Controls.Add(label11);
+ groupBox2.Controls.Add(tbLineX2);
+ groupBox2.Controls.Add(label8);
+ groupBox2.Controls.Add(tbLineY2);
+ groupBox2.Controls.Add(label5);
+ groupBox2.Controls.Add(tbLineX1);
+ groupBox2.Controls.Add(tbLineY1);
+ groupBox2.Controls.Add(label6);
+ groupBox2.Controls.Add(label7);
+ groupBox2.Dock = DockStyle.Top;
+ groupBox2.Location = new Point(0, 36);
+ groupBox2.Name = "groupBox2";
+ groupBox2.Size = new Size(198, 172);
+ groupBox2.TabIndex = 13;
+ groupBox2.TabStop = false;
+ groupBox2.Text = "线参数";
+ //
+ // NumRectWidth1
+ //
+ NumRectWidth1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ NumRectWidth1.Location = new Point(56, 138);
+ NumRectWidth1.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
+ NumRectWidth1.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
+ NumRectWidth1.Name = "NumRectWidth1";
+ NumRectWidth1.Size = new Size(136, 23);
+ NumRectWidth1.TabIndex = 13;
+ NumRectWidth1.Value = new decimal(new int[] { 1, 0, 0, 0 });
+ //
+ // label11
+ //
+ label11.AutoSize = true;
+ label11.Location = new Point(6, 140);
+ label11.Name = "label11";
+ label11.Size = new Size(35, 17);
+ label11.TabIndex = 12;
+ label11.Text = "宽度:";
+ //
+ // tbLineX2
+ //
+ tbLineX2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineX2.Location = new Point(56, 80);
+ tbLineX2.Name = "tbLineX2";
+ tbLineX2.Size = new Size(136, 23);
+ tbLineX2.TabIndex = 9;
+ //
+ // label8
+ //
+ label8.AutoSize = true;
+ label8.Location = new Point(6, 83);
+ label8.Name = "label8";
+ label8.Size = new Size(26, 17);
+ label8.TabIndex = 8;
+ label8.Text = "X2:";
+ //
+ // tbLineY2
+ //
+ tbLineY2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineY2.Location = new Point(56, 109);
+ tbLineY2.Name = "tbLineY2";
+ tbLineY2.Size = new Size(136, 23);
+ tbLineY2.TabIndex = 7;
+ //
+ // label5
+ //
+ label5.AutoSize = true;
+ label5.Location = new Point(6, 112);
+ label5.Name = "label5";
+ label5.Size = new Size(25, 17);
+ label5.TabIndex = 6;
+ label5.Text = "Y2:";
+ //
+ // tbLineX1
+ //
+ tbLineX1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineX1.Location = new Point(56, 22);
+ tbLineX1.Name = "tbLineX1";
+ tbLineX1.Size = new Size(136, 23);
+ tbLineX1.TabIndex = 5;
+ //
+ // tbLineY1
+ //
+ tbLineY1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLineY1.Location = new Point(56, 51);
+ tbLineY1.Name = "tbLineY1";
+ tbLineY1.Size = new Size(136, 23);
+ tbLineY1.TabIndex = 4;
+ //
+ // label6
+ //
+ label6.AutoSize = true;
+ label6.Location = new Point(6, 54);
+ label6.Name = "label6";
+ label6.Size = new Size(25, 17);
+ label6.TabIndex = 1;
+ label6.Text = "Y1:";
+ //
+ // label7
+ //
+ label7.AutoSize = true;
+ label7.Location = new Point(6, 25);
+ label7.Name = "label7";
+ label7.Size = new Size(26, 17);
+ label7.TabIndex = 0;
+ label7.Text = "X1:";
+ //
+ // ctrlTitleBar
+ //
+ ctrlTitleBar.Dock = DockStyle.Top;
+ ctrlTitleBar.Location = new Point(0, 0);
+ ctrlTitleBar.MinimumSize = new Size(0, 36);
+ ctrlTitleBar.Name = "ctrlTitleBar";
+ ctrlTitleBar.Padding = new Padding(3);
+ ctrlTitleBar.Size = new Size(198, 36);
+ ctrlTitleBar.TabIndex = 11;
+ ctrlTitleBar.Title = "直线测量";
+ //
+ // panel1
+ //
+ panel1.BorderStyle = BorderStyle.FixedSingle;
+ panel1.Controls.Add(canvas);
+ panel1.Controls.Add(statusStrip1);
+ panel1.Dock = DockStyle.Fill;
+ panel1.Location = new Point(0, 0);
+ panel1.Name = "panel1";
+ panel1.Size = new Size(1076, 640);
+ panel1.TabIndex = 1;
+ //
+ // canvas
+ //
+ canvas.AllowMultiSelect = false;
+ canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
+ canvas.Dock = DockStyle.Fill;
+ canvas.Enabled = false;
+ canvas.FillDrawing = false;
+ canvas.Location = new Point(0, 0);
+ canvas.Margin = new Padding(2);
+ canvas.Name = "canvas";
+ canvas.OutsideShapes = (List)resources.GetObject("canvas.OutsideShapes");
+ canvas.Scale = 1F;
+ canvas.Shapes = (List)resources.GetObject("canvas.Shapes");
+ canvas.Size = new Size(1074, 616);
+ canvas.TabIndex = 2;
+ //
+ // statusStrip1
+ //
+ statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
+ statusStrip1.Location = new Point(0, 616);
+ statusStrip1.Name = "statusStrip1";
+ statusStrip1.Size = new Size(1074, 22);
+ statusStrip1.TabIndex = 1;
+ statusStrip1.Text = "statusStrip1";
+ //
+ // lblStatus
+ //
+ lblStatus.Name = "lblStatus";
+ lblStatus.Size = new Size(44, 17);
+ lblStatus.Text = " ";
+ //
+ // GuideLineCtrl
+ //
+ AutoScaleDimensions = new SizeF(7F, 17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ Controls.Add(splitContainer);
+ Controls.Add(lblElapsed);
+ Controls.Add(label4);
+ Name = "GuideLineCtrl";
+ Size = new Size(1280, 640);
+ Load += GuideLineCircleCtrl_Load;
+ splitContainer.Panel1.ResumeLayout(false);
+ splitContainer.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
+ splitContainer.ResumeLayout(false);
+ panelGuide.ResumeLayout(false);
+ panelGuide.PerformLayout();
+ groupBox2.ResumeLayout(false);
+ groupBox2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth1).EndInit();
+ panel1.ResumeLayout(false);
+ panel1.PerformLayout();
+ statusStrip1.ResumeLayout(false);
+ statusStrip1.PerformLayout();
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private Label lblElapsed;
+ private Label label4;
+
+ private SplitContainer splitContainer;
+ private Panel panelGuide;
+ private Panel panel1;
+ private Canvas.UI.FlyCanvas canvas;
+ private StatusStrip statusStrip1;
+ private ToolStripStatusLabel lblStatus;
+ private GroupBox groupBox2;
+ private TextBox tbLineX2;
+ private Label label8;
+ private TextBox tbLineY2;
+ private Label label5;
+ private TextBox tbLineX1;
+ private TextBox tbLineY1;
+ private Label label6;
+ private Label label7;
+ private SizeCtrlTitleBar ctrlTitleBar;
+ private Button btnLoadImage;
+ private Label label9;
+ private Button btnExecute;
+ private Label label10;
+ private Button btnCreateLine;
+ private TextBox tbRectWidth1;
+ private Label label11;
+ private NumericUpDown NumRectWidth1;
+ private Label lblResult;
+ private Label label1;
+ private Button btnSave;
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideLineCtrl.cs b/CanFly/UI/SizePanel/SizeGuideLineCtrl.cs
new file mode 100644
index 0000000..c6307fe
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineCtrl.cs
@@ -0,0 +1,387 @@
+using CanFly.Canvas.Helper;
+using CanFly.Canvas.Shape;
+using CanFly.Canvas.UI;
+using CanFly.Helper;
+using HalconDotNet;
+using OpenCvSharp;
+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 CanFly.UI.SizePanel
+{
+ public partial class SizeGuideLineCtrl : SizeBaseGuideControl
+ {
+
+
+
+ private FlyShape? _line;
+
+
+ private float _lineX1;
+ private float _lineY1;
+ private float _lineX2;
+ private float _lineY2;
+ private float _lineWidth;
+ private PointF[] _rectPoints = new PointF[4];
+ //private float _LineLX=new float();
+ //private float _LineLY =new float();
+ //private float _LineRX =new float();
+ //private float _LineRY =new float();
+
+
+
+
+
+ protected override string GetScriptFileName() => "Line_detect.hdvp";
+
+
+
+ public SizeGuideLineCtrl()
+ {
+ InitializeComponent();
+
+ this.canvas.mouseMoved += Canvas_mouseMoved;
+ this.canvas.OnShapeUpdateEvent += UpdateShape;
+ this.canvas.selectionChanged += Canvas_selectionChanged;
+
+ this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
+ this.canvas.newShape += Canvas_newShape;
+
+ this.ctrlTitleBar.OnCloseClicked += OnControlClose;
+
+ NumRectWidth1.ValueChanged -= NumRectWidth1_ValueChanged;
+ NumRectWidth1.Value = 40;
+ NumRectWidth1.ValueChanged += NumRectWidth1_ValueChanged;
+
+ }
+
+
+
+ protected override void UpdateShape(FlyShape shape)
+ {
+ switch (shape.ShapeType)
+ {
+ case ShapeTypeEnum.Line:
+ this._line = shape;
+ _line.IsDrawLineVirtualRect = true;
+ var pts = this._line.Points;
+
+ _lineX1 = pts[0].X;
+ _lineY1 = pts[0].Y;
+ _lineX2 = pts[1].X;
+ _lineY2 = pts[1].Y;
+ _lineWidth = shape.LineVirtualRectWidth;
+ _rectPoints = shape.LineVirtualRectPoints;
+ //_LineLX = (shape.LineVirtualRectPoints[0].X + shape.LineVirtualRectPoints[3].X) / 2;
+ //_LineLY = (shape.LineVirtualRectPoints[0].Y + shape.LineVirtualRectPoints[3].Y) / 2;
+ //_LineRX = (shape.LineVirtualRectPoints[1].X + shape.LineVirtualRectPoints[2].X) / 2;
+ //_LineRY = (shape.LineVirtualRectPoints[1].Y + shape.LineVirtualRectPoints[2].Y) / 2;
+
+ tbLineX1.Text = _lineX1.ToString("F3");
+ tbLineY1.Text = _lineY1.ToString("F3");
+ tbLineX2.Text = _lineX2.ToString("F3");
+ tbLineY2.Text = _lineY2.ToString("F3");
+ // NumRectWidth1.Value = (decimal)_lineWidth;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+
+
+
+ private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
+ {
+
+
+
+ }
+
+
+
+
+ private void Canvas_mouseMoved(PointF pos)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(Canvas_mouseMoved, pos);
+ return;
+ }
+
+ lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
+
+ }
+
+
+
+
+ private void Canvas_selectionChanged(List shapes)
+ {
+ //if (shapes.Count != 1)
+ //{
+ // // panelGuide.Controls.Clear();
+ // return;
+ //}
+ //SwitchGuideForm(shapes[0].ShapeType);
+ // Canvas_OnShapeUpdateEvent(shapes[0]);
+
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+ UpdateShape(shapes[0]);
+
+ }
+
+
+
+ private void Canvas_OnShapeMoving(List shapes)
+ {
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+
+ UpdateShape(shapes[0]);
+ }
+
+
+
+
+
+
+
+ private void btnCreateLine_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+
+ tbLineX1.Text = string.Empty;
+ tbLineY1.Text = string.Empty;
+ tbLineX2.Text = string.Empty;
+ tbLineY2.Text = string.Empty;
+
+
+ this.canvas.Shapes.RemoveAll(shp => shp.ShapeType == ShapeTypeEnum.Line);
+ this.canvas.Invalidate();
+ this.canvas.StartDraw(ShapeTypeEnum.Line);
+
+ }
+
+
+
+ private void btnLoadImage_Click(object sender, EventArgs e)
+ {
+ OpenImageFile(bitmap =>
+ {
+ this.canvas.LoadPixmap(bitmap);
+ this.canvas.Enabled = true;
+
+
+ });
+ }
+
+
+ private void Canvas_newShape()
+ {
+ this.canvas.StopDraw();
+ }
+ string strarrayX = string.Empty;
+ string strarrayY = string.Empty;
+ private void btnExecute_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+ if (this.tbLineX1.Text.Trim().Length == 0)
+ {
+ MessageBox.Show("请先创建直线");
+ return;
+ }
+ this.canvas.OutsideShapes.Clear();
+ this.canvas.Invalidate();
+
+
+ flag = new List();
+ RowBegin = new List();
+ ColBegin = new List();
+ RowEnd = new List();
+ ColEnd = new List();
+ Dictionary inputImg = new Dictionary();
+
+ if (hImage == null)
+ {
+ HOperatorSet.ReadImage(out hImage, CurrentImageFile);
+ }
+ inputImg["INPUT_Image"] = hImage;
+ // 创建一维数组
+
+ Dictionary inputPara = new Dictionary();
+
+ // 获取矩形的 4 个点
+ PointF[] Points = this._line.LineVirtualRectPoints;
+ PointF Point1 = Points[0];
+ PointF Point2 = Points[1];
+ PointF Point3 = Points[2];
+ PointF Point4 = Points[3];
+ PointF Point5 = Points[0];
+
+ float x1 = Point1.X;
+ float y1 = Point1.Y;
+
+ float x2 = Point2.X;
+ float y2 = Point2.Y;
+
+ float x3 = Point3.X;
+ float y3 = Point3.Y;
+
+ float x4 = Point4.X;
+ float y4 = Point4.Y;
+
+ float x5 = Point5.X;
+ float y5 = Point5.Y;
+
+
+ float[] arrayX = new float[] { x1, x2, x3, x4, x5 };
+ HTuple hTupleArrayX = new HTuple(arrayX);
+
+ float[] arrayY = new float[] { y1, y2, y3, y4, y5 };
+ HTuple hTupleArrayY = new HTuple(arrayY);
+
+ strarrayX = string.Join(",", arrayX);
+ strarrayY = string.Join(",", arrayY);
+
+ inputPara["LX"] = _lineX1;
+ inputPara["LY"] = _lineY1;
+ inputPara["RX"] = _lineX2;
+ inputPara["RY"] = _lineY2;
+ inputPara["XRect"] = hTupleArrayX;
+ inputPara["YRect"] = hTupleArrayY;
+
+
+
+ List outputKeys = new List()
+ {
+ "OUTPUT_Flag",
+ "RowBegin",
+ "ColBegin",
+ "RowEnd",
+ "ColEnd"
+ };
+
+ ExecuteHScript(
+ inputImg,
+ inputPara,
+ outputKeys);
+
+ }
+
+
+ List flag = new List();
+ List RowBegin = new List();
+ List ColBegin = new List();
+ List RowEnd = new List();
+ List ColEnd = new List();
+
+
+ protected override void OnExecuteHScriptResult(
+ bool success,
+ Dictionary resultDic,
+ int timeElasped)
+ {
+ if (!success)
+ {
+ return;
+ }
+
+
+ /*
+ "OUTPUT_Flag",
+ "RXCenter",
+ "RYCenter",
+ "RRadius"
+ */
+
+ flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
+ RowBegin = resultDic["RowBegin"].HTupleToDouble();
+ ColBegin = resultDic["ColBegin"].HTupleToDouble();
+ RowEnd = resultDic["RowEnd"].HTupleToDouble();
+ ColEnd = resultDic["ColEnd"].HTupleToDouble();
+ if (flag.Count > 0)
+ {
+ lblResult.Text = flag[0].ToString();
+
+ }
+ else
+ {
+ lblResult.Text = "无";
+ }
+ if (flag.Count > 0 && RowBegin.Count > 0 && ColBegin.Count > 0 && RowEnd.Count > 0 && ColEnd.Count > 0)
+ {
+ float width = 0;
+ this.canvas.DrawLine(new PointF((float)ColBegin[0], (float)RowBegin[0]), new PointF((float)ColEnd[0], (float)RowEnd[0]), width);
+ this.canvas.Invalidate();
+ lblElapsed.Text = $"{timeElasped} ms";
+ }
+ }
+
+
+ private void NumRectWidth1_ValueChanged(object sender, EventArgs e)
+ {
+ if (_line != null)
+ {
+ //_line1.IsDrawLineVirtualRect = true;
+ _line.LineVirtualRectWidth = (float)NumRectWidth1.Value;
+ UpdateShape(_line);
+ this.canvas.Invalidate();
+ }
+ }
+
+ private void btnSave_Click(object sender, EventArgs e)
+ {
+ if (lblResult.Text.Equals("无"))
+ {
+ MessageBox.Show("请先进行绘制");
+ return;
+ }
+ if (lblResult.Text != "0")
+ {
+ MessageBox.Show("测量计算错误,无法保存");
+ return;
+ }
+ //flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
+ //RowBegin = resultDic["RowBegin"].HTupleToDouble();
+ //ColBegin = resultDic["ColBegin"].HTupleToDouble();
+ //RowEnd = resultDic["RowEnd"].HTupleToDouble();
+ //ColEnd = resultDic["ColEnd"].HTupleToDouble();
+
+
+ string input = $"LX:{_lineX1};" +
+ $"LY:{_lineY1};" +
+ $"RX:{_lineX2};" +
+ $"RY:{_lineY2};" +
+ $"Line_XRect:{strarrayX};" +
+ $"Line_YRect:{strarrayY}";
+
+
+ string result = $"RowBegin:{string.Join(";", RowBegin[0])};ColBegin:{string.Join(";", ColBegin[0])};RowEnd:{string.Join(";", RowEnd[0])};ColEnd:{string.Join(";", ColEnd[0])}";
+
+ DataToTriggerEvent(input, result);
+ }
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideLineCtrl.resx b/CanFly/UI/SizePanel/SizeGuideLineCtrl.resx
new file mode 100644
index 0000000..097e294
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineCtrl.resx
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.Designer.cs b/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.Designer.cs
new file mode 100644
index 0000000..474d379
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.Designer.cs
@@ -0,0 +1,570 @@
+namespace CanFly.UI.SizePanel
+{
+ partial class SizeGuideLineLineCtrl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SizeGuideLineLineCtrl));
+ lblStatus = new ToolStripStatusLabel();
+ panel1 = new Panel();
+ canvas = new Canvas.UI.FlyCanvas();
+ statusStrip1 = new StatusStrip();
+ ctrlTitleBar = new SizeCtrlTitleBar();
+ tbLine1X2 = new TextBox();
+ label8 = new Label();
+ tbLine1Y2 = new TextBox();
+ label5 = new Label();
+ label10 = new Label();
+ tbLine1X1 = new TextBox();
+ tbLine1Y1 = new TextBox();
+ label6 = new Label();
+ label7 = new Label();
+ btnLoadImage = new Button();
+ label9 = new Label();
+ btnExecute = new Button();
+ panelGuide = new Panel();
+ lblDistance = new Label();
+ label17 = new Label();
+ lblResult = new Label();
+ label15 = new Label();
+ groupBox3 = new GroupBox();
+ NumRectWidth2 = new NumericUpDown();
+ label2 = new Label();
+ tbLine2X2 = new TextBox();
+ label11 = new Label();
+ tbLine2Y2 = new TextBox();
+ label12 = new Label();
+ tbLine2X1 = new TextBox();
+ tbLine2Y1 = new TextBox();
+ label13 = new Label();
+ label14 = new Label();
+ groupBox2 = new GroupBox();
+ NumRectWidth1 = new NumericUpDown();
+ label1 = new Label();
+ splitContainer = new SplitContainer();
+ lblElapsed = new Label();
+ label4 = new Label();
+ btnSave = new Button();
+ panel1.SuspendLayout();
+ statusStrip1.SuspendLayout();
+ panelGuide.SuspendLayout();
+ groupBox3.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth2).BeginInit();
+ groupBox2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth1).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)splitContainer).BeginInit();
+ splitContainer.Panel1.SuspendLayout();
+ splitContainer.Panel2.SuspendLayout();
+ splitContainer.SuspendLayout();
+ SuspendLayout();
+ //
+ // lblStatus
+ //
+ lblStatus.Name = "lblStatus";
+ lblStatus.Size = new Size(44, 17);
+ lblStatus.Text = " ";
+ //
+ // panel1
+ //
+ panel1.BorderStyle = BorderStyle.FixedSingle;
+ panel1.Controls.Add(canvas);
+ panel1.Controls.Add(statusStrip1);
+ panel1.Dock = DockStyle.Fill;
+ panel1.Location = new Point(0, 0);
+ panel1.Name = "panel1";
+ panel1.Size = new Size(1076, 640);
+ panel1.TabIndex = 1;
+ //
+ // canvas
+ //
+ canvas.AllowMultiSelect = false;
+ canvas.CreateMode = Canvas.Shape.ShapeTypeEnum.Polygon;
+ canvas.Dock = DockStyle.Fill;
+ canvas.Enabled = false;
+ canvas.FillDrawing = false;
+ canvas.Location = new Point(0, 0);
+ canvas.Margin = new Padding(2);
+ canvas.Name = "canvas";
+ canvas.OutsideShapes = (List)resources.GetObject("canvas.OutsideShapes");
+ canvas.Scale = 1F;
+ canvas.Shapes = (List)resources.GetObject("canvas.Shapes");
+ canvas.Size = new Size(1074, 616);
+ canvas.TabIndex = 2;
+ //
+ // statusStrip1
+ //
+ statusStrip1.Items.AddRange(new ToolStripItem[] { lblStatus });
+ statusStrip1.Location = new Point(0, 616);
+ statusStrip1.Name = "statusStrip1";
+ statusStrip1.Size = new Size(1074, 22);
+ statusStrip1.TabIndex = 1;
+ statusStrip1.Text = "statusStrip1";
+ //
+ // ctrlTitleBar
+ //
+ ctrlTitleBar.Dock = DockStyle.Top;
+ ctrlTitleBar.Location = new Point(0, 0);
+ ctrlTitleBar.MinimumSize = new Size(0, 36);
+ ctrlTitleBar.Name = "ctrlTitleBar";
+ ctrlTitleBar.Padding = new Padding(3);
+ ctrlTitleBar.Size = new Size(198, 36);
+ ctrlTitleBar.TabIndex = 11;
+ ctrlTitleBar.Title = "线线测量";
+ //
+ // tbLine1X2
+ //
+ tbLine1X2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine1X2.Location = new Point(56, 80);
+ tbLine1X2.Name = "tbLine1X2";
+ tbLine1X2.Size = new Size(134, 23);
+ tbLine1X2.TabIndex = 9;
+ //
+ // label8
+ //
+ label8.AutoSize = true;
+ label8.Location = new Point(6, 83);
+ label8.Name = "label8";
+ label8.Size = new Size(26, 17);
+ label8.TabIndex = 8;
+ label8.Text = "X2:";
+ //
+ // tbLine1Y2
+ //
+ tbLine1Y2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine1Y2.Location = new Point(56, 109);
+ tbLine1Y2.Name = "tbLine1Y2";
+ tbLine1Y2.Size = new Size(134, 23);
+ tbLine1Y2.TabIndex = 7;
+ //
+ // label5
+ //
+ label5.AutoSize = true;
+ label5.Location = new Point(6, 112);
+ label5.Name = "label5";
+ label5.Size = new Size(25, 17);
+ label5.TabIndex = 6;
+ label5.Text = "Y2:";
+ //
+ // label10
+ //
+ label10.AutoSize = true;
+ label10.Location = new Point(6, 521);
+ label10.Name = "label10";
+ label10.Size = new Size(44, 17);
+ label10.TabIndex = 16;
+ label10.Text = "耗时:";
+ //
+ // tbLine1X1
+ //
+ tbLine1X1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine1X1.Location = new Point(56, 22);
+ tbLine1X1.Name = "tbLine1X1";
+ tbLine1X1.Size = new Size(134, 23);
+ tbLine1X1.TabIndex = 5;
+ //
+ // tbLine1Y1
+ //
+ tbLine1Y1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine1Y1.Location = new Point(56, 51);
+ tbLine1Y1.Name = "tbLine1Y1";
+ tbLine1Y1.Size = new Size(134, 23);
+ tbLine1Y1.TabIndex = 4;
+ //
+ // label6
+ //
+ label6.AutoSize = true;
+ label6.Location = new Point(6, 54);
+ label6.Name = "label6";
+ label6.Size = new Size(25, 17);
+ label6.TabIndex = 1;
+ label6.Text = "Y1:";
+ //
+ // label7
+ //
+ label7.AutoSize = true;
+ label7.Location = new Point(6, 25);
+ label7.Name = "label7";
+ label7.Size = new Size(26, 17);
+ label7.TabIndex = 0;
+ label7.Text = "X1:";
+ //
+ // btnLoadImage
+ //
+ btnLoadImage.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnLoadImage.Location = new Point(6, 394);
+ btnLoadImage.Name = "btnLoadImage";
+ btnLoadImage.Size = new Size(184, 32);
+ btnLoadImage.TabIndex = 18;
+ btnLoadImage.Text = "打开图片";
+ btnLoadImage.UseVisualStyleBackColor = true;
+ btnLoadImage.Click += btnLoadImage_Click;
+ //
+ // label9
+ //
+ label9.AutoSize = true;
+ label9.Location = new Point(54, 521);
+ label9.Name = "label9";
+ label9.Size = new Size(32, 17);
+ label9.TabIndex = 17;
+ label9.Text = "0ms";
+ //
+ // btnExecute
+ //
+ btnExecute.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnExecute.Location = new Point(5, 432);
+ btnExecute.Name = "btnExecute";
+ btnExecute.Size = new Size(184, 32);
+ btnExecute.TabIndex = 15;
+ btnExecute.Text = "执行";
+ btnExecute.UseVisualStyleBackColor = true;
+ btnExecute.Click += btnExecute_Click;
+ //
+ // panelGuide
+ //
+ panelGuide.BorderStyle = BorderStyle.FixedSingle;
+ panelGuide.Controls.Add(btnSave);
+ panelGuide.Controls.Add(lblDistance);
+ panelGuide.Controls.Add(label17);
+ panelGuide.Controls.Add(lblResult);
+ panelGuide.Controls.Add(label15);
+ panelGuide.Controls.Add(groupBox3);
+ panelGuide.Controls.Add(btnLoadImage);
+ panelGuide.Controls.Add(label9);
+ panelGuide.Controls.Add(btnExecute);
+ panelGuide.Controls.Add(label10);
+ panelGuide.Controls.Add(groupBox2);
+ panelGuide.Controls.Add(ctrlTitleBar);
+ panelGuide.Dock = DockStyle.Fill;
+ panelGuide.Location = new Point(0, 0);
+ panelGuide.Name = "panelGuide";
+ panelGuide.Size = new Size(200, 640);
+ panelGuide.TabIndex = 0;
+ //
+ // lblDistance
+ //
+ lblDistance.AutoSize = true;
+ lblDistance.Location = new Point(54, 493);
+ lblDistance.Name = "lblDistance";
+ lblDistance.Size = new Size(15, 17);
+ lblDistance.TabIndex = 25;
+ lblDistance.Text = "0";
+ //
+ // label17
+ //
+ label17.AutoSize = true;
+ label17.Location = new Point(6, 493);
+ label17.Name = "label17";
+ label17.Size = new Size(44, 17);
+ label17.TabIndex = 24;
+ label17.Text = "距离:";
+ //
+ // lblResult
+ //
+ lblResult.AutoSize = true;
+ lblResult.Location = new Point(54, 467);
+ lblResult.Name = "lblResult";
+ lblResult.Size = new Size(20, 17);
+ lblResult.TabIndex = 23;
+ lblResult.Text = "无";
+ //
+ // label15
+ //
+ label15.AutoSize = true;
+ label15.Location = new Point(6, 467);
+ label15.Name = "label15";
+ label15.Size = new Size(44, 17);
+ label15.TabIndex = 22;
+ label15.Text = "结果:";
+ //
+ // groupBox3
+ //
+ groupBox3.Controls.Add(NumRectWidth2);
+ groupBox3.Controls.Add(label2);
+ groupBox3.Controls.Add(tbLine2X2);
+ groupBox3.Controls.Add(label11);
+ groupBox3.Controls.Add(tbLine2Y2);
+ groupBox3.Controls.Add(label12);
+ groupBox3.Controls.Add(tbLine2X1);
+ groupBox3.Controls.Add(tbLine2Y1);
+ groupBox3.Controls.Add(label13);
+ groupBox3.Controls.Add(label14);
+ groupBox3.Dock = DockStyle.Top;
+ groupBox3.Location = new Point(0, 216);
+ groupBox3.Name = "groupBox3";
+ groupBox3.Size = new Size(198, 172);
+ groupBox3.TabIndex = 21;
+ groupBox3.TabStop = false;
+ groupBox3.Text = "线2参数";
+ //
+ // NumRectWidth2
+ //
+ NumRectWidth2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ NumRectWidth2.Location = new Point(53, 138);
+ NumRectWidth2.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
+ NumRectWidth2.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
+ NumRectWidth2.Name = "NumRectWidth2";
+ NumRectWidth2.Size = new Size(136, 23);
+ NumRectWidth2.TabIndex = 13;
+ NumRectWidth2.Value = new decimal(new int[] { 1, 0, 0, 0 });
+ //
+ // label2
+ //
+ label2.AutoSize = true;
+ label2.Location = new Point(6, 140);
+ label2.Name = "label2";
+ label2.Size = new Size(35, 17);
+ label2.TabIndex = 12;
+ label2.Text = "宽度:";
+ //
+ // tbLine2X2
+ //
+ tbLine2X2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine2X2.Location = new Point(56, 80);
+ tbLine2X2.Name = "tbLine2X2";
+ tbLine2X2.Size = new Size(134, 23);
+ tbLine2X2.TabIndex = 9;
+ //
+ // label11
+ //
+ label11.AutoSize = true;
+ label11.Location = new Point(6, 83);
+ label11.Name = "label11";
+ label11.Size = new Size(26, 17);
+ label11.TabIndex = 8;
+ label11.Text = "X2:";
+ //
+ // tbLine2Y2
+ //
+ tbLine2Y2.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine2Y2.Location = new Point(56, 109);
+ tbLine2Y2.Name = "tbLine2Y2";
+ tbLine2Y2.Size = new Size(136, 23);
+ tbLine2Y2.TabIndex = 7;
+ //
+ // label12
+ //
+ label12.AutoSize = true;
+ label12.Location = new Point(6, 112);
+ label12.Name = "label12";
+ label12.Size = new Size(25, 17);
+ label12.TabIndex = 6;
+ label12.Text = "Y2:";
+ //
+ // tbLine2X1
+ //
+ tbLine2X1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine2X1.Location = new Point(56, 22);
+ tbLine2X1.Name = "tbLine2X1";
+ tbLine2X1.Size = new Size(134, 23);
+ tbLine2X1.TabIndex = 5;
+ //
+ // tbLine2Y1
+ //
+ tbLine2Y1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ tbLine2Y1.Location = new Point(56, 51);
+ tbLine2Y1.Name = "tbLine2Y1";
+ tbLine2Y1.Size = new Size(134, 23);
+ tbLine2Y1.TabIndex = 4;
+ //
+ // label13
+ //
+ label13.AutoSize = true;
+ label13.Location = new Point(6, 54);
+ label13.Name = "label13";
+ label13.Size = new Size(25, 17);
+ label13.TabIndex = 1;
+ label13.Text = "Y1:";
+ //
+ // label14
+ //
+ label14.AutoSize = true;
+ label14.Location = new Point(6, 25);
+ label14.Name = "label14";
+ label14.Size = new Size(26, 17);
+ label14.TabIndex = 0;
+ label14.Text = "X1:";
+ //
+ // groupBox2
+ //
+ groupBox2.Controls.Add(NumRectWidth1);
+ groupBox2.Controls.Add(label1);
+ groupBox2.Controls.Add(tbLine1X2);
+ groupBox2.Controls.Add(label8);
+ groupBox2.Controls.Add(tbLine1Y2);
+ groupBox2.Controls.Add(label5);
+ groupBox2.Controls.Add(tbLine1X1);
+ groupBox2.Controls.Add(tbLine1Y1);
+ groupBox2.Controls.Add(label6);
+ groupBox2.Controls.Add(label7);
+ groupBox2.Dock = DockStyle.Top;
+ groupBox2.Location = new Point(0, 36);
+ groupBox2.Name = "groupBox2";
+ groupBox2.Size = new Size(198, 180);
+ groupBox2.TabIndex = 13;
+ groupBox2.TabStop = false;
+ groupBox2.Text = "线1参数";
+ //
+ // NumRectWidth1
+ //
+ NumRectWidth1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ NumRectWidth1.Location = new Point(54, 138);
+ NumRectWidth1.Maximum = new decimal(new int[] { 9000, 0, 0, 0 });
+ NumRectWidth1.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
+ NumRectWidth1.Name = "NumRectWidth1";
+ NumRectWidth1.Size = new Size(135, 23);
+ NumRectWidth1.TabIndex = 11;
+ NumRectWidth1.Value = new decimal(new int[] { 1, 0, 0, 0 });
+ //
+ // label1
+ //
+ label1.AutoSize = true;
+ label1.Location = new Point(6, 140);
+ label1.Name = "label1";
+ label1.Size = new Size(35, 17);
+ label1.TabIndex = 10;
+ label1.Text = "宽度:";
+ //
+ // splitContainer
+ //
+ splitContainer.Dock = DockStyle.Fill;
+ splitContainer.Location = new Point(0, 0);
+ splitContainer.Name = "splitContainer";
+ //
+ // splitContainer.Panel1
+ //
+ splitContainer.Panel1.Controls.Add(panelGuide);
+ splitContainer.Panel1MinSize = 150;
+ //
+ // splitContainer.Panel2
+ //
+ splitContainer.Panel2.Controls.Add(panel1);
+ splitContainer.Size = new Size(1280, 640);
+ splitContainer.SplitterDistance = 200;
+ splitContainer.TabIndex = 11;
+ //
+ // lblElapsed
+ //
+ lblElapsed.AutoSize = true;
+ lblElapsed.Location = new Point(50, 328);
+ lblElapsed.Name = "lblElapsed";
+ lblElapsed.Size = new Size(32, 17);
+ lblElapsed.TabIndex = 13;
+ lblElapsed.Text = "0ms";
+ //
+ // label4
+ //
+ label4.AutoSize = true;
+ label4.Location = new Point(0, 328);
+ label4.Name = "label4";
+ label4.Size = new Size(44, 17);
+ label4.TabIndex = 12;
+ label4.Text = "耗时:";
+ //
+ // btnSave
+ //
+ btnSave.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
+ btnSave.Location = new Point(3, 541);
+ btnSave.Name = "btnSave";
+ btnSave.Size = new Size(186, 32);
+ btnSave.TabIndex = 26;
+ btnSave.Text = "保存数据";
+ btnSave.UseVisualStyleBackColor = true;
+ btnSave.Click += btnSave_Click;
+ //
+ // GuideLineLineCtrl
+ //
+ AutoScaleDimensions = new SizeF(7F, 17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ Controls.Add(splitContainer);
+ Controls.Add(lblElapsed);
+ Controls.Add(label4);
+ Name = "GuideLineLineCtrl";
+ Size = new Size(1280, 640);
+ panel1.ResumeLayout(false);
+ panel1.PerformLayout();
+ statusStrip1.ResumeLayout(false);
+ statusStrip1.PerformLayout();
+ panelGuide.ResumeLayout(false);
+ panelGuide.PerformLayout();
+ groupBox3.ResumeLayout(false);
+ groupBox3.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth2).EndInit();
+ groupBox2.ResumeLayout(false);
+ groupBox2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)NumRectWidth1).EndInit();
+ splitContainer.Panel1.ResumeLayout(false);
+ splitContainer.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)splitContainer).EndInit();
+ splitContainer.ResumeLayout(false);
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private ToolStripStatusLabel lblStatus;
+ private Panel panel1;
+ private Canvas.UI.FlyCanvas canvas;
+ private StatusStrip statusStrip1;
+ private SizeCtrlTitleBar ctrlTitleBar;
+ private TextBox tbLine1X2;
+ private Label label8;
+ private TextBox tbLine1Y2;
+ private Label label5;
+ private Label label10;
+ private TextBox tbLine1X1;
+ private TextBox tbLine1Y1;
+ private Label label6;
+ private Label label7;
+ private Button btnLoadImage;
+ private Label label9;
+ private Button btnExecute;
+ private Panel panelGuide;
+ private GroupBox groupBox2;
+ private SplitContainer splitContainer;
+ private Label lblElapsed;
+ private Label label4;
+ private GroupBox groupBox3;
+ private TextBox tbLine2X2;
+ private Label label11;
+ private TextBox tbLine2Y2;
+ private Label label12;
+ private TextBox tbLine2X1;
+ private TextBox tbLine2Y1;
+ private Label label13;
+ private Label label14;
+ private Label label1;
+ private Label label2;
+ private NumericUpDown NumRectWidth2;
+ private NumericUpDown NumRectWidth1;
+ private Label lblDistance;
+ private Label label17;
+ private Label lblResult;
+ private Label label15;
+ private Button btnSave;
+ }
+}
\ No newline at end of file
diff --git a/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.cs b/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.cs
new file mode 100644
index 0000000..66a2eee
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.cs
@@ -0,0 +1,526 @@
+using CanFly.Canvas.Helper;
+using CanFly.Canvas.Shape;
+using CanFly.Helper;
+using HalconDotNet;
+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 CanFly.UI.SizePanel
+{
+ public partial class SizeGuideLineLineCtrl : SizeBaseGuideControl
+ {
+ private FlyShape? _line1;
+ private FlyShape? _line2;
+
+ private float _line1X1;
+ private float _line1Y1;
+ private float _line1X2;
+ private float _line1Y2;
+ private float _lineWidth;
+
+ private float _line2X1;
+ private float _line2Y1;
+ private float _line2X2;
+ private float _line2Y2;
+ private float _line2Width;
+
+ protected override string GetScriptFileName() => "LineToLine.hdvp";
+
+
+ public SizeGuideLineLineCtrl()
+ {
+ InitializeComponent();
+ this.canvas.mouseMoved += Canvas_mouseMoved;
+ this.canvas.OnShapeUpdateEvent += UpdateShape;
+ this.canvas.selectionChanged += Canvas_selectionChanged;
+
+ this.canvas.OnShapeMoving += Canvas_OnShapeMoving;
+ this.canvas.newShape += Canvas_newShape;
+
+ this.ctrlTitleBar.OnCloseClicked += OnControlClose;
+ NumRectWidth1.ValueChanged -= NumRectWidth1_ValueChanged;
+ NumRectWidth1.Value = 40;
+ NumRectWidth1.ValueChanged += NumRectWidth1_ValueChanged;
+
+ NumRectWidth2.ValueChanged -= NumericUpDown2_ValueChanged;
+ NumRectWidth2.Value = 40;
+ NumRectWidth2.ValueChanged += NumericUpDown2_ValueChanged;
+
+ }
+ protected override void UpdateShape(FlyShape shape)
+ {
+ switch (shape.ShapeType)
+ {
+ case ShapeTypeEnum.Line:
+ // 判断是否为第一条直线或第二条直线
+ if (_line1 == shape)
+ {
+ //_line1 = shape;
+ var pts1 = _line1.Points;
+ _line1X1 = pts1[0].X;
+ _line1Y1 = pts1[0].Y;
+ _line1X2 = pts1[1].X;
+ _line1Y2 = pts1[1].Y;
+ _lineWidth = _line1.LineVirtualRectWidth;
+
+ tbLine1X1.Text = _line1X1.ToString("F3");
+ tbLine1Y1.Text = _line1Y1.ToString("F3");
+ tbLine1X2.Text = _line1X2.ToString("F3");
+ tbLine1Y2.Text = _line1Y2.ToString("F3");
+ //NumRectWidth1.Value = (decimal)_lineWidth;
+ }
+ else
+ {
+ //_line2 = shape;
+ var pts2 = _line2.Points;
+ _line2X1 = pts2[0].X;
+ _line2Y1 = pts2[0].Y;
+ _line2X2 = pts2[1].X;
+ _line2Y2 = pts2[1].Y;
+ _line2Width = _line2.LineVirtualRectWidth;
+
+ tbLine2X1.Text = _line2X1.ToString("F3");
+ tbLine2Y1.Text = _line2Y1.ToString("F3");
+ tbLine2X2.Text = _line2X2.ToString("F3");
+ tbLine2Y2.Text = _line2Y2.ToString("F3");
+ // NumRectWidth2.Value = (decimal)_line2Width;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+
+
+
+ private void GuideLineCircleCtrl_Load(object sender, EventArgs e)
+ {
+
+
+
+ }
+
+
+
+
+ private void Canvas_mouseMoved(PointF pos)
+ {
+ if (InvokeRequired)
+ {
+ Invoke(Canvas_mouseMoved, pos);
+ return;
+ }
+
+ lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
+
+ }
+
+
+
+
+ private void Canvas_selectionChanged(List shapes)
+ {
+ //if (shapes.Count != 1)
+ //{
+ // // panelGuide.Controls.Clear();
+ // return;
+ //}
+ //SwitchGuideForm(shapes[0].ShapeType);
+ // Canvas_OnShapeUpdateEvent(shapes[0]);
+
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+ UpdateShape(shapes[0]);
+
+ }
+
+
+
+ private void Canvas_OnShapeMoving(List shapes)
+ {
+ if (shapes.Count != 1)
+ {
+ return;
+ }
+
+ UpdateShape(shapes[0]);
+ }
+ private void Canvas_newShape()
+ {
+ // 自动切换到下一条直线绘制
+ if (_line1 == null)
+ {
+ _line1 = this.canvas.Shapes.LastOrDefault(shp => shp.ShapeType == ShapeTypeEnum.Line);
+ }
+ else if (_line2 == null)
+ {
+ _line2 = this.canvas.Shapes.LastOrDefault(shp => shp.ShapeType == ShapeTypeEnum.Line);
+ }
+
+ // 停止绘制模式,用户可以根据需要重新启用
+ this.canvas.StopDraw();
+ //this.canvas.StopDraw();
+ }
+
+ private void btnCreateLineOne_Click(object sender, EventArgs e)
+ {
+ // this.canvas.Shapes.RemoveAll(shp => shp == _line1); // 移除第一条直线
+ this._line1 = null;
+ this.canvas.Invalidate();
+ this.canvas.StartDraw(ShapeTypeEnum.Line); // 启动绘制模式
+ this.canvas.Enabled = true;
+ }
+
+ private void btnCreateLineTwo_Click(object sender, EventArgs e)
+ {
+ // this.canvas.Shapes.RemoveAll(shp => shp == _line2); // 移除第二条直线
+ this._line2 = null;
+ this.canvas.Invalidate();
+ this.canvas.StartDraw(ShapeTypeEnum.Line); // 启动绘制模式
+ this.canvas.Enabled = true;
+ }
+
+ private void btnExecute_Click(object sender, EventArgs e)
+ {
+ if (this.canvas.pixmap == null)
+ {
+ MessageBox.Show("请先打开图片");
+ return;
+ }
+
+ this.canvas.OutsideShapes.Clear();
+ this.canvas.Invalidate();
+
+ flag = new List();
+ Distance = new List();
+ Line1_RowBegin = new List();
+ Line1_ColBegin = new List();
+ Line1_RowEnd = new List();
+ Line1_ColEnd = new List();
+ Line2_RowBegin = new List();
+ Line2_ColBegin = new List();
+ Line2_RowEnd = new List();
+ Line2_ColEnd = new List();
+ Dictionary inputImg = new Dictionary();
+
+ if (hImage == null)
+ {
+ HOperatorSet.ReadImage(out hImage, CurrentImageFile);
+ }
+ inputImg["INPUT_Image"] = hImage;
+
+ Dictionary inputPara = new Dictionary();
+
+
+ // 获取矩形的 4 个点
+ PointF[] Points = this._line1.LineVirtualRectPoints;
+ if (Points.Count() < 4)
+ {
+ return;
+ }
+ PointF Point1 = Points[0];
+ PointF Point2 = Points[1];
+ PointF Point3 = Points[2];
+ PointF Point4 = Points[3];
+ PointF Point5 = Points[0];
+
+ float x1 = Point1.X;
+ float y1 = Point1.Y;
+
+ float x2 = Point2.X;
+ float y2 = Point2.Y;
+
+ float x3 = Point3.X;
+ float y3 = Point3.Y;
+
+ float x4 = Point4.X;
+ float y4 = Point4.Y;
+
+ float x5 = Point5.X;
+ float y5 = Point5.Y;
+
+
+ float[] array1X = new float[] { x1, x2, x3, x4, x5 };
+ HTuple hTupleArray1X = new HTuple(array1X);
+
+ float[] array1Y = new float[] { y1, y2, y3, y4, y5 };
+ HTuple hTupleArray1Y = new HTuple(array1Y);
+
+
+ strarray1X = string.Join(",", array1X);
+ strarray1Y = string.Join(",", array1Y);
+
+
+ // 获取矩形的 4 个点
+ PointF[] Points2 = this._line2.LineVirtualRectPoints;
+ if (Points2.Count() < 4)
+ {
+ return;
+ }
+ PointF Point21 = Points2[0];
+ PointF Point22 = Points2[1];
+ PointF Point23 = Points2[2];
+ PointF Point24 = Points2[3];
+ PointF Point25 = Points2[0];
+
+ float x21 = Point21.X;
+ float y21 = Point21.Y;
+
+ float x22 = Point22.X;
+ float y22 = Point22.Y;
+
+ float x23 = Point23.X;
+ float y23 = Point23.Y;
+
+ float x24 = Point24.X;
+ float y24 = Point24.Y;
+
+ float x25 = Point25.X;
+ float y25 = Point25.Y;
+
+
+ float[] array2X = new float[] { x21, x22, x23, x24, x25 };
+ HTuple hTupleArray2X = new HTuple(array2X);
+
+ float[] array2Y = new float[] { y21, y22, y23, y24, y25 };
+ HTuple hTupleArray2Y = new HTuple(array2Y);
+
+
+ strarray2X = string.Join(",", array2X);
+ strarray2Y = string.Join(",", array2Y);
+
+ inputPara["Line1_LX"] = _line1X1;
+ inputPara["Line1_LY"] = _line1Y1;
+ inputPara["Line1_RX"] = _line1X2;
+ inputPara["Line1_RY"] = _line1Y2;
+
+ inputPara["Line2_LX"] = _line2X1;
+ inputPara["Line2_LY"] = _line2Y1;
+ inputPara["Line2_RX"] = _line2X2;
+ inputPara["Line2_RY"] = _line2Y2;
+
+
+
+ inputPara["Line1_XRect"] = hTupleArray1X;
+ inputPara["Line1_YRect"] = hTupleArray1Y;
+
+ inputPara["Line2_XRect"] = hTupleArray2X;
+ inputPara["Line2_YRect"] = hTupleArray2Y;
+
+ List outputKeys = new List()
+ {
+ "OUTPUT_Flag",
+ "Distance",
+ "Line1_RowBegin",
+ "Line1_ColBegin",
+ "Line1_RowEnd",
+ "Line1_ColEnd",
+ "Line2_RowBegin",
+ "Line2_ColBegin",
+ "Line2_RowEnd",
+ "Line2_ColEnd"
+
+ };
+
+ ExecuteHScript(
+ inputImg,
+ inputPara,
+ outputKeys);
+ }
+
+
+ private void btnLoadImage_Click(object sender, EventArgs e)
+ {
+ OpenImageFile(bitmap =>
+ {
+ this.canvas.LoadPixmap(bitmap);
+ this.canvas.Enabled = true;
+ _line1 = new FlyShape();
+ _line2 = new FlyShape();
+ _line1.AddPoint(new Point(10, 10));
+ _line1.AddPoint(new Point(50, 10));
+ _line2.AddPoint(new Point(10, 20));
+ _line2.AddPoint(new Point(60, 20));
+ _line1.ShapeType = ShapeTypeEnum.Line;
+ _line2.ShapeType = ShapeTypeEnum.Line;
+
+ _line1.IsDrawLineVirtualRect = true;
+ _line1.LineVirtualRectWidth = 40;
+ _line2.IsDrawLineVirtualRect = true;
+ _line2.LineVirtualRectWidth = 40;
+
+ canvas.Shapes.Add(_line1);
+ canvas.Shapes.Add(_line2);
+ canvas.Invalidate();
+
+ UpdateShape(_line1);
+ UpdateShape(_line2);
+ });
+ }
+ string strarray1X = string.Empty;
+ string strarray1Y = string.Empty;
+ string strarray2X = string.Empty;
+ string strarray2Y = string.Empty;
+ List flag =new List();
+ List Distance = new List();
+ List Line1_RowBegin = new List();
+ List Line1_ColBegin = new List();
+ List Line1_RowEnd = new List();
+ List Line1_ColEnd = new List();
+ List Line2_RowBegin = new List();
+ List Line2_ColBegin = new List();
+ List Line2_RowEnd = new List();
+ List Line2_ColEnd = new List();
+ protected override void OnExecuteHScriptResult(
+ bool success,
+ Dictionary resultDic,
+ int timeElasped)
+ {
+ if (!success)
+ {
+ return;
+ }
+
+ //"OUTPUT_Flag",
+ // "Distance",
+ // "Line1_RowBegin",
+ // "Line1_ColBegin",
+ // "Line1_RowEnd",
+ // "Line1_ColEnd",
+ // "Line2_RowBegin",
+ // "Line2_ColBegin",
+ // "Line2_RowEnd",
+ // "Line2_ColEnd"
+
+
+ flag = resultDic["OUTPUT_Flag"].HTupleToDouble();
+ Distance = resultDic["Distance"].HTupleToDouble();
+ Line1_RowBegin = resultDic["Line1_RowBegin"].HTupleToDouble();
+ Line1_ColBegin = resultDic["Line1_ColBegin"].HTupleToDouble();
+ Line1_RowEnd = resultDic["Line1_RowEnd"].HTupleToDouble();
+ Line1_ColEnd = resultDic["Line1_ColEnd"].HTupleToDouble();
+ Line2_RowBegin = resultDic["Line2_RowBegin"].HTupleToDouble();
+ Line2_ColBegin = resultDic["Line2_ColBegin"].HTupleToDouble();
+ Line2_RowEnd = resultDic["Line2_RowEnd"].HTupleToDouble();
+ Line2_ColEnd = resultDic["Line2_ColEnd"].HTupleToDouble();
+
+ if (flag.Count > 0)
+ {
+ lblResult.Text = flag[0].ToString();
+
+ }
+ else
+ {
+ lblResult.Text = "无";
+ }
+ if (Distance.Count > 0)
+ {
+ lblDistance.Text = Distance[0].ToString();
+ }
+ else
+ {
+ lblDistance.Text = "0";
+ }
+
+ if (flag.Count > 0 && Distance.Count > 0 && Line1_RowBegin.Count > 0 && Line1_ColBegin.Count > 0 && Line1_RowEnd.Count > 0 && Line1_ColEnd.Count > 0 && Line2_RowBegin.Count > 0 && Line2_ColBegin.Count > 0 && Line2_RowEnd.Count > 0 && Line2_ColEnd.Count > 0)
+ {
+ float width = 0;
+ this.canvas.DrawLine(new PointF((float)Line1_ColBegin[0], (float)Line1_RowBegin[0]), new PointF((float)Line1_ColEnd[0], (float)Line1_RowEnd[0]), width);
+ this.canvas.DrawLine(new PointF((float)Line2_ColBegin[0], (float)Line2_RowBegin[0]), new PointF((float)Line2_ColEnd[0], (float)Line2_RowEnd[0]), width);
+ this.canvas.Invalidate();
+ lblElapsed.Text = $"{timeElasped} ms";
+ }
+ }
+
+ private void NumRectWidth1_ValueChanged(object sender, EventArgs e)
+ {
+ if (_line1 != null)
+ {
+ //_line1.IsDrawLineVirtualRect = true;
+ _line1.LineVirtualRectWidth = (float)NumRectWidth1.Value;
+ UpdateShape(_line1);
+ this.canvas.Invalidate();
+ }
+ }
+
+ private void NumericUpDown2_ValueChanged(object sender, EventArgs e)
+ {
+ if (_line2 != null)
+ {
+ // _line2.IsDrawLineVirtualRect = true;
+ _line2.LineVirtualRectWidth = (float)NumRectWidth2.Value;
+ UpdateShape(_line2);
+ this.canvas.Invalidate();
+ }
+ }
+
+ private void btnSave_Click(object sender, EventArgs e)
+ {
+ if (lblResult.Text.Equals("无"))
+ {
+ MessageBox.Show("请先进行绘制");
+ return;
+ }
+ if (lblResult.Text != "0")
+ {
+ MessageBox.Show("测量计算错误,无法保存");
+ return;
+ }
+
+
+
+ //inputPara["Line1_LX"] = _line1X1;
+ //inputPara["Line1_LY"] = _line1Y1;
+ //inputPara["Line1_RX"] = _line1X2;
+ //inputPara["Line1_RY"] = _line1Y2;
+
+ //inputPara["Line2_LX"] = _line2X1;
+ //inputPara["Line2_LY"] = _line2Y1;
+ //inputPara["Line2_RX"] = _line2X2;
+ //inputPara["Line2_RY"] = _line2Y2;
+
+
+
+ //inputPara["Line1_XRect"] = hTupleArray1X;
+ //inputPara["Line1_YRect"] = hTupleArray1Y;
+
+ //inputPara["Line2_XRect"] = hTupleArray2X;
+ //inputPara["Line2_YRect"] = hTupleArray2Y;
+
+
+ string input = $"Line1_LX:{_line1X1};" +
+ $"Line1_LY:{_line1Y1};" +
+ $"Line1_RX:{_line1X2};" +
+ $"Line1_RY:{_line1Y2};" +
+ $"Line2_LX:{_line2X1};" +
+ $"Line2_LY:{_line2Y1};" +
+ $"Line2_RX:{_line2X2};" +
+ $"Line2_RY:{_line2Y2};" +
+ $"Line1_XRect:{strarray1X};" +
+ $"Line1_YRect:{strarray1Y};" +
+ $"Line2_XRect:{strarray2X};" +
+ $"Line2_YRect:{strarray2Y}"
+ ;
+
+
+ string result = $"Distance:{Distance[0]}";
+
+
+ DataToTriggerEvent(input, result);
+
+ }
+ }
+}
diff --git a/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.resx b/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.resx
new file mode 100644
index 0000000..097e294
--- /dev/null
+++ b/CanFly/UI/SizePanel/SizeGuideLineLineCtrl.resx
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAERDYW5GbHkuQ2FudmFzLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
+ cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAdlN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
+ cmljLkxpc3RgMVtbQ2FuRmx5LkNhbnZhcy5TaGFwZS5GbHlTaGFwZSwgQ2FuRmx5LkNhbnZhcywgQ3Vs
+ dHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVyc2lv
+ bgQAAB5DYW5GbHkuQ2FudmFzLlNoYXBlLkZseVNoYXBlW10CAAAACAgJAwAAAAAAAAAAAAAADAQAAAAz
+ Q2FuRmx5LkNhbnZhcywgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMAAAAAAQAA
+ AAAAAAAEHENhbkZseS5DYW52YXMuU2hhcGUuRmx5U2hhcGUEAAAACw==
+
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/CanFly/UI/UIMain/FrmMainSize.Designer.cs b/CanFly/UI/UIMain/FrmMainSize.Designer.cs
new file mode 100644
index 0000000..5cd1fbb
--- /dev/null
+++ b/CanFly/UI/UIMain/FrmMainSize.Designer.cs
@@ -0,0 +1,93 @@
+
+
+namespace XKRS.CanFly
+{
+ partial class FrmMainSize
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ statusStrip1 = new StatusStrip();
+ panelContent = new Panel();
+ pageHeader1 = new AntdUI.PageHeader();
+ panelContent.SuspendLayout();
+ SuspendLayout();
+ //
+ // statusStrip1
+ //
+ statusStrip1.Location = new Point(0, 808);
+ statusStrip1.Name = "statusStrip1";
+ statusStrip1.Size = new Size(1185, 22);
+ statusStrip1.TabIndex = 4;
+ statusStrip1.Text = "statusStrip1";
+ //
+ // panelContent
+ //
+ panelContent.Controls.Add(pageHeader1);
+ panelContent.Dock = DockStyle.Fill;
+ panelContent.Location = new Point(0, 0);
+ panelContent.Margin = new Padding(4, 3, 4, 3);
+ panelContent.Name = "panelContent";
+ panelContent.Size = new Size(1185, 808);
+ panelContent.TabIndex = 5;
+ //
+ // pageHeader1
+ //
+ pageHeader1.BackColor = Color.FromArgb(46, 108, 227);
+ pageHeader1.Dock = DockStyle.Top;
+ pageHeader1.Location = new Point(0, 0);
+ pageHeader1.Mode = AntdUI.TAMode.Dark;
+ pageHeader1.Name = "pageHeader1";
+ pageHeader1.ShowButton = true;
+ pageHeader1.ShowIcon = true;
+ pageHeader1.Size = new Size(1185, 33);
+ pageHeader1.TabIndex = 2;
+ pageHeader1.Text = "尺寸测量";
+ //
+ // FrmMainSize
+ //
+ AutoScaleDimensions = new SizeF(7F, 17F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(1185, 830);
+ Controls.Add(panelContent);
+ Controls.Add(statusStrip1);
+ FormBorderStyle = FormBorderStyle.FixedSingle;
+ Margin = new Padding(2, 3, 2, 3);
+ Name = "FrmMainSize";
+ StartPosition = FormStartPosition.CenterScreen;
+ Text = "尺寸测量";
+ Load += FrmMain_Load;
+ panelContent.ResumeLayout(false);
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+ private StatusStrip statusStrip1;
+ private Panel panelContent;
+ private AntdUI.PageHeader pageHeader1;
+ }
+}
diff --git a/CanFly/UI/UIMain/FrmMainSize.cs b/CanFly/UI/UIMain/FrmMainSize.cs
new file mode 100644
index 0000000..c608b17
--- /dev/null
+++ b/CanFly/UI/UIMain/FrmMainSize.cs
@@ -0,0 +1,440 @@
+using AntdUI;
+using CanFly.Canvas.Shape;
+using CanFly.Helper;
+using CanFly.UI;
+using CanFly.UI.GuidePanel;
+using CanFly.UI.SizePanel;
+using CanFly.Util;
+using DH.Commons.Base;
+using HalconDotNet;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Windows.Forms;
+
+namespace XKRS.CanFly
+{
+
+ public partial class FrmMainSize : Window
+ {
+
+ private string _currentImageFile = "";
+ private System.Windows.Forms.Timer _statusTimer = new System.Windows.Forms.Timer();
+ private SizeBaseGuideControl? _currentGuideCtrl;
+
+
+ private SizeGuideCircleCtrl guideCircleCtrl = new SizeGuideCircleCtrl();
+ private SizeGuideLineCircleCtrl guideLineCircleCtrl = new SizeGuideLineCircleCtrl();
+ private SizeGuideLineLineCtrl guideLineLineCtrl = new SizeGuideLineLineCtrl();
+ private SizeGuideLineCtrl guideLineCtrl = new SizeGuideLineCtrl();
+ private SizeGuideHeightCtrl guideHeightCtrl = new SizeGuideHeightCtrl();
+ string Type=string.Empty;
+
+
+ public string inputtext=string.Empty;
+ public string outtext = string.Empty;
+ DetectionConfig DetectionConfig;
+ public FrmMainSize(string type,DetectionConfig detectionConfig)
+ {
+ InitializeComponent();
+
+ DetectionConfig = detectionConfig;
+ Type=type;
+
+ guideCircleCtrl.Dock = DockStyle.Fill;
+ guideCircleCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
+ guideCircleCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
+
+
+ guideLineCircleCtrl.Dock = DockStyle.Fill;
+ guideLineCircleCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
+ guideLineCircleCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
+
+ guideLineLineCtrl.Dock = DockStyle.Fill;
+ guideLineLineCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
+ guideLineLineCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
+
+ guideLineCtrl.Dock = DockStyle.Fill;
+ guideLineCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
+ guideLineCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
+
+
+ guideHeightCtrl.Dock = DockStyle.Fill;
+ guideHeightCtrl.OnControlCloseEvent -= () => panelContent.Controls.Clear();
+ guideHeightCtrl.OnControlCloseEvent += () => panelContent.Controls.Clear();
+ }
+
+
+
+ private void FrmMain_Load(object sender, EventArgs e)
+ {
+ switch (Type)
+ {
+ case "1":
+ SwitchMeasureMode(guideCircleCtrl);
+ break;
+ case "2":
+ SwitchMeasureMode(guideLineCtrl);
+ break;
+ case "3":
+ SwitchMeasureMode(guideLineLineCtrl);
+ break;
+ case "4":
+ SwitchMeasureMode(guideLineCircleCtrl);
+ break;
+ case "5":
+ SwitchMeasureMode(guideHeightCtrl);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ private void btnLoadImage_Click(object sender, EventArgs e)
+ {
+ //OpenFileDialog ofd = new OpenFileDialog();
+ //ofd.Filter = "ͼļ|*.jpg;*.png";
+ //ofd.Multiselect = false;
+ //if (ofd.ShowDialog() == DialogResult.OK)
+ //{
+ // _currentImageFile = ofd.FileName;
+ // Bitmap bitmap = (Bitmap)Image.FromFile(_currentImageFile);
+ // this.canvas.LoadPixmap(bitmap);
+ // this.btnCreateCircle.Enabled = true;
+ //}
+ }
+
+
+
+ private void btnMeasureCircle_Click(object sender, EventArgs e)
+ {
+ //var contentCtrls = panelContent.Controls;
+
+ //if (contentCtrls.Count > 0)
+ //{
+ // if (contentCtrls[0] == guideCircleCtrl)
+ // {
+ // return;
+ // }
+ //}
+
+ //panelContent.Controls.Clear();
+ //panelContent.Controls.Add(guideCircleCtrl);
+
+ SwitchMeasureMode(guideCircleCtrl);
+ }
+
+
+ private void btnMeasureLineCircle_Click(object sender, EventArgs e)
+ {
+ SwitchMeasureMode(guideLineCircleCtrl);
+ }
+
+
+ private void SwitchMeasureMode(SizeBaseGuideControl control)
+ {
+ var contentCtrls = panelContent.Controls;
+
+ if (contentCtrls.Count > 0)
+ {
+ if (contentCtrls[0] == control)
+ {
+ return;
+ }
+ }
+
+ panelContent.Controls.Clear();
+
+ control.OnDataPassed -= Control_OnDataPassed;
+ control.OnDataPassed += Control_OnDataPassed;
+
+
+
+ //control.Dock = DockStyle.Fill;
+ //control.OnControlCloseEvent -= () => panelContent.Controls.Clear();
+ //control.OnControlCloseEvent += () => panelContent.Controls.Clear();
+ panelContent.Controls.Add(control);
+ }
+
+ private void Control_OnDataPassed(string obj,string obj1)
+ {
+ inputtext = obj;
+ outtext = obj1;
+ this.Close();
+ }
+
+ private void btnCreateRect_Click(object sender, EventArgs e)
+ {
+ //this.canvas.StartDraw(ShapeTypeEnum.Rectangle);
+ //this.btnCreateCircle.Enabled = false;
+ //this.btnStopDraw.Enabled = true;
+ //this.canvas.Enabled = true;
+ }
+
+
+
+ private void btnStopDraw_Click(object sender, EventArgs e)
+ {
+ //panelGuide.Controls.Clear();
+ StopDrawMode();
+ }
+
+
+
+ private void StartDrawMode()
+ {
+
+ }
+
+
+ private void StopDrawMode()
+ {
+ //this.canvas.StopDraw();
+
+
+ //this.btnStopDraw.Enabled = false;
+ //this.btnCreateCircle.Enabled = true;
+ }
+
+
+
+
+
+ private void Status(string message, int delay = 5000)
+ {
+ //_statusTimer.Stop();
+ //// ʾϢ
+ //lblStatus.Text = message;
+
+ //// һʱ
+
+ //_statusTimer.Interval = delay; // ӳʱ
+ //_statusTimer.Tick += (sender, e) =>
+ //{
+ // _statusTimer.Stop(); // ֹͣʱ
+ // lblStatus.Text = string.Empty; // ״̬Ϣ
+ //};
+ //_statusTimer.Start(); // ʱ
+ }
+
+
+
+
+ private void Canvas_mouseMoved(PointF pos)
+ {
+ //if (InvokeRequired)
+ //{
+ // Invoke(Canvas_mouseMoved, pos);
+ // return;
+ //}
+
+ //lblStatus.Text = $"X:{pos.X}, Y:{pos.Y}";
+
+ }
+
+
+
+
+ private void Canvas_selectionChanged(List shapes)
+ {
+ if (shapes.Count != 1)
+ {
+ // panelGuide.Controls.Clear();
+ return;
+ }
+ //SwitchGuideForm(shapes[0].ShapeType);
+ Canvas_OnShapeUpdateEvent(shapes[0]);
+
+ }
+
+
+
+ private void SwitchGuideForm(ShapeTypeEnum shapeType)
+ {
+ //if (_currentGuideCtrl == null)
+ //{
+ // switch (shapeType)
+ // {
+ // case ShapeTypeEnum.Point:
+ // break;
+ // case ShapeTypeEnum.Line:
+ // break;
+ // case ShapeTypeEnum.Rectangle:
+ // break;
+ // case ShapeTypeEnum.Circle:
+ // _currentGuideCtrl = new GuideCircleCtrl();
+ // _currentGuideCtrl.ImageFile = _currentImageFile;
+ // _currentGuideCtrl.OnDrawCircle += this.canvas.DrawCircle;
+ // _currentGuideCtrl.OnClose += () =>
+ // {
+ // panelGuide.Controls.Clear();
+ // StopDrawMode();
+ // };
+ // break;
+ // case ShapeTypeEnum.Polygon:
+ // break;
+ // case ShapeTypeEnum.LineStrip:
+ // break;
+ // default:
+ // break;
+ // }
+ //}
+ //_currentGuideCtrl?.AddToPanel(panelGuide);
+ }
+
+
+
+ private void Canvas_OnShapeMoving(List shapes)
+ {
+ //if (shapes.Count != 1)
+ //{
+ // panelGuide.Controls.Clear();
+ // return;
+ //}
+
+ //_currentGuideCtrl?.UpdateShape(shapes[0]);
+ }
+
+
+
+ private void Canvas_OnShapeUpdateEvent(FlyShape shape)
+ {
+ switch (shape.ShapeType)
+ {
+ case ShapeTypeEnum.Point:
+ break;
+ case ShapeTypeEnum.Line:
+ break;
+ case ShapeTypeEnum.Rectangle:
+ break;
+ case ShapeTypeEnum.Circle:
+ {
+ //_currentGuideCtrl?.UpdateShape(shape);
+ }
+ break;
+ case ShapeTypeEnum.Polygon:
+ break;
+ case ShapeTypeEnum.LineStrip:
+ break;
+ default:
+ break;
+ }
+ }
+
+
+
+ private void btnTestOutsideDraw_Click(object sender, EventArgs e)
+ {
+ //Random random = new Random((int)DateTime.Now.Ticks);
+
+ //for (int i = 0; i < 10; i++)
+ //{
+ // // this.canvas.DrawCircle(new PointF(500, 500), 100);
+
+ // int x = random.Next() % 500;
+ // int y = random.Next() % 500;
+ // int r = random.Next() % 200;
+
+ // Debug.WriteLine($"X:{x}\tY:{y}\tR:{r}");
+
+ // this.canvas.DrawCircle(new PointF(x, y), r);
+ //}
+ }
+
+ private void btnTestClearDraw_Click(object sender, EventArgs e)
+ {
+ //this.canvas.ClearDraw();
+ }
+
+
+
+ private async void btnTestCircleMeasure_Click(object sender, EventArgs e)
+ {
+ //string dir = Path.Combine(Environment.CurrentDirectory, "hscripts");
+ //string file = "CircleMeasure.hdvp";
+ //string filePath = Path.Combine(dir, file);
+ //if (!File.Exists(filePath))
+ //{
+ // MessageBox.Show($"ļ {filePath} ");
+ // return;
+ //}
+
+ //HObject? hImage = null;
+
+ //try
+ //{
+ // HDevEngineTool tool = new HDevEngineTool(dir);
+ // tool.LoadProcedure(Path.GetFileNameWithoutExtension(file));
+
+ // // string imageFile = Path.Combine(Environment.CurrentDirectory, "hscripts", "image.png");
+
+ // HOperatorSet.ReadImage(out hImage, _currentImageFile);
+ // tool.InputImageDic["INPUT_Image"] = hImage;
+ // tool.InputTupleDic["XCenter"] = 981.625;
+ // tool.InputTupleDic["YCenter"] = 931.823;
+ // tool.InputTupleDic["Radius"] = 900.141;
+
+ // Stopwatch sw = new Stopwatch();
+ // sw.Start();
+ // if (!tool.RunProcedure(out string error, out _))
+ // {
+ // throw new Exception();
+ // }
+ // sw.Stop();
+
+
+
+ // var flag = tool.GetResultTuple("OUTPUT_Flag").HTupleToDouble();
+ // List x = tool.GetResultTuple("RXCenter").HTupleToDouble();
+ // var y = tool.GetResultTuple("RYCenter").HTupleToDouble();
+ // var r = tool.GetResultTuple("RRadius").HTupleToDouble();
+
+ // if (flag.Count > 0 && x.Count > 0 && y.Count > 0 && r.Count > 0)
+ // {
+ // this.canvas.DrawCircle(new PointF((float)x[0], (float)y[0]), (float)r[0]);
+ // }
+
+ // //
+ // Debug.WriteLine("");
+ //}
+ //catch (Exception)
+ //{
+ // throw;
+ //}
+ //finally
+ //{
+ // hImage?.Dispose();
+ //}
+
+
+ }
+
+ private void btnTest_Click(object sender, EventArgs e)
+ {
+ //this.canvas.DrawRectangle(new PointF(300, 300),
+ // new PointF(800, 500), 33f);
+ }
+
+
+ private void btnRotateTest_Click(object sender, EventArgs e)
+ {
+ //if (this.canvas.Shapes.Count == 0)
+ //{
+ // return;
+ //}
+
+ //this.canvas.Shapes[0]._currentRotateAngle += 10;
+ //this.canvas.Invalidate();
+ }
+
+ private void btnMeasureLineline_Click(object sender, EventArgs e)
+ {
+ SwitchMeasureMode(guideLineLineCtrl);
+ }
+
+ private void btnMeasureLine_Click(object sender, EventArgs e)
+ {
+ SwitchMeasureMode(guideLineCtrl);
+ }
+ }
+}
diff --git a/CanFly/UI/UIMain/FrmMainSize.resx b/CanFly/UI/UIMain/FrmMainSize.resx
new file mode 100644
index 0000000..7258ec3
--- /dev/null
+++ b/CanFly/UI/UIMain/FrmMainSize.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/CanFly/XKRS.CanFly.csproj b/CanFly/XKRS.CanFly.csproj
index 94a81c0..5724784 100644
--- a/CanFly/XKRS.CanFly.csproj
+++ b/CanFly/XKRS.CanFly.csproj
@@ -11,26 +11,20 @@
AnyCPU;x64
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/DH.Commons.Devies/Base/VisionEngineBase.cs b/DH.Commons.Devies/Base/VisionEngineBase.cs
deleted file mode 100644
index 28f5718..0000000
--- a/DH.Commons.Devies/Base/VisionEngineBase.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-using System.Collections;
-using System.ComponentModel;
-using System.Drawing;
-using System.Drawing.Imaging;
-using DH.Commons.Enums;
-using HalconDotNet;
-using OpenCvSharp;
-
-
-
-namespace DH.Devices.Devices
-{
- ///
- /// 视觉处理引擎:1.传统视觉 2.深度学习
- /// CV深度学习 四大领域
- /// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗;
- /// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体;
- /// Object Detection 目标检测:寻找图像中的物体并进行定位;
- /// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体;
- ///
- public abstract class VisionEngineBase
- {
- public List DetectionConfigs = new List();
- #region event
- public event Action> OnCropParamsOutput;
- public event Action> OnDetectionDone;
- public event Action OnDetectionWarningStop;//有无检测 需要报警停机
- #endregion
- //public VisionEngineInitialConfigBase IConfig
- //{
- // get => InitialConfig as VisionEngineInitialConfigBase;
- //}
- // public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
- public string BatchNO { get; set; }
-
- public HTuple hv_ModelID;
-
- public abstract DetectStationResult RunInference(Mat originImgSet, string detectionId = null);
-
- //public abstract void SaveDetectResultAsync(DetectStationResult detectResult);
-
-
-
- public virtual void DetectionDone(string detectionId, Bitmap image, List detectionResults)
- {
- OnDetectionDone?.Invoke(detectionId, image, detectionResults);
- }
-
- public virtual void DetectionWarningStop(string detectionDes)
- {
- OnDetectionWarningStop?.Invoke(detectionDes);
- }
-
- public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat)
- {
- if (saveMap != null)
- {
- //ImageSaveSet imageSaveSet = new ImageSaveSet()
- //{
- // FullName = fullname,
- // SaveImage = saveMap.CopyBitmap(),
- // ImageFormat = imageFormat.DeepSerializeClone()
- //};
-
- //ImageSaveHelper.ImageSaveAsync(imageSaveSet);
- }
- }
- }
- public class CamModuleXY
- {
- [Category("图片行")]
- [DisplayName("行")]
- [Description("行")]
- // [TypeConverter(typeof(DeviceIdSelectorConverter))]
- //[TypeConverter(typeof(CollectionCountConvert))]
- public int PicRows { get; set; } = 1;
-
- [Category("图片列")]
- [DisplayName("列")]
- [Description("列")]
- // [TypeConverter(typeof(DeviceIdSelectorConverter))]
- //[TypeConverter(typeof(CollectionCountConvert))]
- public int PicCols { get; set; } = 1;
-
- public string GetDisplayText()
- {
- return "行:" + PicRows.ToString() + "列:" + PicCols.ToString();
- }
- }
-
- //public class RelatedCamera
- //{
-
- // [Category("关联相机")]
- // [DisplayName("关联相机")]
- // [Description("关联相机描述")]
- // //[TypeConverter(typeof(DeviceIdSelectorConverter))]
- // //[TypeConverter(typeof(CollectionCountConvert))]
- // public string CameraSourceId { get; set; } = "";
-
-
- // //public string GetDisplayText()
- // //{
- // // using (var scope = GlobalVar.Container.BeginLifetimeScope())
- // // {
- // // List deviceList = scope.Resolve>();
- // // IDevice CameraDevice = deviceList.FirstOrDefault(dev => dev.Id.Equals(CameraSourceId));
-
- // // if (CameraDevice != null && CameraDevice is CameraBase)
- // // {
- // // return CameraDevice.Name;
- // // }
-
- // // }
- // // return CameraSourceId;
- // //}
- //}
- public class VisionEngineInitialConfigBase //: InitialConfigBase
- {
- [Category("深度学习检测配置")]
- [DisplayName("检测配置集合")]
- [Description("检测配置集合")]
- //[TypeConverter(typeof(CollectionCountConvert))]
- //[Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))]
- public List DetectionConfigs { get; set; } = new List();
-
- [Category("深度学习检测配置")]
- [DisplayName("标签分类")]
- [Description("标签分类,A_NG,B_TBD...")]
- // [TypeConverter(typeof(CollectionCountConvert))]
- // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))]
- public List RecongnitionLabelCategoryList { get; set; } = new List();
-
- [Category("深度学习检测配置")]
- [DisplayName("检测标签定义集合")]
- [Description("定义检测标签的集合,例如:Seg/Detection模式:断裂、油污、划伤...;Class模式:ok、ng、上面、下面、套环、正常...")]
- // [TypeConverter(typeof(CollectionCountConvert))]
- // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))]
- public List RecongnitionLabelList { get; set; } = new List();
-
- [Category("深度学习检测配置")]
- [DisplayName("标签置信度")]
- [Description("标签置信度,过滤小于改置信度的标签,大于该设置的标签才能识别")]
- public float Score { get; set; } = 0.5f;
-
- [Category("深度学习检测配置")]
- [DisplayName("CPU线程数量")]
- [Description("用于深度学习的CPU线程数量,不要设置太大,会单独占用线程,影响其他程序运行")]
- public int CPUNums { get; set; } = 1;
-
- //[Category("深度学习检测配置")]
- //[DisplayName("检测项GPU指定")]
- //[Description("将检测项指定到GPU")]
- // [TypeConverter(typeof(CollectionCountConvert))]
- // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))]
- // public List DetectionGPUList { get; set; } = new List();
-
- // [Category("数据保存配置")]
- //[DisplayName("是否保存检测明细CSV")]
- //[Description("是否保存 检测明细CSV")]
- //public override bool IsEnableCSV { get; set; } = true;
-
- //[Category("数据保存配置")]
- //[DisplayName("是否保存检测图片")]
- //[Description("是否保存 检测图片,总开关")]
- //public bool IsSaveImage { get; set; } = true;
-
- //[Category("数据保存配置")]
- //[Description("检测图片 保存文件夹")]
- //[DisplayName("检测图片保存文件夹")]
- //[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
- //public string ImageSaveDirectory { get; set; } = "D:\\PROJECTS\\X017\\Images";
-
- //[Category("数据保存配置")]
- //[Description("检测明细CSV文件夹")]
- //[DisplayName("检测明细CSV文件夹")]
- //[Editor(typeof(FoldDialogEditor), typeof(UITypeEditor))]
- //public string CSVDataPath { get; set; } = "D:\\PROJECTS\\X017\\Images";
-
- }
-}
-
-
-
-
-
diff --git a/DH.Commons.Devies/DH.Commons.Devies.csproj b/DH.Commons.Devies/DH.Commons.Devies.csproj
index 64a8d06..bbfb35a 100644
--- a/DH.Commons.Devies/DH.Commons.Devies.csproj
+++ b/DH.Commons.Devies/DH.Commons.Devies.csproj
@@ -21,6 +21,7 @@
+
diff --git a/DH.Commons.Devies/Base/CameraBase.cs b/DH.Commons/Base/CameraBase.cs
similarity index 72%
rename from DH.Commons.Devies/Base/CameraBase.cs
rename to DH.Commons/Base/CameraBase.cs
index 4aa04c3..047f788 100644
--- a/DH.Commons.Devies/Base/CameraBase.cs
+++ b/DH.Commons/Base/CameraBase.cs
@@ -2,36 +2,92 @@
using System.ComponentModel;
using System.Drawing.Imaging;
using AntdUI;
+using DH.Commons.Enums;
+using DVPCameraType;
+using HalconDotNet;
using OpenCvSharp;
-namespace DH.Devices.Devices
+namespace DH.Commons.Base
{
+ public class MatSet
+ {
+ public DateTime ImageTime { get; set; } = DateTime.Now;
+
+ private string id = "";
+ public string Id
+ {
+ get
+ {
+ if (string.IsNullOrWhiteSpace(id))
+ {
+ id = ImageTime.ToString("HHmmssfff");
+ }
+ return id;
+ }
+ set
+ {
+ id = value;
+ }
+ }
+ public string CameraId { get; set; }
+ public Mat _mat { get; set; } = null;
+
+ public ImageFormat _imageFormat { get; set; } = ImageFormat.Jpeg;
+ public virtual void Dispose()
+ {
+ _mat?.Dispose();
+ _mat = null;
+
+ }
+ }
public class CameraBase : NotifyProperty
{
+
+ // public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
+
// 私有字段 + 带通知的属性(与DetectionLabel风格一致)
private bool _isEnabled = false;
+ private bool _isallPicEnabled = true;//默认全画幅
+ private bool _isRGBEnabled = true;//默认彩色
private bool _isContinueMode = false;
private bool _isSavePicEnabled = false;
+ private bool _isZoomCamera = false;
private string _imageSaveDirectory;
+ private EnumCamType _CamType;
+ private dvpStreamFormat _dvpstreamFormat = dvpStreamFormat.S_RGB24;
private ImageFormat _imageFormat = ImageFormat.Jpeg;
- private bool _isHardwareTrigger = false;
+ private bool _isHardwareTrigger = true;
private string _serialNumber = string.Empty;
private string _cameraName = string.Empty;
private string _cameraIP = string.Empty;
private string _computerIP = string.Empty;
private bool _isDirectHardwareTrigger = false;
- private float _gain = -1;
- private float _rotateImage = 0;
+ private float _gain =6;
+ private int _rotateImage = 0;
private float _exposure = 200;
private float _triggerDelay = 0;
private decimal _roiX = 0;
private decimal _roiY = 0;
- private decimal _roiW = 0;
- private decimal _roiH = 0;
+ private decimal _roiW = 2448;
+ private decimal _roiH = 2048;
private int _lineDebouncerTime = 0;
public volatile int SnapshotCount = 0;
+ [Category("相机设置")]
+ [DisplayName("图像格式")]
+ [Description("相机采集图像格式")]
+ public dvpStreamFormat DvpImageFormat
+ {
+ get => _dvpstreamFormat;
+ set
+ {
+ if (_dvpstreamFormat == value) return;
+ _dvpstreamFormat = value;
+ OnPropertyChanged(nameof(DvpImageFormat));
+ }
+ }
+
[Category("采图模式")]
[DisplayName("连续模式")]
[Description("是否连续模式。true:连续模式采图;false:触发模式采图")]
@@ -45,6 +101,16 @@ namespace DH.Devices.Devices
OnPropertyChanged(nameof(IsContinueMode));
}
}
+ public bool IsZoomCamera
+ {
+ get => _isZoomCamera;
+ set
+ {
+ if (_isZoomCamera == value) return;
+ _isZoomCamera = value;
+ OnPropertyChanged(nameof(IsZoomCamera));
+ }
+ }
public virtual bool IsEnabled
{
@@ -56,7 +122,16 @@ namespace DH.Devices.Devices
OnPropertyChanged(nameof(IsEnabled));
}
}
-
+ public virtual bool IsAllPicEnabled
+ {
+ get => _isallPicEnabled;
+ set
+ {
+ if (_isallPicEnabled == value) return;
+ _isallPicEnabled = value;
+ OnPropertyChanged(nameof(IsAllPicEnabled));
+ }
+ }
public virtual bool IsSavePicEnabled
{
get => _isSavePicEnabled;
@@ -95,6 +170,19 @@ namespace DH.Devices.Devices
OnPropertyChanged(nameof(ImageFormat));
}
}
+ [Category("设备配置")]
+ [DisplayName("相机类型")]
+ [Description("相机类型")]
+ public EnumCamType CamType
+ {
+ get => _CamType;
+ set
+ {
+ if (_CamType == value) return;
+ _CamType = value;
+ OnPropertyChanged(nameof(CamType));
+ }
+ }
[Category("采图模式")]
[DisplayName("硬触发")]
@@ -185,7 +273,7 @@ namespace DH.Devices.Devices
[Category("图像旋转")]
[DisplayName("默认旋转")]
[Description("默认旋转,相机开启后默认不旋转")]
- public virtual float RotateImage
+ public virtual int RotateImage
{
get => _rotateImage;
set
@@ -283,7 +371,18 @@ namespace DH.Devices.Devices
}
// 其他方法保持原有逻辑
- public Action OnHImageOutput { get; set; }
+ public MatSet CopyImageSet(MatSet srcSet)
+ {
+ MatSet imageSet = new MatSet
+ {
+ Id = srcSet.Id,
+ _mat = srcSet._mat.Clone(),
+ // ImageSaveOption = srcSet.ImageSaveOption.Copy(),
+ ImageTime = srcSet.ImageTime
+ };
+ return imageSet;
+ }
+ public Action OnHImageOutput { get; set; }
public virtual bool CameraConnect() { return false; }
diff --git a/DH.Commons/DetectionConfig.cs b/DH.Commons/Base/DetectionConfig.cs
similarity index 68%
rename from DH.Commons/DetectionConfig.cs
rename to DH.Commons/Base/DetectionConfig.cs
index 85f20b4..8b56293 100644
--- a/DH.Commons/DetectionConfig.cs
+++ b/DH.Commons/Base/DetectionConfig.cs
@@ -9,27 +9,14 @@ using AntdUI;
using System.Text.Json.Serialization;
using static DH.Commons.Enums.EnumHelper;
-using System.Collections.ObjectModel;
+using System.Text.Json.Serialization;
+using DH.Commons.Enums;
+using System.Drawing.Imaging;
-
-namespace DH.Commons.Enums
+namespace DH.Commons.Base
{
- public enum MLModelType
- {
- [Description("图像分类")]
- ImageClassification = 1,
- [Description("目标检测")]
- ObjectDetection = 2,
- //[Description("图像分割")]
- //ImageSegmentation = 3
- [Description("语义分割")]
- SemanticSegmentation = 3,
- [Description("实例分割")]
- InstanceSegmentation = 4,
- [Description("目标检测GPU")]
- ObjectGPUDetection = 5
- }
- public class ModelLabel
+
+ public class ModelLabel
{
public string LabelId { get; set; }
@@ -45,7 +32,7 @@ namespace DH.Commons.Enums
[Description("模型识别的标签名称")]
public string LabelName { get; set; }
-
+
//[Category("模型配置")]
@@ -74,28 +61,28 @@ namespace DH.Commons.Enums
//public int ImageResizeCount;
public bool IsCLDetection;
public int ProCount;
- public string in_node_name;
+ public string in_node_name;
- public string out_node_name;
+ public string out_node_name;
- public string in_lable_path;
+ public string in_lable_path;
public int ResizeImageSize;
public int segmentWidth;
public int ImageWidth;
- // public List OkClassTxtList;
+ // public List OkClassTxtList;
- public List LabelNames;
+ public List LabelNames;
+
-
}
public enum ResultState
{
-
+
[Description("检测NG")]
DetectNG = -3,
@@ -120,20 +107,20 @@ namespace DH.Commons.Enums
///
public class DetectionResultDetail
{
-
+
public string LabelBGR { get; set; }//识别到对象的标签BGR
public int LabelNo { get; set; } // 识别到对象的标签索引
-
+
public string LabelName { get; set; }//识别到对象的标签名称
public double Score { get; set; }//识别目标结果的可能性、得分
-
+
public string LabelDisplay { get; set; }//识别到对象的 显示信息
@@ -154,10 +141,10 @@ namespace DH.Commons.Enums
public class MLResult
{
public bool IsSuccess = false;
-
+
public string ResultMessage;
-
+
public Bitmap ResultMap;
public List ResultDetails = new List();
@@ -181,8 +168,7 @@ namespace DH.Commons.Enums
public bool IsGPU;
public int GPUId;
public float Score_thre;
-
-
+
public MLInit(string modelFile, bool isGPU, int gpuId, float score_thre)
@@ -205,31 +191,48 @@ namespace DH.Commons.Enums
}
}
- public class DetectStationResult
+ public class DetectStationResult
{
-
+ public DateTime ImageTime { get; set; } = DateTime.Now;
+
+ private string id = "";
+ public string Id
+ {
+ get
+ {
+ if (string.IsNullOrWhiteSpace(id))
+ {
+ id = ImageTime.ToString("HHmmssfff");
+ }
+ return id;
+ }
+ set
+ {
+ id = value;
+ }
+ }
public string Pid { get; set; }
-
-
- public string TempPid { get; set; }
+ public string TempPid { get; set; }
///
/// 检测工位名称
///
-
public string DetectName { get; set; }
-
+
///
/// 深度学习 检测结果
///
public List DetectDetails = new List();
public List DetectionResultShapes = new List();
-
-
+ ///
+ /// 视觉测量结果集合
+ ///
+
+ public List realSpecs { get; set; } = new List();
///
/// 工位检测结果
///
@@ -254,36 +257,25 @@ namespace DH.Commons.Enums
/// 预处理阶段已经NG
///
public bool IsPreTreatNG { get; set; } = false;
-
+ ///
+ /// 检测原图
+ ///
+ public Bitmap DetectionOriginImage { get; set; }
///
/// 目标检测NG
///
public bool IsObjectDetectNG { get; set; } = false;
-
+ public ImageFormat ImageFormat { get; set; } = ImageFormat.Jpeg;
public DateTime EndTime { get; set; }
+ public string ImageSaveDirectory { get; set; }
public int StationDetectElapsed { get; set; }
- public static string NormalizeAndClean(string input)
- {
-#pragma warning disable CS8603 // 可能返回 null 引用
- if (input == null) return null;
-#pragma warning restore CS8603 // 可能返回 null 引用
+ public bool SaveOKOriginal = false;
+ public bool SaveNGOriginal = false;
+ public bool SaveOKDetect = false;
+ public bool SaveNGDetect = false;
- // Step 1: 标准化字符编码为 Form C (规范组合)
- string normalizedString = input.Normalize(NormalizationForm.FormC);
- // Step 2: 移除所有空白字符,包括制表符和换行符
- string withoutWhitespace = Regex.Replace(normalizedString, @"\s+", "");
-
- // Step 3: 移除控制字符 (Unicode 控制字符,范围 \u0000 - \u001F 和 \u007F)
- string withoutControlChars = Regex.Replace(withoutWhitespace, @"[\u0000-\u001F\u007F]+", "");
-
- // Step 4: 移除特殊的不可见字符(如零宽度空格等)
- string cleanedString = Regex.Replace(withoutControlChars, @"[\u200B\u200C\u200D\uFEFF]+", "");
-
- return cleanedString;
- }
-
}
public class RelatedCamera : NotifyProperty
{
@@ -406,7 +398,7 @@ namespace DH.Commons.Enums
public static double GetDistance(CustomizedPoint p1, CustomizedPoint p2)
{
- return Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2));
+ return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
}
public override string ToString()
@@ -447,13 +439,13 @@ namespace DH.Commons.Enums
public int CompareTo(CustomizedPoint other)
{
- return (X == other.X && Y == other.Y) ? 0 : 1;
+ return X == other.X && Y == other.Y ? 0 : 1;
}
public override int GetHashCode()
{
//return (int)(X * 10 + Y);
- return (new Tuple(X, Y)).GetHashCode();
+ return new Tuple(X, Y).GetHashCode();
}
public static CustomizedPoint operator -(CustomizedPoint p1, CustomizedPoint p2)
@@ -476,7 +468,7 @@ namespace DH.Commons.Enums
// [Category("预处理参数")]
// [DisplayName("参数名称")]
// [Description("参数名称")]
- //
+ //#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
// public string Name { get; set; }
@@ -488,7 +480,7 @@ namespace DH.Commons.Enums
// [Category("预处理参数")]
// [DisplayName("参数值")]
// [Description("参数值")]
- //
+ //#pragma warning disable CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
// public string Value { get; set; }
@@ -496,48 +488,135 @@ namespace DH.Commons.Enums
// }
public class DetectionConfig : NotifyProperty
{
- #region 基本信息
- [JsonPropertyName("id")]
+ #region 属性字段
+ private string _id = Guid.NewGuid().ToString();
+ private string _name;
+ private EnumDetectionType _detectionType= EnumDetectionType.深度学习;
+ private string _cameraSourceId = "";
+ private List _cameraCollects = new List();
+ private bool _isEnableGPU;
+ private bool _isMixModel;
+ private bool _isPreEnabled;
+ private bool _isEnabled;
+ private bool _isAddStation = true;
+ private string _halconAlgorithemPath_Pre;
+ private AntList _preTreatParams = new AntList();
+ private AntList _outPreTreatParams = new AntList();
+ private ModelType _modelType = ModelType.目标检测;
+ private string _modelPath;
+ private int _modelWidth = 640;
+ private int _modelHeight = 640;
+ private string _modeloutNodeName = "output0";
+ private float _modelconfThreshold = 0.5f;
+ private string _in_lable_path;
+ private AntList _detectionLableList = new AntList();
+ private AntList _sizeTreatParamList = new AntList();
+
+ private CustomizedPoint _showLocation = new CustomizedPoint();
+ private string _imageSaveDirectory= "D://PROJECTS//Images//";
+ private bool _saveOKOriginal = false;
+ private bool _saveNGOriginal = false;
+ private bool _saveOKDetect = false;
+ private bool _saveNGDetect = false;
+
+ #endregion
+
+ #region 属性声明
[ReadOnly(true)]
- public string Id { get; private set; } = Guid.NewGuid().ToString();
+ public string Id
+ {
+ get => _id;
+ set
+ {
+ if (_id == value) return;
+ _id = value;
+ OnPropertyChanged(nameof(Id));
+ }
+ }
[Category("检测配置")]
[DisplayName("检测配置名称")]
[Description("检测配置名称")]
- [JsonPropertyName("name")]
- public string Name { get; set; }
-
- #endregion
-
- #region 相机配置
- [Category("关联相机")]
- [DisplayName("关联相机")]
- [Description("关联相机描述")]
- [JsonPropertyName("camera_source_id")]
- public string CameraSourceId { get; set; } = "";
+ public string Name
+ {
+ get => _name;
+ set
+ {
+ if (_name == value) return;
+ _name = value;
+ OnPropertyChanged(nameof(Name));
+ }
+ }
[Category("关联相机集合")]
[DisplayName("关联相机集合")]
[Description("关联相机描述")]
- [JsonPropertyName("camera_Collects")]
- public List CameraCollects { get; set; } = new();
- #endregion
+ public List CameraCollects
+ {
+ get => _cameraCollects;
+ set
+ {
+ if (_cameraCollects == value) return;
+ _cameraCollects = value;
+ OnPropertyChanged(nameof(CameraCollects));
+ }
+ }
- #region 启用选项
[Category("启用配置")]
[DisplayName("是否启用GPU检测")]
- [JsonPropertyName("is_enable_gpu")]
- public bool IsEnableGPU { get; set; }
+ [Description("是否启用GPU检测")]
+ public bool IsEnableGPU
+ {
+ get => _isEnableGPU;
+ set
+ {
+ if (_isEnableGPU == value) return;
+ _isEnableGPU = value;
+ OnPropertyChanged(nameof(IsEnableGPU));
+ }
+ }
[Category("启用配置")]
[DisplayName("是否混料模型")]
- [JsonPropertyName("is_mixModel")]
- public bool IsMixModel { get; set; }
+ [Description("是否混料模型")]
+ public bool IsMixModel
+ {
+ get => _isMixModel;
+ set
+ {
+ if (_isMixModel == value) return;
+ _isMixModel = value;
+ OnPropertyChanged(nameof(IsMixModel));
+ }
+ }
+
+ [Category("启用配置")]
+ [DisplayName("是否启用预处理")]
+ [Description("是否启用预处理")]
+ public bool IsPreEnabled
+ {
+ get => _isPreEnabled;
+ set
+ {
+ if (_isPreEnabled == value) return;
+ _isPreEnabled = value;
+ OnPropertyChanged(nameof(IsPreEnabled));
+ }
+ }
[Category("启用配置")]
[DisplayName("是否启用该检测")]
- [JsonPropertyName("is_enabled")]
- public bool IsEnabled { get; set; }
+ [Description("是否启用该检测")]
+ public bool IsEnabled
+ {
+ get => _isEnabled;
+ set
+ {
+ if (_isEnabled == value) return;
+ _isEnabled = value;
+ OnPropertyChanged(nameof(IsEnabled));
+ }
+ }
[Category("启用配置")]
[DisplayName("是否启用预处理")]
@@ -548,133 +627,293 @@ namespace DH.Commons.Enums
private bool _isAddStation;
[Category("启用配置")]
[DisplayName("是否加入检测工位")]
- [JsonPropertyName("is_addstation")]
+ [Description("是否加入检测工位")]
public bool IsAddStation
{
get => _isAddStation;
set
{
- if (_isAddStation != value)
- {
- _isAddStation = value;
- OnPropertyChanged(nameof(IsAddStation));
- }
+ if (_isAddStation == value) return;
+ _isAddStation = value;
+ OnPropertyChanged(nameof(IsAddStation));
+ }
+ }
+ [Category("图片保存")]
+ [DisplayName("图片保存文件夹")]
+ [Description("图片保存文件夹")]
+ public virtual string ImageSaveDirectory
+ {
+ get => _imageSaveDirectory;
+ set
+ {
+ if (_imageSaveDirectory == value) return;
+ _imageSaveDirectory = value;
+ OnPropertyChanged(nameof(ImageSaveDirectory));
}
}
- #endregion
-
- #region 预处理(视觉算子)
[Category("1.预处理(视觉算子)")]
[DisplayName("预处理-算法文件路径")]
- [JsonPropertyName("halcon_algorithemPath_pre")]
- public string HalconAlgorithemPath_Pre { get; set; }
+ public string HalconAlgorithemPath_Pre
+ {
+ get => _halconAlgorithemPath_Pre;
+ set
+ {
+ if (_halconAlgorithemPath_Pre == value) return;
+ _halconAlgorithemPath_Pre = value;
+ OnPropertyChanged(nameof(HalconAlgorithemPath_Pre));
+ }
+ }
[Category("1.预处理(视觉算子)")]
[DisplayName("预处理-参数列表")]
- [JsonPropertyName("pre_treatParams")]
- public List PreTreatParams { get; set; } = new();
-
- [Category("1.预处理(视觉算子)")]
- [DisplayName("预处理-输出参数列表")]
- [JsonPropertyName("out_preTreatParams")]
- public List OUTPreTreatParams { get; set; } = new();
- #endregion
-
- #region 深度学习检测
- [Category("2.中检测(深度学习)")]
- [DisplayName("模型类型")]
- [JsonPropertyName("model_Type")]
- public MLModelType ModelType { get; set; } = MLModelType.ObjectDetection;
-
- [Category("2.中检测(深度学习)")]
- [DisplayName("模型文件路径")]
- [JsonPropertyName("model_Path")]
- public string ModelPath { get; set; }
-
- [Category("2.中检测(深度学习)")]
- [DisplayName("模型宽度")]
- [JsonPropertyName("model_Width")]
- public int ModelWidth { get; set; } = 640;
-
- [Category("2.中检测(深度学习)")]
- [DisplayName("模型高度")]
- [JsonPropertyName("model_Height")]
- public int ModelHeight { get; set; } = 640;
-
- [Category("2.中检测(深度学习)")]
- [DisplayName("模型节点名称")]
- [JsonPropertyName("model_outNodeName")]
- public string ModeloutNodeName { get; set; } = "output0";
-
- [Category("2.中检测(深度学习)")]
- [DisplayName("模型置信度")]
- [JsonPropertyName("model_confThreshold")]
- public float ModelconfThreshold { get; set; } = 0.5f;
-
- [Category("2.中检测(深度学习)")]
- [DisplayName("模型标签路径")]
- [JsonPropertyName("in_lablepath")]
- public string in_lable_path { get; set; }
- #endregion
-
- #region 尺寸测量
-
- // public List PreTreatCollects { get; set; } = new();
- private List _preTreatParams = new();
-
- [Category("1.尺寸测量集合")]
- [DisplayName("尺寸测量集合")]
- [JsonPropertyName("Pre_TreatCollects")]
- public List PreTreatCollects
+ [Description("预处理-参数列表")]
+ public AntList PreTreatParams
{
get => _preTreatParams;
set
{
- if (_preTreatParams != value)
- {
- _preTreatParams = value;
- OnPropertyChanged(nameof(PreTreatCollects));
-
- }
+ if (_preTreatParams == value) return;
+ _preTreatParams = value;
+ OnPropertyChanged(nameof(PreTreatParams));
}
}
- #endregion
+ [Category("1.预处理(视觉算子)")]
+ [DisplayName("预处理-输出参数列表")]
+ [Description("预处理-输出参数列表")]
+ public AntList OUTPreTreatParams
+ {
+ get => _outPreTreatParams;
+ set
+ {
+ if (_outPreTreatParams == value) return;
+ _outPreTreatParams = value;
+ OnPropertyChanged(nameof(OUTPreTreatParams));
+ }
+ }
- #region 过滤器
- [Category("4.最终过滤(逻辑过滤)")]
- [DisplayName("过滤器集合")]
- [JsonPropertyName("detection_filterList")]
- public List DetectionFilterList { get; set; } = new();
- #endregion
+ [Category("2.中检测(深度学习)")]
+ [DisplayName("中检测-模型类型")]
+ [Description("模型类型:ImageClassification-图片分类;ObjectDetection:目标检测;Segmentation-图像分割")]
+ public ModelType ModelType
+ {
+ get => _modelType;
+ set
+ {
+ if (_modelType == value) return;
+ _modelType = value;
+ OnPropertyChanged(nameof(ModelType));
+ }
+ }
- #region 其他信息
- [JsonPropertyName("Detection_LableList")]
- public List DetectionLableList { get; set; } = new();
+ [Category("2.中检测(深度学习)")]
+ [DisplayName("中检测-模型文件路径")]
+ [Description("中处理 深度学习模型文件路径")]
+ public string ModelPath
+ {
+ get => _modelPath;
+ set
+ {
+ if (_modelPath == value) return;
+ _modelPath = value;
+ OnPropertyChanged(nameof(ModelPath));
+ }
+ }
+
+ [Category("2.中检测(深度学习)")]
+ [DisplayName("中检测-模型宽度")]
+ [Description("中处理-模型宽度")]
+ public int ModelWidth
+ {
+ get => _modelWidth;
+ set
+ {
+ if (_modelWidth == value) return;
+ _modelWidth = value;
+ OnPropertyChanged(nameof(ModelWidth));
+ }
+ }
+
+ [Category("2.中检测(深度学习)")]
+ [DisplayName("中检测-模型高度")]
+ [Description("中处理-模型高度")]
+ public int ModelHeight
+ {
+ get => _modelHeight;
+ set
+ {
+ if (_modelHeight == value) return;
+ _modelHeight = value;
+ OnPropertyChanged(nameof(ModelHeight));
+ }
+ }
+
+ [Category("2.中检测(深度学习)")]
+ [DisplayName("中检测-模型节点名称")]
+ [Description("中处理-模型节点名称")]
+ public string ModeloutNodeName
+ {
+ get => _modeloutNodeName;
+ set
+ {
+ if (_modeloutNodeName == value) return;
+ _modeloutNodeName = value;
+ OnPropertyChanged(nameof(ModeloutNodeName));
+ }
+ }
+
+ [Category("2.中检测(深度学习)")]
+ [DisplayName("中检测-模型置信度")]
+ [Description("中处理-模型置信度")]
+ public float ModelconfThreshold
+ {
+ get => _modelconfThreshold;
+ set
+ {
+ if (_modelconfThreshold == value) return;
+ _modelconfThreshold = value;
+ OnPropertyChanged(nameof(ModelconfThreshold));
+ }
+ }
+
+ [Category("2.中检测(深度学习)")]
+ [DisplayName("中检测-模型标签路径")]
+ [Description("中处理-模型标签路径")]
+ public string In_lable_path
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(ModelPath) || string.IsNullOrWhiteSpace(ModelPath))
+ {
+ return string.Empty;
+ }
+
+ string dir = Path.GetDirectoryName(ModelPath);
+ string file = $"{Path.GetFileNameWithoutExtension(ModelPath)}.txt";
+ return Path.Combine(dir, file);
+ }
+ set
+ {
+ if (_in_lable_path == value) return;
+ _in_lable_path = value;
+ OnPropertyChanged(nameof(In_lable_path));
+ }
+ }
+
+ [Category("检测配置")]
+ [DisplayName("检测类型")]
+ [Description("检测类型")]
+ public EnumDetectionType DetectionType
+ {
+ get => _detectionType;
+ set
+ {
+ if (_detectionType == value) return;
+ _detectionType = value;
+ OnPropertyChanged(nameof(DetectionType));
+ }
+ }
[Category("显示配置")]
[DisplayName("显示位置")]
- [JsonPropertyName("Show_Location")]
- public CustomizedPoint ShowLocation { get; set; } = new();
- #endregion
- //public event PropertyChangedEventHandler PropertyChanged;
+ [Description("检测信息显示位置")]
+ public CustomizedPoint ShowLocation
+ {
+ get => _showLocation;
+ set
+ {
+ if (_showLocation == value) return;
+ _showLocation = value;
+ OnPropertyChanged(nameof(ShowLocation));
+ }
+ }
- //protected virtual void OnPropertyChanged(string propertyName)
- //{
- // PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
- //}
+ ///
+ /// 标签集合(需确保DetectionLable也实现INotifyPropertyChanged)
+ ///
+ public AntList DetectionLableList
+ {
+ get => _detectionLableList;
+ set
+ {
+ if (_detectionLableList == value) return;
+ _detectionLableList = value;
+ OnPropertyChanged(nameof(DetectionLableList));
+ }
+ }
+
+ public AntList SizeTreatParamList
+ {
+ get => _sizeTreatParamList;
+ set
+ {
+ if (_sizeTreatParamList == value) return;
+ _sizeTreatParamList = value;
+ OnPropertyChanged(nameof(SizeTreatParamList));
+ }
+ }
+
+
+ public bool SaveOKOriginal
+ {
+ get => _saveOKOriginal;
+ set
+ {
+ if (_saveOKOriginal == value) return;
+ _saveOKOriginal = value;
+ OnPropertyChanged(nameof(SaveOKOriginal));
+ }
+ }
+
+ public bool SaveNGOriginal
+ {
+ get => _saveNGOriginal;
+ set
+ {
+ if (_saveNGOriginal == value) return;
+ _saveNGOriginal = value;
+ OnPropertyChanged(nameof(SaveNGOriginal));
+ }
+ }
+ public bool SaveOKDetect
+ {
+ get => _saveOKDetect;
+ set
+ {
+ if (_saveOKDetect == value) return;
+ _saveOKDetect = value;
+ OnPropertyChanged(nameof(SaveOKDetect));
+ }
+ }
+ public bool SaveNGDetect
+ {
+ get => _saveNGDetect;
+ set
+ {
+ if (_saveNGDetect == value) return;
+ _saveNGDetect = value;
+ OnPropertyChanged(nameof(SaveNGDetect));
+ }
+ }
+ #endregion
#region 构造函数
public DetectionConfig() { }
- public DetectionConfig(string name, MLModelType modelType, string modelPath, bool isEnableGPU, string sCameraSourceId)
+ public DetectionConfig(
+ string name,
+ ModelType modelType,
+ string modelPath,
+ bool isEnableGPU,
+ string sCameraSourceId)
{
+ // 通过属性赋值触发通知
+ ModelPath = modelPath ?? string.Empty;
Name = name;
ModelType = modelType;
ModelPath = modelPath ?? string.Empty;
IsEnableGPU = isEnableGPU;
- CameraSourceId = sCameraSourceId;
- Id = Guid.NewGuid().ToString();
+
}
#endregion
}
@@ -727,6 +966,7 @@ namespace DH.Commons.Enums
}
private CellLink[] cellLinks;
+ [JsonIgnore]
public CellLink[] CellLinks
{
get {
@@ -747,17 +987,18 @@ namespace DH.Commons.Enums
public class DetectionLable : NotifyProperty
{
private bool _selected = false;
+
private string _labelId;
private string _labelName;
- private double _maxSource;
- private double _minSource;
+ private double _maxScore;
+ private double _minScore;
private double _maxArea;
private double _minArea;
private ResultState _resultState = ResultState.ResultTBD;
-
+
public bool Selected
{
get { return _selected; }
@@ -792,27 +1033,26 @@ namespace DH.Commons.Enums
OnPropertyChanged(nameof(LabelName));
}
}
- [JsonPropertyName("maxSource")]
- public double MaxSource
+
+ public double MaxScore
{
- get { return _maxSource; }
+ get { return _maxScore; }
set
{
- if (_maxSource.Equals(value)) return;
- _maxSource = value;
- OnPropertyChanged(nameof(MaxSource));
+ if (_maxScore.Equals(value)) return;
+ _maxScore = value;
+ OnPropertyChanged(nameof(MaxScore));
}
}
- [JsonPropertyName("minSource")]
- public double MinSource
+ public double MinScore
{
- get { return _minSource; }
+ get { return _minScore; }
set
{
- if (_minSource.Equals(value)) return;
- _minSource = value;
- OnPropertyChanged(nameof(MinSource));
+ if (_minScore.Equals(value)) return;
+ _minScore = value;
+ OnPropertyChanged(nameof(MinScore));
}
}
[JsonPropertyName("maxArea")]
@@ -850,6 +1090,7 @@ namespace DH.Commons.Enums
}
private CellLink[] cellLinks;
+ [JsonIgnore]
public CellLink[] CellLinks
{
get {
@@ -862,6 +1103,15 @@ namespace DH.Commons.Enums
OnPropertyChanged(nameof(CellLinks));
}
}
+
+ public bool FilterOperation(DetectionResultDetail recongnitionResult)
+ {
+
+ double compareValue = recongnitionResult.Area;
+ double compareScoreValue = recongnitionResult.Score;
+ return (compareValue >= MinArea && compareValue <= MaxArea)&& (compareScoreValue >= MinScore && compareScoreValue <= MaxScore);
+
+ }
}
public class PreTreatCollect
{
@@ -999,7 +1249,7 @@ namespace DH.Commons.Enums
_resultShow = value;
OnPropertyChanged(nameof(ResultShow));
}
-
+
}
public string OutResultShow
@@ -1013,19 +1263,20 @@ namespace DH.Commons.Enums
}
}
- //public string PrePath
- //{
- // get { return _prePath; }
- // set
- // {
- // if (_prePath.Equals(value)) return;
- // _prePath = value;
- // OnPropertyChanged(nameof(PrePath));
- // }
- //}
-
+ public string PrePath
+ {
+ get { return _prePath; }
+ set
+ {
+ if (_prePath.Equals(value)) return;
+ _prePath = value;
+ OnPropertyChanged(nameof(PrePath));
+ }
+ }
+
private CellLink[] cellLinks;
+ [JsonIgnore]
public CellLink[] CellLinks
{
get { return cellLinks; }
@@ -1063,9 +1314,9 @@ namespace DH.Commons.Enums
//[TypeConverter(typeof(LabelCategoryConverter))]
public string LabelCategory { get; set; } = "";
-
-
+
+
}
///
@@ -1126,8 +1377,8 @@ namespace DH.Commons.Enums
//public string GetLabelName()
//{
// var name = "";
-
-
+
+
// var mlBase = iConfig.DeviceConfigs.FirstOrDefault(c => c is VisionEngineInitialConfigBase) as VisionEngineInitialConfigBase;
// if (mlBase != null)
// {
@@ -1138,7 +1389,7 @@ namespace DH.Commons.Enums
// }
// }
-
+
// return name;
//}
}
@@ -1199,11 +1450,11 @@ namespace DH.Commons.Enums
[DisplayName("过滤条件集合")]
[Description("过滤条件集合,集合之间为“且”关系")]
//[TypeConverter(typeof(CollectionCountConvert))]
- // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))]
+ // [Editor(typeof(ComplexCollectionEditor), typeof(UITypeEditor))]
public List FilterConditionsCollection { get; set; } = new List();
-
-
+
+
public bool FilterOperation(DetectionResultDetail recongnitionResult)
{
return FilterConditionsCollection.All(u =>
diff --git a/DH.Commons/Base/DeviceBase.cs b/DH.Commons/Base/DeviceBase.cs
new file mode 100644
index 0000000..d1b3b92
--- /dev/null
+++ b/DH.Commons/Base/DeviceBase.cs
@@ -0,0 +1,389 @@
+
+using DH.Commons.Enums;
+using OpenCvSharp.Internal;
+using System;
+using System.ComponentModel;
+using System.IO;
+using System.Text.Json.Serialization;
+using System.Threading;
+using System.Threading.Tasks;
+using static DH.Commons.Enums.EnumHelper;
+using Timer = System.Threading.Timer;
+
+namespace DH.Commons.Base
+{
+ public abstract class DeviceBase : IDisposable
+ {
+ #region Event
+ [JsonIgnore]
+ [Browsable(false)]
+ public Action OnExceptionOccured { get; set; }
+ //public event Action OnLog;
+ public event Action OnLog;
+ // public event Action OnDeviceStateChanged;
+ public event PropertyChangedEventHandler PropertyChanged;
+ #endregion
+
+ #region field
+ int RetryTime = 3;
+ ///
+ /// 和设备暂停状态关联的信号量
+ ///
+ private readonly ManualResetEvent pauseHandle = new ManualResetEvent(true);
+ readonly Timer stateChangedTimer;
+ #endregion
+
+ #region Property
+ #region State
+ private EnumHelper.DeviceState _currentStateToBe = EnumHelper.DeviceState.DSUninit;
+ ///
+ /// 当前设备状态
+ ///
+ [JsonIgnore]
+ internal EnumHelper.DeviceState CurrentStateToBe
+ {
+ get
+ {
+ return _currentStateToBe;
+ }
+ set
+ {
+ if (value != _currentStateToBe)
+ {
+ var initialState = _currentStateToBe;
+ _currentStateToBe = value;
+
+ if (_currentStateToBe != EnumHelper.DeviceState.DSExcept)
+ {
+ // OnStateChanged(initialState);
+ }
+ else
+ {
+ stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
+ }
+ }
+ }
+ }
+
+ //private EnumHelper.DeviceState initialState = EnumHelper.DeviceState.DSUninit;
+ private EnumHelper.DeviceState _currentState = EnumHelper.DeviceState.DSUninit;
+ public EnumHelper.DeviceState CurrentState
+ {
+ get
+ {
+ return _currentState;
+ }
+ set
+ {
+ _currentState = value;
+
+ if (value != EnumHelper.DeviceState.TBD)
+ {
+ // OnDeviceStateChanged?.Invoke(this, _currentState);
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentState"));
+ }
+ //else
+ //{
+ // initialState = _currentState;
+ //}
+ }
+ }
+ #endregion
+
+ ///
+ /// 设备标识符 从数据库获取
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// 设备名称 从数据库获取
+ ///
+ public string Name { get; set; }
+
+ //private IInitialConfig initialConfig = null;
+ /////
+ ///// 设备初始化配置 从数据库获取
+ /////
+ //public virtual IInitialConfig InitialConfig
+ //{
+ // get => initialConfig;
+ // set
+ // {
+ // initialConfig = value;
+ // Id = initialConfig.Id;
+ // Name = initialConfig.Name;
+
+ // LoggerHelper.LogPath = initialConfig.LogPath;
+ // LoggerHelper.LogPrefix = initialConfig.Name;
+ // }
+ //}
+ #endregion
+
+ #region 构造函数
+ public DeviceBase()
+ {
+ RegisterFileWriterException();
+ // stateChangedTimer = new Timer(new TimerCallback(CheckDeviceOpTimeOut), null, Timeout.Infinite, Timeout.Infinite);
+ }
+ #endregion
+
+ #region 设备抽象方法
+ protected virtual void Init()
+ {
+ LogAsync(DateTime.Now, LogLevel.Information, $"{Name}初始化完成");
+ }
+
+
+
+ protected virtual void Start()
+ {
+ LogAsync(DateTime.Now, LogLevel.Information, $"{Name}启动");
+ }
+
+ protected virtual void Stop()
+ {
+ LogAsync(DateTime.Now, LogLevel.Information, $"{Name}停止");
+ }
+
+ //public abstract void AttachToProcess(IProcess process);
+ #endregion
+
+ ///
+ /// 常用操作封装方法
+ ///
+ ///
+ ///
+ //public virtual ResponseMessage RunWrap(IOperationConfig opConfig)
+ //{
+ // ResponseMessage msg = new ResponseMessage();
+ // msg.Message = "设备基类默认操作";
+ // return msg;
+ //}
+
+ #region 状态切换
+ //[DeviceExceptionAspect]
+ //public void StateChange(EnumHelper.DeviceState stateToBe)
+ //{
+ // if (CurrentState == stateToBe)
+ // {
+ // return;
+ // }
+
+ // if (!stateToBe.CheckPreStateValid((int)CurrentStateToBe))
+ // {
+ // string currentStateStr = CurrentStateToBe.GetEnumDescription();
+ // string stateToBeStr = stateToBe.GetEnumDescription();
+ // throw new ProcessException($"{InitialConfig.Name}设备的当前状态为{currentStateStr},无法切换至{stateToBeStr}");
+ // }
+
+ // CurrentState = EnumHelper.DeviceState.TBD;
+ // CurrentStateToBe = stateToBe;
+ //}
+
+ //[DeviceExceptionAspect]
+ //private void OnStateChanged(EnumHelper.DeviceState initialState)
+ //{
+ // try
+ // {
+ // if (CurrentStateToBe != EnumHelper.DeviceState.DSExcept)
+ // {
+ // }
+ // else
+ // {
+ // if (CurrentState == EnumHelper.DeviceState.DSExcept)
+ // {
+ // return;
+ // }
+ // else
+ // {
+ // throw new ProcessException($"{InitialConfig.Name}设备操作超时");
+ // }
+ // }
+
+ // if (RetryTime >= 0)
+ // {
+ // if (initialState == CurrentStateToBe)
+ // {
+ // CurrentState = CurrentStateToBe;
+ // return;
+ // }
+
+ // #region 状态切换操作
+ // switch (CurrentStateToBe)
+ // {
+ // case EnumHelper.DeviceState.DSInit:
+ // if (initialState == EnumHelper.DeviceState.DSOpen)
+ // {
+ // return;
+ // }
+ // else
+ // {
+ // Init();
+ // }
+ // break;
+ // case EnumHelper.DeviceState.DSOpen:
+ // if (initialState == EnumHelper.DeviceState.DSInit)
+ // {
+ // Start();
+ // }
+ // else if (initialState == EnumHelper.DeviceState.DSPause)
+ // {
+ // Resume();
+ // pauseHandle.Set();
+ // }
+ // break;
+ // case EnumHelper.DeviceState.DSPause:
+ // pauseHandle.Reset();
+ // Pause();
+ // break;
+ // case EnumHelper.DeviceState.DSClose:
+ // if (initialState != DeviceState.DSUninit)
+ // {
+ // Stop();
+ // }
+ // break;
+ // default:
+ // break;
+ // }
+
+ // RetryTime = 3;
+ // CurrentState = CurrentStateToBe;
+ // #endregion
+ // }
+
+ // stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
+ // }
+ // catch (Exception ex)
+ // {
+ // RetryTime--;
+ // if (RetryTime > 0)
+ // {
+ // OnStateChanged(initialState);
+ // }
+ // else
+ // {
+ // if (CurrentState != EnumHelper.DeviceState.DSExcept)
+ // {
+ // RetryTime = 3;
+ // throw new ProcessException($"设备{InitialConfig.Name}的{CurrentStateToBe.GetEnumDescription()}操作重复3次失败", ex, ExceptionLevel.Warning);
+ // }
+ // }
+ // }
+ //}
+
+ //private void CheckDeviceOpTimeOut(object state)
+ //{
+ // stateChangedTimer?.Change(Timeout.Infinite, Timeout.Infinite);
+
+ // if (CurrentState != EnumHelper.DeviceState.DSExcept)
+ // {
+ // StateChange(EnumHelper.DeviceState.DSExcept);
+ // }
+ //}
+ #endregion
+
+ #region 日志处理
+ private void RegisterFileWriterException()
+ {
+ LoggerHelper.OnLogExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
+ // CSVHelper.OnCSVExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
+
+ LoggerHelper.OnLogExceptionRaised += LoggerHelper_OnLogExceptionRaised;
+ // CSVHelper.OnCSVExceptionRaised += LoggerHelper_OnLogExceptionRaised;
+ }
+ // public CSVHelper CSVHelper { get; set; } = new CSVHelper();
+
+ public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
+
+ public virtual void LogAsync(LogMsg msg)
+ {
+ msg.MsgSource = Name;
+ msg.ThreadId = Thread.CurrentThread.ManagedThreadId;
+
+ //OnLog?.BeginInvoke(msg, null, null);
+ OnLog?.Invoke(msg);
+
+ //if (InitialConfig.IsEnableLog)
+ //{
+ LoggerHelper.LogAsync(msg);
+ //}
+ }
+
+ public virtual void LogAsync(DateTime dt, LogLevel logLevel, string msg)
+ {
+ LogAsync(new LogMsg(dt, logLevel, msg));
+ }
+ private void LoggerHelper_OnLogExceptionRaised(DateTime dt, string msg)
+ {
+ OnLog?.Invoke(new LogMsg(dt, LogLevel.Error, msg));
+ }
+ ///
+ /// CSV异步数据输出
+ ///
+ /// CSV输出文件的文件全路径
+ /// CSV输出数据
+ /// CSV文件表头
+ public virtual void CSVRecordAsync(string csvFile, string csvData, string csvHead = "")
+ {
+ // CSVHelper.CSVOutputAsync(csvFile, csvData, csvHead);
+ }
+ #endregion
+
+ #region 报警记录
+ //object _alarmLock = new object();
+ //protected virtual async void SaveAlarmCSVAsync(DateTime now, string deviceName, IWarningSet ws)
+ //{
+ // await Task.Run(() =>
+ // {
+ // LogAsync(now, LogLevel.Warning, $"{ws.WarningCode}-{ws.WarningDescription} {(ws.CurrentStatus ? "发生" : "取消")}");
+
+ // if (string.IsNullOrWhiteSpace(this.InitialConfig.LogPath) || !InitialConfig.IsEnableCSV)
+ // return;
+
+ // string path = Path.Combine(InitialConfig.LogPath, $"Alarm_{Name}_{now.ToString("yyyyMMdd")}.csv");
+ // string head = "Time,Source,AlarmCode,AlarmDescription,AlarmStatus";
+ // string data = $"{now.ToString("HH:mm:ss.fff")},{deviceName},{ws.WarningCode},{ws.WarningDescription},{(ws.CurrentStatus ? "报警发生" : "报警取消")}";
+ // CSVRecordAsync(path, data, head);
+ // });
+ //}
+ #endregion
+
+ #region IDisposable Support
+ private bool disposedValue = false; // 要检测冗余调用
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ //释放托管状态(托管对象)。
+ stateChangedTimer?.Dispose();
+ pauseHandle?.Dispose();
+ }
+
+ // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
+ // TODO: 将大型字段设置为 null。
+
+ disposedValue = true;
+ }
+ }
+
+ // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
+ // ~DeviceBase()
+ // {
+ // // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
+ // Dispose(false);
+ // }
+
+ // 添加此代码以正确实现可处置模式。
+ public void Dispose()
+ {
+ // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
+ Dispose(true);
+ // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
+ // GC.SuppressFinalize(this);
+ }
+ #endregion
+ }
+}
diff --git a/DH.Commons/Base/GlobalConfig.cs b/DH.Commons/Base/GlobalConfig.cs
new file mode 100644
index 0000000..50d93b0
--- /dev/null
+++ b/DH.Commons/Base/GlobalConfig.cs
@@ -0,0 +1,169 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using AntdUI;
+
+namespace DH.Commons.Base
+{
+ public class GlobalConfig : NotifyProperty
+ {
+ bool _EnableVibrator=false;
+ bool _EnableBelt = false;
+ int _ClearTime=0;
+ string _name;
+ private BindingList _InitProcessList = new BindingList();
+ private BindingList _StartProcessList = new BindingList();
+ private BindingList _StopProcessList = new BindingList();
+ private BindingList _StartResetList = new BindingList();
+ private BindingList _StopResetList = new BindingList();
+ public string Name
+ {
+ get => _name;
+ set
+ {
+ if (_name != value)
+ {
+ _name = value;
+ OnPropertyChanged(nameof(Name));
+ }
+ }
+ }
+ public bool EnableBelt
+ {
+ get => _EnableBelt;
+ set
+ {
+ if (_EnableBelt != value)
+ {
+ _EnableBelt = value;
+ OnPropertyChanged(nameof(EnableBelt));
+ }
+ }
+ }
+ public bool EnableVibrator
+ {
+ get => _EnableVibrator;
+ set
+ {
+ if (_EnableVibrator != value)
+ {
+ _EnableVibrator = value;
+ OnPropertyChanged(nameof(EnableVibrator));
+ }
+ }
+ }
+ public int ClearTime
+ {
+ get => _ClearTime;
+ set
+ {
+ if (_ClearTime != value)
+ {
+ _ClearTime = value;
+ OnPropertyChanged(nameof(ClearTime));
+ }
+ }
+ }
+ public BindingList InitProcessList
+ {
+ get => _InitProcessList;
+ set
+ {
+ if (_InitProcessList == value) return;
+ _InitProcessList = value;
+ OnPropertyChanged(nameof(InitProcessList));
+ }
+ }
+ public BindingList StartProcessList
+ {
+ get => _StartProcessList;
+ set
+ {
+ if (_StartProcessList == value) return;
+ _StartProcessList = value;
+ OnPropertyChanged(nameof(StartProcessList));
+ }
+ }
+ public BindingList StopProcessList
+ {
+ get => _StopProcessList;
+ set
+ {
+ if (_StopProcessList == value) return;
+ _StopProcessList = value;
+ OnPropertyChanged(nameof(StopProcessList));
+ }
+ }
+ public BindingList StartResetList
+ {
+ get => _StartResetList;
+ set
+ {
+ if (_StartResetList == value) return;
+ _StartResetList = value;
+ OnPropertyChanged(nameof(StartResetList));
+ }
+ }
+ public BindingList StopResetList
+ {
+ get => _StopResetList;
+ set
+ {
+ if (_StopResetList == value) return;
+ _StopResetList = value;
+ OnPropertyChanged(nameof(StopResetList));
+ }
+ }
+
+
+ string _imgSavePath;
+ string _dbSavePath;
+ string _configSavePath;
+
+ public string ImgSavePath
+ {
+ get => _imgSavePath;
+ set
+ {
+ if (_imgSavePath != value)
+ {
+ _imgSavePath = value;
+ OnPropertyChanged(nameof(ImgSavePath));
+ }
+ }
+ }
+
+ public string DbSavePath
+ {
+ get => _dbSavePath;
+ set
+ {
+ if (_dbSavePath != value)
+ {
+ _dbSavePath = value;
+ OnPropertyChanged(nameof(DbSavePath));
+ }
+ }
+ }
+
+ public string ConfigSavePath
+ {
+ get => _configSavePath;
+ set
+ {
+ if (_configSavePath != value)
+ {
+ _configSavePath = value;
+ OnPropertyChanged(nameof(ConfigSavePath));
+ }
+ }
+ }
+ }
+
+
+
+}
diff --git a/DH.Commons/Base/PLCBase.cs b/DH.Commons/Base/PLCBase.cs
new file mode 100644
index 0000000..d6e890f
--- /dev/null
+++ b/DH.Commons/Base/PLCBase.cs
@@ -0,0 +1,378 @@
+using System.ComponentModel;
+using System.IO.Ports;
+using System.Text.Json.Serialization;
+using AntdUI;
+using DH.Commons.Enums; // 请确保此命名空间包含EnumPLCType
+
+namespace DH.Commons.Base
+{
+ public class PLCBase : NotifyProperty
+ {
+
+ // 私有字段
+ private bool _enable;
+ private bool _connected;
+ private string _plcName;
+ private EnumPLCType _plcType;
+ private string _com = "COM1";
+ private int _baudRate = 9600;
+ private int _dataBit = 8;
+ private StopBits _stopBit = StopBits.One;
+ private Parity _parity = Parity.None;
+ private string _ip = "192.168.6.61";
+ private int _port = 502;
+ private BindingList _PLCItemList = new BindingList();
+
+ [Category("设备配置")]
+ [DisplayName("是否启用")]
+ [Description("是否启用")]
+ public bool Enable
+ {
+ get => _enable;
+ set
+ {
+ if (_enable == value) return;
+ _enable = value;
+ OnPropertyChanged(nameof(Enable));
+ }
+ }
+
+
+ [Category("状态监控")]
+ [DisplayName("连接状态")]
+ [Description("PLC连接状态")]
+ public bool Connected
+ {
+ get => _connected;
+ set
+ {
+ if (_connected == value) return;
+ _connected = value;
+ OnPropertyChanged(nameof(Connected));
+ }
+ }
+
+ [Category("设备配置")]
+ [DisplayName("PLC名称")]
+ [Description("PLC设备名称")]
+ public string PLCName
+ {
+ get => _plcName;
+ set
+ {
+ if (_plcName == value) return;
+ _plcName = value;
+ OnPropertyChanged(nameof(PLCName));
+ }
+ }
+
+ [Category("设备配置")]
+ [DisplayName("PLC类型")]
+ [Description("PLC通信协议类型")]
+ public EnumPLCType PLCType
+ {
+ get => _plcType;
+ set
+ {
+ if (_plcType == value) return;
+ _plcType = value;
+ OnPropertyChanged(nameof(PLCType));
+ }
+ }
+
+ [Category("串口配置")]
+ [DisplayName("COM端口")]
+ [Description("串口号,如COM1")]
+ public string COM
+ {
+ get => _com;
+ set
+ {
+ if (_com == value) return;
+ _com = value;
+ OnPropertyChanged(nameof(COM));
+ }
+ }
+
+ [Category("串口配置")]
+ [DisplayName("波特率")]
+ [Description("串口通信波特率")]
+ public int BaudRate
+ {
+ get => _baudRate;
+ set
+ {
+ if (_baudRate == value) return;
+ _baudRate = value;
+ OnPropertyChanged(nameof(BaudRate));
+ }
+ }
+
+ [Category("串口配置")]
+ [DisplayName("数据位")]
+ [Description("数据位长度(5/6/7/8)")]
+ public int DataBit
+ {
+ get => _dataBit;
+ set
+ {
+ if (_dataBit == value) return;
+ _dataBit = value;
+ OnPropertyChanged(nameof(DataBit));
+ }
+ }
+
+ [Category("串口配置")]
+ [DisplayName("停止位")]
+ [Description("停止位设置")]
+ public StopBits StopBit
+ {
+ get => _stopBit;
+ set
+ {
+ if (_stopBit == value) return;
+ _stopBit = value;
+ OnPropertyChanged(nameof(StopBit));
+ }
+ }
+
+ [Category("串口配置")]
+ [DisplayName("校验位")]
+ [Description("奇偶校验方式")]
+ public Parity Parity
+ {
+ get => _parity;
+ set
+ {
+ if (_parity == value) return;
+ _parity = value;
+ OnPropertyChanged(nameof(Parity));
+ }
+ }
+
+ [Category("网络配置")]
+ [DisplayName("IP地址")]
+ [Description("PLC网络地址")]
+ public string IP
+ {
+ get => _ip;
+ set
+ {
+ if (_ip == value) return;
+ _ip = value;
+ OnPropertyChanged(nameof(IP));
+ }
+ }
+
+ [Category("网络配置")]
+ [DisplayName("端口号")]
+ [Description("网络通信端口")]
+ public int Port
+ {
+ get => _port;
+ set
+ {
+ if (_port == value) return;
+ _port = value;
+ OnPropertyChanged(nameof(Port));
+ }
+ }
+
+ [Category("点位配置")]
+ [DisplayName("点位配置")]
+ [Description("点位配置")]
+ public BindingList PLCItemList
+ {
+ get => _PLCItemList;
+ set
+ {
+ if (_PLCItemList == value) return;
+ _PLCItemList = value;
+ OnPropertyChanged(nameof(PLCItemList));
+ }
+ }
+
+
+ public virtual bool PLCConnect()
+ {
+ Connected = true;
+ return true;
+ }
+
+ public virtual bool PLCDisConnect()
+ {
+ Connected = false;
+ return true;
+ }
+
+ public virtual Int16 ReadInt16(string address) { return 0; }
+
+ public virtual Int32 ReadInt32(string address) { return 0; }
+
+ public virtual UInt16 ReadUInt16(string address) { return 0; }
+
+ public virtual UInt32 ReadUInt32(string address) { return 0; }
+ public virtual float ReadFloat(string address) { return 0; }
+ public virtual bool ReadBool(string address) { return false; }
+
+ public virtual bool WriteInt16(string address, Int16 value, bool waitForReply = true) { return false; }
+ public virtual bool WriteInt32(string address, Int32 value, bool waitForReply = true) { return false; }
+
+
+ public virtual bool WriteUInt16(string address, UInt16 value, bool waitForReply = true) { return false; }
+ public virtual bool WriteUInt32(string address, UInt32 value, bool waitForReply = true) { return false; }
+
+ public virtual bool WriteFloat(string address, float value, bool waitForReply = true) { return false; }
+ public virtual bool WriteBool(string address, bool value, bool waitForReply = true) { return false; }
+ }
+
+
+ public class PLCItem : NotifyProperty
+ {
+ private bool _selected;
+ private string _name = string.Empty;
+ private EnumPLCDataType _type;
+ private string _value = string.Empty;
+ private bool _startexecute;
+ private int _startindex;
+ private string _address;
+ ///
+ /// 是否选中
+ ///
+ public bool Selected
+ {
+ get => _selected;
+ set
+ {
+ if (_selected != value)
+ {
+ _selected = value;
+ OnPropertyChanged(nameof(Selected));
+ }
+ }
+ }
+
+ ///
+ /// 参数名称
+ ///
+ public string Name
+ {
+ get => _name;
+ set
+ {
+ if (_name != value)
+ {
+ _name = value;
+ OnPropertyChanged(nameof(Name));
+ }
+ }
+ }
+ public EnumPLCDataType Type
+ {
+ get => _type;
+ set
+ {
+ if (_type != value)
+ {
+ _type = value;
+ OnPropertyChanged(nameof(Type));
+ }
+ }
+ }
+ ///
+ /// 参数类型
+ ///
+ public string Address
+ {
+ get => _address;
+ set
+ {
+ if (_address != value)
+ {
+ _address = value;
+ OnPropertyChanged(nameof(Address));
+ }
+ }
+ }
+
+ ///
+ /// 参数值
+ ///
+ public string Value
+ {
+ get => _value;
+ set
+ {
+ if (_value != value)
+ {
+ _value = value;
+ OnPropertyChanged(nameof(Value));
+ }
+ }
+ }
+
+ ///
+ /// 启用状态
+ ///
+ public bool StartExecute
+ {
+ get => _startexecute;
+ set
+ {
+ if (_startexecute != value)
+ {
+ _startexecute = value;
+ OnPropertyChanged(nameof(StartExecute));
+ }
+ }
+ }
+
+
+
+
+
+ ///
+ /// 顺序
+ ///
+ public int StartIndex
+ {
+ get => _startindex;
+ set
+ {
+ if (_startindex != value)
+ {
+ _startindex = value;
+ OnPropertyChanged(nameof(StartIndex));
+ }
+ }
+ }
+
+ private CellLink[] cellLinks;
+ [JsonIgnore]
+ public CellLink[] CellLinks
+ {
+ get { return cellLinks; }
+ set
+ {
+ if (cellLinks == value) return;
+ cellLinks = value;
+ OnPropertyChanged(nameof(CellLinks));
+ }
+ }
+
+ //private CellTag[] cellTags;
+ //[JsonIgnore]
+ //public CellTag[] CellTags
+ //{
+ // get { return cellTags; }
+ // set
+ // {
+ // if (cellTags == value) return;
+ // cellTags = value;
+ // OnPropertyChanged(nameof(CellTags));
+ // }
+ //}
+ }
+
+
+}
\ No newline at end of file
diff --git a/DH.Commons/Base/VisionEngineBase.cs b/DH.Commons/Base/VisionEngineBase.cs
new file mode 100644
index 0000000..3addef4
--- /dev/null
+++ b/DH.Commons/Base/VisionEngineBase.cs
@@ -0,0 +1,78 @@
+using System.Collections;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Imaging;
+using DH.Commons.Enums;
+using DH.Commons.Helper;
+using HalconDotNet;
+using OpenCvSharp;
+
+
+
+namespace DH.Commons.Base
+{
+ ///
+ /// 视觉处理引擎:1.传统视觉 2.深度学习
+ /// CV深度学习 四大领域
+ /// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗;
+ /// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体;
+ /// Object Detection 目标检测:寻找图像中的物体并进行定位;
+ /// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体;
+ ///
+ public abstract class VisionEngineBase : DeviceBase
+ {
+ public List DetectionConfigs = new List();
+ #region event
+ public event Action> OnCropParamsOutput;
+ public event Action> OnDetectionDone;
+ public event Action OnDetectionWarningStop;//有无检测 需要报警停机
+ #endregion
+ //public VisionEngineInitialConfigBase IConfig
+ //{
+ // get => InitialConfig as VisionEngineInitialConfigBase;
+ //}
+ // public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
+ public string BatchNO { get; set; }
+
+ public HTuple hv_ModelID;
+
+ public abstract DetectStationResult RunInference(MatSet originImgSet, string detectionId = null);
+
+ //public abstract void SaveDetectResultAsync(DetectStationResult detectResult);
+
+
+
+ public virtual void DetectionDone(string detectionId, Bitmap image, List detectionResults)
+ {
+ OnDetectionDone?.Invoke(detectionId, image, detectionResults);
+ }
+
+ public virtual void DetectionWarningStop(string detectionDes)
+ {
+ OnDetectionWarningStop?.Invoke(detectionDes);
+ }
+ public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
+ public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat)
+ {
+ if (saveMap != null)
+ {
+ ImageSaveSet imageSaveSet = new ImageSaveSet()
+ {
+ FullName = fullname,
+ SaveImage = saveMap.CopyBitmap(),
+ ImageFormat = imageFormat.DeepSerializeClone()
+
+ };
+
+ ImageSaveHelper.ImageSaveAsync(imageSaveSet);
+ }
+ }
+ }
+
+
+}
+
+
+
+
+
diff --git a/DH.Commons/Base/VisualLocalization.cs b/DH.Commons/Base/VisualLocalization.cs
new file mode 100644
index 0000000..66c7694
--- /dev/null
+++ b/DH.Commons/Base/VisualLocalization.cs
@@ -0,0 +1,80 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.Json;
+
+namespace DH.Commons.Base
+{
+ public class VisualLocalization
+ {
+ // 配置属性
+ public string CameraName { get; set; }
+ public string ModelPath { get; set; }
+ public string ImgPath { get; set; }
+ public string Threshold { get; set; }
+ public string Direction { get; set; }
+ public string Speed { get; set; }
+
+ public string MSpeed { get; set; }
+
+ // 配置文件路径
+ private const string ConfigFile = "VisualConfigs.json";
+ private static readonly object _fileLock = new object();
+
+ ///
+ /// 保存当前配置(存在则更新,不存在则新增)
+ ///
+ public void Save()
+ {
+ lock (_fileLock)
+ {
+ var list = LoadAll();
+ var existing = list.FirstOrDefault(c => c.CameraName == CameraName);
+
+ if (existing != null)
+ {
+ // 更新现有配置
+ existing.ModelPath = ModelPath;
+ existing.ImgPath = ImgPath;
+ existing.Threshold = Threshold;
+ existing.Direction = Direction;
+ existing.Speed = Speed;
+ existing.MSpeed = MSpeed;
+ }
+ else
+ {
+ list.Add(this);
+ }
+
+ SaveAll(list);
+ }
+ }
+
+ ///
+ /// 获取全部配置列表
+ ///
+ public static List LoadAll()
+ {
+ lock (_fileLock)
+ {
+ if (!File.Exists(ConfigFile)) return new List();
+
+ var json = File.ReadAllText(ConfigFile);
+ return JsonSerializer.Deserialize>(json)
+ ?? new List();
+ }
+ }
+
+ private static void SaveAll(List list)
+ {
+ var options = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ IgnoreNullValues = true
+ };
+
+ File.WriteAllText(ConfigFile, JsonSerializer.Serialize(list, options));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DH.Commons/DH.Commons.csproj b/DH.Commons/DH.Commons.csproj
index 433b8fb..4771958 100644
--- a/DH.Commons/DH.Commons.csproj
+++ b/DH.Commons/DH.Commons.csproj
@@ -13,15 +13,23 @@
+
+
+
+
+
+
+ ..\X64\Debug\DVPCameraCS64.dll
+
..\x64\Debug\halcondotnet.dll
diff --git a/DH.Commons/Enums/ClassHelper.cs b/DH.Commons/Enums/ClassHelper.cs
deleted file mode 100644
index 6270021..0000000
--- a/DH.Commons/Enums/ClassHelper.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace DH.Commons.Enums
-{
- public class CameraInfo
- {
- public string CamName { get; set; }
- public string Serinum { get; set; }
- public string IP { get; set; }
- }
-
-}
diff --git a/DH.Commons/Enums/Enum.cs b/DH.Commons/Enums/Enum.cs
index 5405e52..e13843a 100644
--- a/DH.Commons/Enums/Enum.cs
+++ b/DH.Commons/Enums/Enum.cs
@@ -7,12 +7,62 @@ using System.Threading.Tasks;
namespace DH.Commons.Enums
{
+ public enum EnumStatus
+ {
+ 待机中,
+ 运行中,
+ 清料中,
+ 警告,
+ 异常
+ }
+ public enum ModelType
+ {
+ 图像分类 = 1,
+ 目标检测 = 2,
+ 语义分割 = 3,
+ 实例分割 = 4,
+ 目标检测GPU = 5
+ }
+ public enum SelectPicType
+ {
+ [Description("训练图片")]
+ train = 0,
+ [Description("测试图片")]
+ test
+
+ }
+ public enum NetModel
+ {
+ [Description("目标检测")]
+ training = 0,
+ [Description("语义分割")]
+ train_seg,
+ [Description("模型导出")]
+ emport,
+ [Description("推理预测")]
+ infernce
+
+ }
+ public enum EnumCamType
+ {
+ [Description("度申相机")]
+ 度申Do3think = 0,
+ [Description("海康相机")]
+ 海康hik ,
+
+ }
+
+
public enum EnumPLCType
{
- 信捷XC_串口,
- 信捷XC_网口,
- 信捷XD_串口,
- 信捷XD_网口
+ [Description("信捷XC串口")]
+ 信捷XC串口 = 0,
+ [Description("信捷XC网口")]
+ 信捷XC网口 = 1,
+ [Description("信捷XD串口")]
+ 信捷XD串口 = 2,
+ [Description("信捷XD网口")]
+ 信捷XD网口 = 3
}
@@ -28,32 +78,84 @@ namespace DH.Commons.Enums
public enum EnumPLCOutputIO
{
转盘方向=0,
- 转盘速度=1,
- 转盘使能=2,
- 转盘启动=3,
- 转盘清料=4,
- 指示灯绿=5,
- 指示灯黄=6,
- 指示灯红=7,
- 蜂鸣器=8,
- 振动盘=9,
- 皮带=10,
- 工位1=11,
- 工位2=12,
- 工位3=13,
- 工位4=14,
- 工位5=15,
- OK料盒=16,
- NG料盒=17,
- OK吹气时间=18,
- NG吹气时间=19,
- 产品计数=20,
- 计数清零=21,
- 工件最小值=22,
- 工具最大值=23,
- 启用心跳=24,
- 心跳=25
+ 转盘速度,
+ 转盘使能,
+ 转盘启动,
+ 转盘清料,
+ 指示灯绿,
+ 指示灯黄,
+ 指示灯红,
+ 蜂鸣器,
+ 振动盘,
+ 皮带,
+ 工位1,
+ 工位2,
+ 工位3,
+ 工位4,
+ 工位5,
+ 工位6 ,
+ 工位7 ,
+ 工位8 ,
+ 工位9 ,
+ 工位10 ,
+ 相机触发时间,
+ 吹气时间,
+ 产品计数,
+ 计数清零,
+ 工件最小值,
+ 工件最大值,
+ 启用心跳,
+ 心跳地址,
+ 挡料电机回原点,
+ 挡料电机回原点速度,
+ 挡料电机速度,
+ 挡料电机顺时针,
+ 挡料电机逆时针,
+ 挡料电机位置,
+ OK脉冲,
+ NG脉冲,
+ 状态复位,
+ 启用定位,
+ 定位完成脉冲值,
+ 相机步进原点,
+ 相机步进位置,
+ 相机步进速度,
+ 相机步进顺时针,
+ 相机步进逆时针,
+ 点动相机步进,
+ 点动挡杆步进,
+ 相机步进实时位置,
+ 挡料电机实时位置
+
+
+
+ }
+
+
+ public enum EnumPLCDataType
+ {
+ 单字整型,
+ 双字整型,
+ 浮点型,
+ 布尔型
+ }
+
+ public enum EnumBool
+ {
+ 关闭,
+ 启用
+ }
+ public enum EnumBool1
+ {
+ False,
+ True
+ }
+
+ public enum EnumDetectionType
+ {
+ 深度学习,
+ 尺寸测量
}
diff --git a/DH.Commons/Exception/ExceptionHelper.cs b/DH.Commons/Exception/ExceptionHelper.cs
new file mode 100644
index 0000000..9b49522
--- /dev/null
+++ b/DH.Commons/Exception/ExceptionHelper.cs
@@ -0,0 +1,64 @@
+using System;
+using static DH.Commons.Enums.EnumHelper;
+
+
+namespace DH.Commons.Helper
+{
+ public enum ExceptionLevel
+ {
+ Info = 0,
+ Warning = 1,
+ Fatal = 2,
+ }
+
+ //public delegate void OnProcessExceptionRaisedDelegate(DateTime dt, ProcessException ex);
+ //[Serializable]
+ public class ProcessException : Exception
+ {
+ public ExceptionLevel Level { get; set; } = ExceptionLevel.Warning;
+
+ public ProcessException()
+ {
+ }
+
+ public ProcessException(Exception ex, ExceptionLevel lvl = ExceptionLevel.Warning) : base(ex.Message, ex)
+ {
+ Level = lvl;
+ ExceptionNotice();
+ }
+
+ public ProcessException(string error, Exception ex = null, ExceptionLevel lvl = ExceptionLevel.Warning) : base(error, ex)
+ {
+ Level = lvl;
+ ExceptionNotice();
+ }
+
+ public void ExceptionNotice()
+ {
+ //OnProcessExceptionRaised?.Invoke(DateTime.Now, this);
+ }
+ }
+
+ public static class ExceptionHelper
+ {
+ public static LogLevel LogLevel = LogLevel.Information;
+ public static string GetExceptionMessage(this Exception ex)
+ {
+ string msg = "异常信息:" + ex.Message;
+ if (ex.InnerException != null)
+ {
+ msg += ";\t内部异常信息:" + ex.InnerException.GetExceptionMessage();
+ }
+
+ if (LogLevel <= LogLevel.Assist)
+ {
+ msg += (";\r\n\t\tStackTrace:" + ex.StackTrace);
+ }
+ return msg;
+ }
+ }
+
+ public class AuthorityException : ProcessException
+ {
+ }
+}
diff --git a/DH.Commons/Helper/AttributeHelper.cs b/DH.Commons/Helper/AttributeHelper.cs
new file mode 100644
index 0000000..5236ed2
--- /dev/null
+++ b/DH.Commons/Helper/AttributeHelper.cs
@@ -0,0 +1,162 @@
+using DH.Commons.Enums;
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using static DH.Commons.Enums.EnumHelper;
+
+
+namespace DH.Commons.Enums
+{
+ ///
+ /// 设备特性,指示该信息的设备类型,适用于设备信息和配置信息
+ ///
+ public class DeviceAttribute : Attribute
+ {
+ ///
+ /// 设备类型
+ ///
+ public string TypeCode { get; set; }
+
+ public string TypeDescription { get; set; }
+
+ ///
+ /// 特性修饰类别
+ ///
+ public DeviceAttributeType AttrType { get; set; }
+
+ public DeviceAttribute(string typeCode, string typeDesc, EnumHelper.DeviceAttributeType attrType)
+ {
+ TypeCode = typeCode;
+ TypeDescription = typeDesc;
+ AttrType = attrType;
+ }
+ }
+
+ ///
+ /// 预置状态特性 指定该修饰信息的前置状态允许范围
+ ///
+ public class PreStateAttribute : Attribute
+ {
+ public int PreState { get; set; }
+ public PreStateAttribute(int _preState)
+ {
+ PreState = _preState;
+ }
+
+ ///
+ /// 检查当前待执行操作的前置状态要求是否合法
+ ///
+ ///
+ ///
+ public bool CheckPreStateValid(int currentState)
+ {
+ return (currentState & PreState) == currentState;
+ }
+ }
+
+ public class ColorSelectAttribute : Attribute
+ {
+ public string SelectedColor { get; set; }
+ public ColorSelectAttribute(string selectedColor)
+ {
+ SelectedColor = selectedColor;
+ }
+ }
+
+ public class FontColorSelectAttribute : Attribute
+ {
+ public string SelectedColor { get; set; }
+ public FontColorSelectAttribute(string selectedColor)
+ {
+ SelectedColor = selectedColor;
+ }
+ }
+
+ public enum InvokeType
+ {
+ ///
+ /// 不公开调用
+ ///
+ [Description("不公开调用")]
+ NoneInvoke = 0,
+ ///
+ /// 测试调用
+ ///
+ [Description("测试调用")]
+ TestInvoke = 1,
+ ///
+ /// 标定调用
+ ///
+ [Description("标定调用")]
+ CalibInvoke = 2,
+ }
+
+ ///
+ /// 用来修饰对外开放的调用方法的特性
+ /// 调用方法参数顺序:IOperationConfig,InvokeDevice,SourceDevice
+ ///
+ public class ProcessMethodAttribute : Attribute
+ {
+ public string MethodCode { get; set; }
+ public string MethodDesc { get; set; }
+
+ ///
+ /// 是否提供人工调用测试
+ ///
+ public InvokeType InvokeType { get; set; }
+
+ public string DeviceType { get; set; }
+
+ public ProcessMethodAttribute(string deviceType, string code, string description, InvokeType invokeType)
+ {
+ DeviceType = deviceType;
+ MethodCode = code;
+ MethodDesc = description;
+ InvokeType = invokeType;
+ }
+ }
+
+ public class SwitchDisplayAttribute : Attribute
+ {
+ public string SwitchName { get; set; }
+
+ public bool SwithOnStatus { get; set; } = true;
+
+ public SwitchDisplayAttribute(string name, bool status)
+ {
+ SwitchName = name;
+ SwithOnStatus = status;
+ }
+ }
+
+ public class ElementAttribute : Attribute
+ {
+ public string Name { get; set; }
+
+ public string Desc { get; set; }
+
+ public string IconPath { get; set; }
+
+ public bool IsShowInToolBar { get; set; }
+
+ public ElementAttribute(string desc, string iconPath, bool isShowInToolBar = true, [CallerMemberName] string name = "")
+ {
+ Name = name;
+ Desc = desc;
+ IconPath = iconPath;
+ IsShowInToolBar = isShowInToolBar;
+ }
+ }
+
+ public class ProcessAttribute : Attribute
+ {
+ public string ProcessCode { get; set; }
+ public DeviceAttributeType AttrType { get; set; }
+
+ public ProcessAttribute(string stationCode, DeviceAttributeType attrType)
+ {
+ ProcessCode = stationCode;
+ AttrType = attrType;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DH.Commons/Helper/ConfigHelper.cs b/DH.Commons/Helper/ConfigHelper.cs
new file mode 100644
index 0000000..b77febc
--- /dev/null
+++ b/DH.Commons/Helper/ConfigHelper.cs
@@ -0,0 +1,280 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using AntdUI;
+using DH.Commons.Base;
+using DH.Commons.Enums;
+using DH.Commons.Models;
+
+namespace DH.Commons.Helper
+{
+ public static class ConfigHelper
+ {
+ private static readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
+ {
+ WriteIndented = true,
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
+ IgnoreNullValues = true
+ };
+
+ ///
+ /// 配置存储根目录
+ ///
+ private static string ConfigsRoot => Path.Combine(
+ AppDomain.CurrentDomain.BaseDirectory,
+ "configs");
+
+ ///
+ /// 获取当前方案的主配置文件路径
+ ///
+ private static string CurrentConfigPath
+ {
+ get
+ {
+ ValidateCurrentScheme();
+ return Path.Combine(
+ ConfigsRoot,
+ $"config_{SystemModel.CurrentScheme}.json");
+ }
+ }
+
+ ///
+ /// 获取当前方案的备份目录路径
+ ///
+ private static string CurrentBackupDir
+ {
+ get
+ {
+ ValidateCurrentScheme();
+ return Path.Combine(
+ ConfigsRoot,
+ $"bak_{SystemModel.CurrentScheme}");
+ }
+ }
+
+ ///
+ /// 初始化新方案(创建空文件)
+ ///
+ public static void InitializeScheme(string scheme)
+ {
+ SystemModel.CurrentScheme = scheme;
+
+ // 创建空配置文件
+ if (!File.Exists(CurrentConfigPath))
+ {
+ Directory.CreateDirectory(ConfigsRoot);
+ File.WriteAllText(CurrentConfigPath, "{}");
+ }
+
+ // 创建备份目录
+ Directory.CreateDirectory(CurrentBackupDir);
+ }
+
+ ///
+ /// 保存当前配置(自动备份)
+ ///
+ public static void SaveConfig()
+ {
+ ValidateCurrentScheme();
+
+ // 确保配置目录存在
+ Directory.CreateDirectory(ConfigsRoot);
+
+ // 备份现有配置
+ if (File.Exists(CurrentConfigPath))
+ {
+ var backupName = $"config_{SystemModel.CurrentScheme}_{DateTime.Now:yyyyMMddHHmmss}.json";
+ var backupPath = Path.Combine(CurrentBackupDir, backupName);
+
+ Directory.CreateDirectory(CurrentBackupDir);
+ File.Copy(CurrentConfigPath, backupPath);
+ }
+ //重置标签文件路径和内容
+ ConfigModel.DetectionList.ForEach(config =>
+ {
+ GenerateLabelFile(config);
+ });
+
+ // 序列化当前配置
+ var json = JsonSerializer.Serialize(new
+ {
+ ConfigModel.CameraBaseList,
+ ConfigModel.PLCBaseList,
+ ConfigModel.DetectionList,
+ ConfigModel.GlobalList,
+ }, _jsonOptions);
+
+ // 写入新配置
+ File.WriteAllText(CurrentConfigPath, json);
+ }
+ private static void GenerateLabelFile(DetectionConfig config)
+ {
+ try
+ {
+ if (config.DetectionLableList == null || string.IsNullOrEmpty(config.In_lable_path))
+ return;
+
+ // 确保目录存在
+ var directory = Path.GetDirectoryName(config.In_lable_path);
+ if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
+ {
+ Directory.CreateDirectory(directory);
+ }
+
+ // 写入文件内容
+ using (var writer = new StreamWriter(config.In_lable_path, false))
+ {
+ foreach (var label in config.DetectionLableList)
+ {
+ //是否假如判断标签为中文转为为英文
+ //string pinyinlabel = FileHelper.ConvertHanzitoPinyinWithNumbers(label.LabelName.ToString());
+ //if (FileHelper.IsAlphaNumericOnly(pinyinlabel))
+ //{
+
+ //}
+
+ // 根据实际需求格式化输出
+ writer.WriteLine(label.LabelName.ToString()); // 假设DetectionLable重写了ToString()
+
+ // 或者明确指定格式:
+ // writer.WriteLine($"{label.Id},{label.Name},{label.Confidence}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine($"生成标签文件失败: {ex.Message}");
+ // 可以考虑记录更详细的日志
+ }
+ }
+ ///
+ /// 加载当前方案配置
+ ///
+ public static void LoadConfig()
+ {
+ ValidateCurrentScheme();
+
+ if (!File.Exists(CurrentConfigPath))
+ {
+ InitializeScheme(SystemModel.CurrentScheme);
+ return;
+ }
+
+ var json = File.ReadAllText(CurrentConfigPath);
+ var data = JsonSerializer.Deserialize(json, _jsonOptions);
+
+ ConfigModel.CameraBaseList = data?.Cameras ?? new List();
+ ConfigModel.DetectionList = data?.Detections ?? new List();
+ ConfigModel.PLCBaseList = data?.PLCs ?? new List();
+ ConfigModel.GlobalList = data?.GlobalConfigs ?? new List();
+ }
+
+ ///
+ /// 验证当前方案有效性
+ ///
+ private static void ValidateCurrentScheme()
+ {
+ if (string.IsNullOrWhiteSpace(SystemModel.CurrentScheme))
+ throw new InvalidOperationException("当前方案未设置");
+ }
+ ///
+ /// 派生新方案(基于当前方案创建副本)
+ ///
+ /// 新方案名称
+ public static void DeriveScheme(string newSchemeName)
+ {
+ // 验证输入
+ if (string.IsNullOrWhiteSpace(newSchemeName))
+ {
+ throw new ArgumentException("新方案名称不能为空");
+ }
+
+ // 验证当前方案是否有效
+ ValidateCurrentScheme();
+
+ // 检查新方案是否已存在
+ var newConfigPath = Path.Combine(ConfigsRoot, $"config_{newSchemeName}.json");
+ if (File.Exists(newConfigPath))
+ {
+ throw new InvalidOperationException($"方案 {newSchemeName} 已存在");
+ }
+
+ // 保存当前配置确保最新
+ SaveConfig();
+
+ try
+ {
+ // 复制配置文件
+ File.Copy(CurrentConfigPath, newConfigPath);
+
+ // 创建备份目录
+ var newBackupDir = Path.Combine(ConfigsRoot, $"bak_{newSchemeName}");
+ Directory.CreateDirectory(newBackupDir);
+
+ // 可选:自动切换新方案
+ // SystemModel.CurrentScheme = newSchemeName;
+ }
+ catch (IOException ex)
+ {
+ throw new InvalidOperationException($"方案派生失败: {ex.Message}", ex);
+ }
+ }
+
+ ///
+ /// 删除指定方案的配置文件及备份目录
+ ///
+ /// 要删除的方案名称
+ /// 当方案名称为空时抛出
+ /// 文件操作失败时抛出
+ public static void DeleteSchemeConfig(string schemeName)
+ {
+ if (string.IsNullOrWhiteSpace(schemeName))
+ throw new ArgumentException("方案名称无效");
+
+ // 构造路径
+ var configPath = Path.Combine(ConfigsRoot, $"config_{schemeName}.json");
+ var backupDir = Path.Combine(ConfigsRoot, $"bak_{schemeName}");
+
+ try
+ {
+ // 删除配置文件
+ if (File.Exists(configPath))
+ {
+ File.Delete(configPath);
+ }
+
+ // 删除备份目录(递归删除)
+ if (Directory.Exists(backupDir))
+ {
+ Directory.Delete(backupDir, true);
+ }
+ }
+ catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException)
+ {
+ throw new IOException($"删除方案 {schemeName} 的配置文件失败: {ex.Message}", ex);
+ }
+ }
+
+
+ ///
+ /// 配置数据模型(内部类)
+ ///
+ private class ConfigData
+ {
+ [JsonPropertyName("cameraBaseList")]
+ public List Cameras { get; set; } = new List();
+
+ [JsonPropertyName("plcBaseList")]
+ public List PLCs { get; set; } = new List();
+
+ [JsonPropertyName("detectionList")]
+ public List Detections { get; set; } = new List();
+ [JsonPropertyName("globalList")]
+ public List GlobalConfigs { get; set; } = new List();
+
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/DH.Commons/Helper/EnumHelper.cs b/DH.Commons/Helper/EnumHelper.cs
index 0308390..10898bc 100644
--- a/DH.Commons/Helper/EnumHelper.cs
+++ b/DH.Commons/Helper/EnumHelper.cs
@@ -76,159 +76,83 @@ namespace DH.Commons.Enums
}
}
- //public static System.Windows.Media.Color GetEnumSelectedMediaColor(this Enum enumObj)
- //{
- // Type t = enumObj.GetType();
- // FieldInfo f = t.GetField(enumObj.ToString());
-
- // ColorSelectAttribute attr = f.GetCustomAttribute