From ebcc1d53f14112363bbf539bcaf0202aadcdc9d7 Mon Sep 17 00:00:00 2001
From: C3032 <1057644574@qq.com>
Date: 星期一, 13 四月 2026 12:58:58 +0800
Subject: [PATCH] 2D取图计数功能完成
---
LB_SmartVision/ProcessRun/ProcessRunBll.cs | 44 +
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.cs | 161 +++++
LB_VisionProcesses/Cameras/CameraConfig.cs | 5
LB_SmartVision/ProcessRun/ProcessContext.cs | 80 ++
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcess.cs | 413 ++++++++++++++
LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.Designer.cs | 567 ++++++++++++++++++++
LB_VisionProcesses/Processes/TyreCounter/TyreStatistics.cs | 266 +++++++++
LB_SmartVision/CSV/CsvRecordProductData.cs | 20
LB_SmartVision/SQL/RecordProductData.cs | 32 +
LB_VisionProcesses/Cameras/2DCameraForm.cs | 2
LB_VisionProcesses/Cameras/ICamera.cs | 88 +++
11 files changed, 1,677 insertions(+), 1 deletions(-)
diff --git a/LB_SmartVision/CSV/CsvRecordProductData.cs b/LB_SmartVision/CSV/CsvRecordProductData.cs
index 6648f12..93e9875 100644
--- a/LB_SmartVision/CSV/CsvRecordProductData.cs
+++ b/LB_SmartVision/CSV/CsvRecordProductData.cs
@@ -47,6 +47,26 @@
/// 妫�娴嬬浉鏈�
/// </summary>
public string CameraInspection { get; set; }
+
+ /// <summary>
+ /// 杞儙ID
+ /// </summary>
+ public int TyreID { get; set; }
+
+ /// <summary>
+ /// 鍥惧儚搴忓彿锛�1~n锛�
+ /// </summary>
+ public int ImageIndex { get; set; }
+
+ /// <summary>
+ /// 杞儙绾ф娴嬬粨鏋�
+ /// </summary>
+ public string TyreResult { get; set; }
+
+ /// <summary>
+ /// 姣忓紶杞儙鍥惧儚鏁�
+ /// </summary>
+ public int ImagesPerTyre { get; set; }
}
}
diff --git a/LB_SmartVision/ProcessRun/ProcessContext.cs b/LB_SmartVision/ProcessRun/ProcessContext.cs
index e46967c..c680c4f 100644
--- a/LB_SmartVision/ProcessRun/ProcessContext.cs
+++ b/LB_SmartVision/ProcessRun/ProcessContext.cs
@@ -6,6 +6,7 @@
using LB_VisionProcesses.Alogrithms;
using LB_VisionProcesses.Cameras;
using LB_VisionProcesses.Communicators;
+using LB_VisionProcesses.Processes;
using LB_VisionProcesses.Processes.ScriptTool;
using OpenCvSharp;
using System.Collections.Concurrent;
@@ -585,7 +586,86 @@
[Node("Halcon2D鍥惧儚婊ゆ尝", "Halcon2D宸ュ叿", "Basic", "Halcon2D鍥惧儚婊ゆ尝")]
public void Halcon2D鍥惧儚婊ゆ尝(FlowNode node) { RunNodeAsync(node); }
+ [Node("杞儙璁℃暟", "鎺у埗", "Logic", "杞儙璁℃暟鑺傜偣")]
+ public void 杞儙璁℃暟(FlowNode node)
+ {
+ string ProcessName = node.Text;
+ try
+ {
+ if (dicContext.TryGetValue(ProcessName, out IProcess obj)
+ && obj is TyreCounterProcess counter)
+ {
+ UpdateInputs(counter);
+ if (node.Break)
+ {
+ node.BranchIndex = "0";
+ node.Result = true;
+ counter.Result = true;
+ counter.Msg = "杞儙璁℃暟鑺傜偣宸茶烦杩�";
+ return;
+ }
+
+ // 浠庡墠缃妭鐐硅幏鍙栨娴嬬粨鏋滐紙閫氳繃杈撳叆鏄犲皠锛�
+ bool imageResult = GetPreviousResult(node);
+
+ // 璁剧疆杈撳叆缁撴灉
+ counter.InputImage = imageResult;
+
+ // 杩愯杞儙璁℃暟
+ if (!counter.Run())
+ {
+ node.Result = false;
+ Result &= false;
+ Msg += $"[{ProcessName}]{counter.Msg}";
+ }
+ else
+ {
+ node.Result = true;
+
+ // 濡傛灉瀹屾垚涓�涓疆鑳庯紝杈撳嚭瀹屾垚淇″彿
+ if (counter.IsTyreComplete)
+ {
+ Msg += $"[{ProcessName}]瀹屾垚杞儙 #{counter.CurrentTyreID - 1}锛岀粨鏋�: {(counter.TyreResult ? "OK" : "NG")}";
+ }
+ }
+ }
+ else
+ {
+ node.Result = false;
+ Result &= false;
+ Msg += $"[{ProcessName}]鏈壘鍒拌疆鑳庤鏁板伐鍏峰疄渚�";
+ }
+ }
+ catch (Exception ex)
+ {
+ node.Result = false;
+ Result &= false;
+ Msg += $"[{ProcessName}]杩愯鍙戠敓鎰忓,{ex.Message}";
+ }
+ }
+
+ /// <summary>
+ /// 鑾峰彇鍓嶇疆鑺傜偣鐨勬娴嬬粨鏋�
+ /// </summary>
+ private bool GetPreviousResult(FlowNode node)
+ {
+ try
+ {
+ // 鏌ユ壘鍓嶇疆鑺傜偣
+ var prevNode = dicContext.Values
+ .OfType<IProcess>()
+ .FirstOrDefault(p => p.Result == true || p.Result == false);
+
+ if (prevNode != null)
+ {
+ return prevNode.Result;
+ }
+ }
+ catch { }
+
+ return true; // 榛樿杩斿洖OK
+ }
#endregion
diff --git a/LB_SmartVision/ProcessRun/ProcessRunBll.cs b/LB_SmartVision/ProcessRun/ProcessRunBll.cs
index 014464b..09c7798 100644
--- a/LB_SmartVision/ProcessRun/ProcessRunBll.cs
+++ b/LB_SmartVision/ProcessRun/ProcessRunBll.cs
@@ -875,9 +875,26 @@
double total_OK;
double total_NG;
+ /// <summary>
+ /// 杞儙绾х粺璁� - OK璁℃暟
+ /// </summary>
+ double tyre_OK;
+ /// <summary>
+ /// 杞儙绾х粺璁� - NG璁℃暟
+ /// </summary>
+ double tyre_NG;
+
public double total
{
get { return total_OK + total_NG; }
+ }
+
+ /// <summary>
+ /// 杞儙鎬绘暟
+ /// </summary>
+ public double tyreTotal
+ {
+ get { return tyre_OK + tyre_NG; }
}
public double Rate_OK
@@ -890,10 +907,37 @@
}
}
+ /// <summary>
+ /// 杞儙鑹搧鐜�
+ /// </summary>
+ public double TyreRate_OK
+ {
+ get
+ {
+ if (tyreTotal == 0)
+ return 100;
+ return (tyre_OK / tyreTotal) * 100;
+ }
+ }
+
public void ClearTotal()
{
total_OK = 0;
total_NG = 0;
+ tyre_OK = 0;
+ tyre_NG = 0;
+ }
+
+ /// <summary>
+ /// 娣诲姞杞儙缁熻
+ /// </summary>
+ /// <param name="isOK">杞儙鏄惁OK</param>
+ public void AddTyreResult(bool isOK)
+ {
+ if (isOK)
+ tyre_OK++;
+ else
+ tyre_NG++;
}
/// <summary>
diff --git a/LB_SmartVision/SQL/RecordProductData.cs b/LB_SmartVision/SQL/RecordProductData.cs
index 0020776..fbe0589 100644
--- a/LB_SmartVision/SQL/RecordProductData.cs
+++ b/LB_SmartVision/SQL/RecordProductData.cs
@@ -71,5 +71,37 @@
[DisplayName("妫�娴嬬浉鏈�")]
[Browsable(true)]
public string CameraInspection { get; set; }
+
+ /// <summary>
+ /// 杞儙ID
+ /// </summary>
+ [Category("RecordProductData"), PropertyOrder(7)]
+ [DisplayName("杞儙ID")]
+ [Browsable(true)]
+ public int TyreID { get; set; }
+
+ /// <summary>
+ /// 鍥惧儚搴忓彿锛�1~n锛�
+ /// </summary>
+ [Category("RecordProductData"), PropertyOrder(8)]
+ [DisplayName("鍥惧儚搴忓彿")]
+ [Browsable(true)]
+ public int ImageIndex { get; set; }
+
+ /// <summary>
+ /// 杞儙绾ф娴嬬粨鏋�
+ /// </summary>
+ [Category("RecordProductData"), PropertyOrder(9)]
+ [DisplayName("杞儙缁撴灉")]
+ [Browsable(true)]
+ public string TyreResult { get; set; }
+
+ /// <summary>
+ /// 姣忓紶杞儙鍥惧儚鏁�
+ /// </summary>
+ [Category("RecordProductData"), PropertyOrder(10)]
+ [DisplayName("杞儙鍥惧儚鏁�")]
+ [Browsable(true)]
+ public int ImagesPerTyre { get; set; }
}
}
diff --git a/LB_VisionProcesses/Cameras/2DCameraForm.cs b/LB_VisionProcesses/Cameras/2DCameraForm.cs
index 5aabcf7..2409faf 100644
--- a/LB_VisionProcesses/Cameras/2DCameraForm.cs
+++ b/LB_VisionProcesses/Cameras/2DCameraForm.cs
@@ -78,7 +78,7 @@
UserPictureBox onlinePictureBox { get; set; }
private System.Windows.Forms.Timer updateTimer;
- Total total = new Total { iImageCount = 0, iScanCount = 0 };
+ Total total = new Total { iImageCount = 0, iScanCount = 0, ImagesPerTyre = 1 };
DateTime startGrabtime = DateTime.Now;
// 鍔ㄦ�佹坊鍔犵殑澧炵泭涓嬫媺妗�
diff --git a/LB_VisionProcesses/Cameras/CameraConfig.cs b/LB_VisionProcesses/Cameras/CameraConfig.cs
index 4bec6f7..3b619c9 100644
--- a/LB_VisionProcesses/Cameras/CameraConfig.cs
+++ b/LB_VisionProcesses/Cameras/CameraConfig.cs
@@ -42,6 +42,11 @@
Params.Inputs.Add("瓒呮椂鏃堕棿", 1000);
Params.Inputs.Add("鏄惁澶辫触閲嶆柊鍙栧浘", false);
+
+ // 2D杞儙璁℃暟閰嶇疆锛堥粯璁や负1锛岃〃绀�3D妯″紡锛�2D鐩告満璁剧疆涓簄锛�
+ Params.Inputs.Add("ImagesPerTyre", 1);
+ Params.Inputs.Add("褰撳墠杞儙ID", 1);
+ Params.Inputs.Add("褰撳墠鍥惧儚搴忓彿", 0);
}
/// <summary>
diff --git a/LB_VisionProcesses/Cameras/ICamera.cs b/LB_VisionProcesses/Cameras/ICamera.cs
index 27c6c3a..ef64a79 100644
--- a/LB_VisionProcesses/Cameras/ICamera.cs
+++ b/LB_VisionProcesses/Cameras/ICamera.cs
@@ -8,8 +8,45 @@
{
public class Total
{
+ /// <summary>
+ /// 鍥惧儚璁℃暟
+ /// </summary>
public int iImageCount { get; set; } = 0;
+
+ /// <summary>
+ /// 鎵弿璁℃暟
+ /// </summary>
public int iScanCount { get; set; } = 0;
+
+ /// <summary>
+ /// 瀹屾暣杞儙璁℃暟
+ /// </summary>
+ public int TyreCount { get; set; } = 0;
+
+ /// <summary>
+ /// 姣忓紶杞儙鎵�闇�鍥惧儚鏁帮紙2D鐩告満浣跨敤锛岄粯璁�1琛ㄧず3D鐩告満锛�
+ /// </summary>
+ public int ImagesPerTyre { get; set; } = 1;
+
+ /// <summary>
+ /// 褰撳墠杞儙鐨勫浘鍍忓簭鍙凤紙0~ImagesPerTyre-1锛�
+ /// </summary>
+ public int CurrentImageIndex { get; set; } = 0;
+
+ /// <summary>
+ /// 杞儙OK璁℃暟
+ /// </summary>
+ public int TyreOK { get; set; } = 0;
+
+ /// <summary>
+ /// 杞儙NG璁℃暟
+ /// </summary>
+ public int TyreNG { get; set; } = 0;
+
+ /// <summary>
+ /// 褰撳墠杞儙ID
+ /// </summary>
+ public int CurrentTyreID { get; set; } = 1;
public Total() { }
@@ -19,10 +56,61 @@
this.iScanCount = iScanCount;
}
+ /// <summary>
+ /// 娣诲姞鍥惧儚骞舵洿鏂拌疆鑳庤鏁�
+ /// </summary>
+ /// <param name="imageResult">鍥惧儚妫�娴嬬粨鏋�</param>
+ /// <returns>鏄惁瀹屾垚涓�涓疆鑳�</returns>
+ public bool AddImageResult(bool imageResult)
+ {
+ iImageCount++;
+ CurrentImageIndex++;
+
+ // 妫�鏌ユ槸鍚﹀畬鎴愪竴涓疆鑳�
+ if (CurrentImageIndex >= ImagesPerTyre)
+ {
+ TyreCount++;
+ CurrentImageIndex = 0;
+
+ // 鏇存柊杞儙OK/NG璁℃暟锛坣寮犱腑浠讳竴NG鍒欐暣鑳嶯G锛�
+ if (imageResult)
+ TyreOK++;
+ else
+ TyreNG++;
+
+ CurrentTyreID++;
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// 鑾峰彇杞儙鑹搧鐜�
+ /// </summary>
+ public double TyreRateOK => TyreCount > 0 ? (TyreOK / (double)TyreCount) * 100 : 0;
+
public void Clear()
{
iImageCount = 0;
iScanCount = 0;
+ TyreCount = 0;
+ CurrentImageIndex = 0;
+ TyreOK = 0;
+ TyreNG = 0;
+ CurrentTyreID = 1;
+ }
+
+ /// <summary>
+ /// 閲嶇疆杞儙璁℃暟锛堜繚鐣橧magesPerTyre閰嶇疆锛�
+ /// </summary>
+ public void ResetTyreCount()
+ {
+ TyreCount = 0;
+ CurrentImageIndex = 0;
+ TyreOK = 0;
+ TyreNG = 0;
+ CurrentTyreID = 1;
}
}
public interface ICamera : IDisposable
diff --git a/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcess.cs b/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcess.cs
new file mode 100644
index 0000000..3704425
--- /dev/null
+++ b/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcess.cs
@@ -0,0 +1,413 @@
+using HalconDotNet;
+using LB_VisionProcesses.Alogrithms;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LB_VisionProcesses.Processes
+{
+ /// <summary>
+ /// 杞儙璁℃暟宸ュ叿 - 鐢ㄤ簬娴佺▼鑺傜偣涓粺璁¤疆鑳庢暟閲�
+ /// </summary>
+ [Process("杞儙璁℃暟", Category = "鎺у埗", Description = "鐢ㄤ簬2D宸ヤ綅杞儙璁℃暟锛岄厤缃畁寮犲浘/杞儙")]
+ public class TyreCounterProcess : BaseProcess
+ {
+ #region 閰嶇疆灞炴��
+
+ /// <summary>
+ /// 姣忓紶杞儙鎵�闇�鍥惧儚鏁�
+ /// </summary>
+ public int ImagesPerTyre
+ {
+ get
+ {
+ if (Params.Inputs.ContainsKey("ImagesPerTyre"))
+ return Convert.ToInt32(Params.Inputs["ImagesPerTyre"]);
+ return 8;
+ }
+ set
+ {
+ Params.Inputs["ImagesPerTyre"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鍒ゅ畾瑙勫垯
+ /// </summary>
+ public TyreJudgeRule JudgeRule
+ {
+ get
+ {
+ if (Params.Inputs.ContainsKey("JudgeRule"))
+ return (TyreJudgeRule)Enum.Parse(typeof(TyreJudgeRule), Params.Inputs["JudgeRule"].ToString());
+ return TyreJudgeRule.AnyNG;
+ }
+ set
+ {
+ Params.Inputs["JudgeRule"] = value.ToString();
+ }
+ }
+
+ /// <summary>
+ /// 鏄惁鑷姩閲嶇疆锛堝畬鎴愪竴涓疆鑳庡悗鑷姩閲嶇疆璁℃暟锛�
+ /// </summary>
+ public bool AutoReset
+ {
+ get
+ {
+ if (Params.Inputs.ContainsKey("AutoReset"))
+ return Convert.ToBoolean(Params.Inputs["AutoReset"]);
+ return true;
+ }
+ set
+ {
+ Params.Inputs["AutoReset"] = value;
+ }
+ }
+
+ #endregion
+
+ #region 杈撳嚭灞炴��
+
+ /// <summary>
+ /// 褰撳墠杞儙ID
+ /// </summary>
+ public int CurrentTyreID
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("CurrentTyreID"))
+ return Convert.ToInt32(Params.Outputs["CurrentTyreID"]);
+ return 1;
+ }
+ private set
+ {
+ Params.Outputs["CurrentTyreID"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 褰撳墠鍥惧儚搴忓彿锛�1~n锛�
+ /// </summary>
+ public int CurrentImageIndex
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("CurrentImageIndex"))
+ return Convert.ToInt32(Params.Outputs["CurrentImageIndex"]);
+ return 0;
+ }
+ private set
+ {
+ Params.Outputs["CurrentImageIndex"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鏄惁瀹屾垚杞儙
+ /// </summary>
+ public bool IsTyreComplete
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("IsTyreComplete"))
+ return Convert.ToBoolean(Params.Outputs["IsTyreComplete"]);
+ return false;
+ }
+ private set
+ {
+ Params.Outputs["IsTyreComplete"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 杞儙缁撴灉
+ /// </summary>
+ public bool TyreResult
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("TyreResult"))
+ return Convert.ToBoolean(Params.Outputs["TyreResult"]);
+ return false;
+ }
+ private set
+ {
+ Params.Outputs["TyreResult"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 杞儙鎬绘暟
+ /// </summary>
+ public int TyreTotal
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("TyreTotal"))
+ return Convert.ToInt32(Params.Outputs["TyreTotal"]);
+ return 0;
+ }
+ private set
+ {
+ Params.Outputs["TyreTotal"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 杞儙OK鏁�
+ /// </summary>
+ public int TyreOK
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("TyreOK"))
+ return Convert.ToInt32(Params.Outputs["TyreOK"]);
+ return 0;
+ }
+ private set
+ {
+ Params.Outputs["TyreOK"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 杞儙NG鏁�
+ /// </summary>
+ public int TyreNG
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("TyreNG"))
+ return Convert.ToInt32(Params.Outputs["TyreNG"]);
+ return 0;
+ }
+ private set
+ {
+ Params.Outputs["TyreNG"] = value;
+ }
+ }
+
+ /// <summary>
+ /// 鑹搧鐜�
+ /// </summary>
+ public double TyreRateOK
+ {
+ get
+ {
+ if (Params.Outputs.ContainsKey("TyreRateOK"))
+ return Convert.ToDouble(Params.Outputs["TyreRateOK"]);
+ return 0;
+ }
+ private set
+ {
+ Params.Outputs["TyreRateOK"] = value;
+ }
+ }
+
+ #endregion
+
+ #region 绉佹湁瀛楁
+
+ /// <summary>
+ /// 杞儙缁熻鍣ㄥ疄渚�
+ /// </summary>
+ private TyreStatistics? _tyreStatistics;
+
+ /// <summary>
+ /// 杈撳叆鐨勫浘鍍忕粨鏋滐紙浠庡墠缃妭鐐硅幏鍙栵級
+ /// </summary>
+ private bool _inputImageResult = true;
+
+ #endregion
+
+ #region 鏋勯�犳柟娉�
+
+ public TyreCounterProcess()
+ {
+ strProcessClass = "LB_VisionProcesses.Processes.TyreCounterProcess";
+ _tyreStatistics = new TyreStatistics();
+ InitParams();
+ }
+
+ /// <summary>
+ /// 鍒濆鍖栧弬鏁�
+ /// </summary>
+ private void InitParams()
+ {
+ // 杈撳叆鍙傛暟
+ if (!Params.Inputs.ContainsKey("ImagesPerTyre"))
+ Params.Inputs.Add("ImagesPerTyre", 8);
+ if (!Params.Inputs.ContainsKey("JudgeRule"))
+ Params.Inputs.Add("JudgeRule", TyreJudgeRule.AnyNG.ToString());
+ if (!Params.Inputs.ContainsKey("AutoReset"))
+ Params.Inputs.Add("AutoReset", true);
+
+ // 杈撳嚭鍙傛暟
+ if (!Params.Outputs.ContainsKey("CurrentTyreID"))
+ Params.Outputs.Add("CurrentTyreID", 1);
+ if (!Params.Outputs.ContainsKey("CurrentImageIndex"))
+ Params.Outputs.Add("CurrentImageIndex", 0);
+ if (!Params.Outputs.ContainsKey("IsTyreComplete"))
+ Params.Outputs.Add("IsTyreComplete", false);
+ if (!Params.Outputs.ContainsKey("TyreResult"))
+ Params.Outputs.Add("TyreResult", false);
+ if (!Params.Outputs.ContainsKey("TyreTotal"))
+ Params.Outputs.Add("TyreTotal", 0);
+ if (!Params.Outputs.ContainsKey("TyreOK"))
+ Params.Outputs.Add("TyreOK", 0);
+ if (!Params.Outputs.ContainsKey("TyreNG"))
+ Params.Outputs.Add("TyreNG", 0);
+ if (!Params.Outputs.ContainsKey("TyreRateOK"))
+ Params.Outputs.Add("TyreRateOK", 0.0);
+ }
+
+ #endregion
+
+ #region 鏍稿績鏂规硶
+
+ /// <summary>
+ /// 杩愯杞儙璁℃暟閫昏緫
+ /// </summary>
+ public override bool Run()
+ {
+ DateTime startTime = DateTime.Now;
+
+ try
+ {
+ // 鑾峰彇杈撳叆缁撴灉锛堜粠鍓嶇疆鑺傜偣鐨凴esult鍙傛暟锛�
+ GetInputResult();
+
+ // 鏇存柊缁熻鍣ㄩ厤缃�
+ _tyreStatistics.ImagesPerTyre = ImagesPerTyre;
+ _tyreStatistics.JudgeRule = JudgeRule;
+
+ // 娣诲姞鍥惧儚缁撴灉
+ var result = _tyreStatistics.AddImageResult(_inputImageResult);
+
+ // 鏇存柊杈撳嚭鍙傛暟
+ UpdateOutputs(result);
+
+ // 璁剧疆缁撴灉
+ Result = true;
+ Msg = result.Message;
+
+ RunTime = (DateTime.Now - startTime).TotalMilliseconds;
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Result = false;
+ Msg = $"杞儙璁℃暟杩愯澶辫触: {ex.Message}";
+ RunTime = (DateTime.Now - startTime).TotalMilliseconds;
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// 鑾峰彇杈撳叆缁撴灉锛堜粠鍓嶇疆鑺傜偣浼犻�掔殑Result锛�
+ /// </summary>
+ private void GetInputResult()
+ {
+ // 濡傛灉InputImage鏄痓ool绫诲瀷锛岃鏄庡墠缃妭鐐逛紶閫掍簡缁撴灉
+ if (InputImage is bool boolResult)
+ {
+ _inputImageResult = boolResult;
+ }
+ else
+ {
+ // 榛樿璁や负OK
+ _inputImageResult = true;
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊杈撳嚭鍙傛暟
+ /// </summary>
+ private void UpdateOutputs(TyreCountResult result)
+ {
+ CurrentTyreID = result.TyreID > 0 ? result.TyreID : _tyreStatistics.CurrentTyreID;
+ CurrentImageIndex = result.CurrentImageIndex;
+ IsTyreComplete = result.IsTyreComplete;
+ TyreResult = result.TyreResult;
+ TyreTotal = _tyreStatistics.TyreTotal;
+ TyreOK = _tyreStatistics.TyreOK;
+ TyreNG = _tyreStatistics.TyreNG;
+ TyreRateOK = _tyreStatistics.TyreRateOK;
+ }
+
+ /// <summary>
+ /// 鍒濆鍖栬繍琛屽弬鏁�
+ /// </summary>
+ public override void InitRunParams()
+ {
+ base.InitRunParams();
+ _inputImageResult = true;
+ }
+
+ /// <summary>
+ /// 閲嶇疆杞儙璁℃暟
+ /// </summary>
+ public void ResetTyreCount()
+ {
+ _tyreStatistics?.Reset();
+ UpdateOutputs(new TyreCountResult());
+ }
+
+ /// <summary>
+ /// 鑾峰彇缁熻淇℃伅
+ /// </summary>
+ public string GetStatisticsInfo()
+ {
+ return _tyreStatistics?.GetStatisticsInfo() ?? "缁熻鍣ㄦ湭鍒濆鍖�";
+ }
+
+ /// <summary>
+ /// 鑾峰彇杩涘害淇℃伅
+ /// </summary>
+ public string GetProgressInfo()
+ {
+ return _tyreStatistics?.GetProgressInfo() ?? "缁熻鍣ㄦ湭鍒濆鍖�";
+ }
+
+ #endregion
+
+ #region 閲嶅啓鏂规硶
+
+ public override bool Load(string fullPath = null)
+ {
+ bool result = base.Load(fullPath);
+ if (result)
+ {
+ // 鍔犺浇閰嶇疆鍚庨噸鏂板垵濮嬪寲缁熻鍣�
+ _tyreStatistics = new TyreStatistics(ImagesPerTyre, JudgeRule);
+ }
+ return result;
+ }
+
+ public override bool Save(string filePath = null)
+ {
+ return base.Save(filePath);
+ }
+
+ public override object Clone()
+ {
+ TyreCounterProcess clone = (TyreCounterProcess)MemberwiseClone();
+ clone._tyreStatistics = new TyreStatistics(ImagesPerTyre, JudgeRule);
+ return clone;
+ }
+
+ public override void Dispose()
+ {
+ _tyreStatistics = null;
+ base.Dispose();
+ }
+
+ #endregion
+ }
+}
diff --git a/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.Designer.cs b/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.Designer.cs
new file mode 100644
index 0000000..da63386
--- /dev/null
+++ b/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.Designer.cs
@@ -0,0 +1,567 @@
+namespace LB_VisionProcesses.Processes
+{
+ partial class TyreCounterProcessEdit
+ {
+ /// <summary>
+ /// 蹇呴渶鐨勮璁″櫒鍙橀噺銆�
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// 娓呯悊鎵�鏈夋鍦ㄤ娇鐢ㄧ殑璧勬簮銆�
+ /// </summary>
+ /// <param name="disposing">濡傛灉搴旈噴鏀炬墭绠¤祫婧愶紝涓� true锛涘惁鍒欎负 false銆�</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region 缁勪欢璁捐鍣ㄧ敓鎴愮殑浠g爜
+
+ /// <summary>
+ /// 璁捐鍣ㄦ敮鎸佹墍闇�鐨勬柟娉� - 涓嶈淇敼
+ /// 浣跨敤浠g爜缂栬緫鍣ㄤ慨鏀规鏂规硶鐨勫唴瀹广��
+ /// </summary>
+ private void InitializeComponent()
+ {
+ splitContainer1 = new SplitContainer();
+ groupBoxInputs = new GroupBox();
+ dataGridInputs = new DataGridView();
+ groupBoxConfig = new GroupBox();
+ tableLayoutPanelConfig = new TableLayoutPanel();
+ lblImagesPerTyre = new Label();
+ numericUpDownImagesPerTyre = new NumericUpDown();
+ lblJudgeRule = new Label();
+ comboBoxJudgeRule = new ComboBox();
+ checkBoxAutoReset = new CheckBox();
+ groupBoxStatistics = new GroupBox();
+ tableLayoutPanelStats = new TableLayoutPanel();
+ lblCurrentTyreID = new Label();
+ txtCurrentTyreID = new TextBox();
+ lblCurrentImageIndex = new Label();
+ txtCurrentImageIndex = new TextBox();
+ lblTyreTotal = new Label();
+ txtTyreTotal = new TextBox();
+ lblTyreOK = new Label();
+ txtTyreOK = new TextBox();
+ lblTyreNG = new Label();
+ txtTyreNG = new TextBox();
+ lblTyreRateOK = new Label();
+ txtTyreRateOK = new TextBox();
+ groupBoxOutputs = new GroupBox();
+ dataGridOutputs = new DataGridView();
+ topToolStrip = new ToolStrip();
+ btnRun = new ToolStripButton();
+ btnSave = new ToolStripButton();
+ btnReset = new ToolStripButton();
+ statusStrip = new StatusStrip();
+ lblResult = new ToolStripStatusLabel();
+ lblMsg = new ToolStripStatusLabel();
+ ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
+ splitContainer1.Panel1.SuspendLayout();
+ splitContainer1.Panel2.SuspendLayout();
+ splitContainer1.SuspendLayout();
+ groupBoxInputs.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)dataGridInputs).BeginInit();
+ groupBoxConfig.SuspendLayout();
+ tableLayoutPanelConfig.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)numericUpDownImagesPerTyre).BeginInit();
+ groupBoxStatistics.SuspendLayout();
+ tableLayoutPanelStats.SuspendLayout();
+ groupBoxOutputs.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)dataGridOutputs).BeginInit();
+ topToolStrip.SuspendLayout();
+ statusStrip.SuspendLayout();
+ SuspendLayout();
+ //
+ // splitContainer1
+ //
+ splitContainer1.BackColor = Color.FromArgb(32, 41, 50);
+ splitContainer1.Dock = DockStyle.Fill;
+ splitContainer1.Location = new Point(0, 31);
+ splitContainer1.Name = "splitContainer1";
+ //
+ // splitContainer1.Panel1
+ //
+ splitContainer1.Panel1.Controls.Add(groupBoxInputs);
+ //
+ // splitContainer1.Panel2
+ //
+ splitContainer1.Panel2.Controls.Add(groupBoxOutputs);
+ splitContainer1.Size = new Size(884, 458);
+ splitContainer1.SplitterDistance = 294;
+ splitContainer1.TabIndex = 0;
+ //
+ // groupBoxInputs
+ //
+ groupBoxInputs.BackColor = Color.FromArgb(32, 41, 50);
+ groupBoxInputs.Controls.Add(dataGridInputs);
+ groupBoxInputs.Dock = DockStyle.Fill;
+ groupBoxInputs.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ groupBoxInputs.ForeColor = SystemColors.Control;
+ groupBoxInputs.Location = new Point(0, 0);
+ groupBoxInputs.Name = "groupBoxInputs";
+ groupBoxInputs.Size = new Size(294, 458);
+ groupBoxInputs.TabIndex = 0;
+ groupBoxInputs.TabStop = false;
+ groupBoxInputs.Text = "杈撳叆鍙傛暟";
+ //
+ // dataGridInputs
+ //
+ dataGridInputs.BackgroundColor = Color.FromArgb(32, 46, 50);
+ dataGridInputs.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ dataGridInputs.Dock = DockStyle.Fill;
+ dataGridInputs.GridColor = SystemColors.Control;
+ dataGridInputs.Location = new Point(3, 24);
+ dataGridInputs.Name = "dataGridInputs";
+ dataGridInputs.Size = new Size(288, 431);
+ dataGridInputs.TabIndex = 0;
+ //
+ // groupBoxConfig
+ //
+ groupBoxConfig.BackColor = Color.FromArgb(32, 41, 50);
+ groupBoxConfig.Controls.Add(tableLayoutPanelConfig);
+ groupBoxConfig.Dock = DockStyle.Top;
+ groupBoxConfig.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ groupBoxConfig.ForeColor = SystemColors.Control;
+ groupBoxConfig.Location = new Point(0, 0);
+ groupBoxConfig.Name = "groupBoxConfig";
+ groupBoxConfig.Size = new Size(586, 180);
+ groupBoxConfig.TabIndex = 1;
+ groupBoxConfig.TabStop = false;
+ groupBoxConfig.Text = "閰嶇疆";
+ //
+ // tableLayoutPanelConfig
+ //
+ tableLayoutPanelConfig.ColumnCount = 2;
+ tableLayoutPanelConfig.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F));
+ tableLayoutPanelConfig.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
+ tableLayoutPanelConfig.Controls.Add(lblImagesPerTyre, 0, 0);
+ tableLayoutPanelConfig.Controls.Add(numericUpDownImagesPerTyre, 1, 0);
+ tableLayoutPanelConfig.Controls.Add(lblJudgeRule, 0, 1);
+ tableLayoutPanelConfig.Controls.Add(comboBoxJudgeRule, 1, 1);
+ tableLayoutPanelConfig.Controls.Add(checkBoxAutoReset, 1, 2);
+ tableLayoutPanelConfig.Dock = DockStyle.Fill;
+ tableLayoutPanelConfig.Location = new Point(3, 24);
+ tableLayoutPanelConfig.Name = "tableLayoutPanelConfig";
+ tableLayoutPanelConfig.RowCount = 3;
+ tableLayoutPanelConfig.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
+ tableLayoutPanelConfig.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
+ tableLayoutPanelConfig.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
+ tableLayoutPanelConfig.Size = new Size(580, 153);
+ tableLayoutPanelConfig.TabIndex = 0;
+ //
+ // lblImagesPerTyre
+ //
+ lblImagesPerTyre.AutoSize = true;
+ lblImagesPerTyre.Dock = DockStyle.Fill;
+ lblImagesPerTyre.Location = new Point(3, 0);
+ lblImagesPerTyre.Name = "lblImagesPerTyre";
+ lblImagesPerTyre.Size = new Size(144, 40);
+ lblImagesPerTyre.TabIndex = 0;
+ lblImagesPerTyre.Text = "姣忓紶杞儙鍥惧儚鏁�:";
+ lblImagesPerTyre.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // numericUpDownImagesPerTyre
+ //
+ numericUpDownImagesPerTyre.Location = new Point(153, 3);
+ numericUpDownImagesPerTyre.Maximum = new decimal(new int[] { 64, 0, 0, 0 });
+ numericUpDownImagesPerTyre.Minimum = new decimal(new int[] { 1, 0, 0, 0 });
+ numericUpDownImagesPerTyre.Name = "numericUpDownImagesPerTyre";
+ numericUpDownImagesPerTyre.Size = new Size(100, 29);
+ numericUpDownImagesPerTyre.TabIndex = 1;
+ numericUpDownImagesPerTyre.Value = new decimal(new int[] { 8, 0, 0, 0 });
+ //
+ // lblJudgeRule
+ //
+ lblJudgeRule.AutoSize = true;
+ lblJudgeRule.Dock = DockStyle.Fill;
+ lblJudgeRule.Location = new Point(3, 40);
+ lblJudgeRule.Name = "lblJudgeRule";
+ lblJudgeRule.Size = new Size(144, 40);
+ lblJudgeRule.TabIndex = 2;
+ lblJudgeRule.Text = "鍒ゅ畾瑙勫垯:";
+ lblJudgeRule.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // comboBoxJudgeRule
+ //
+ comboBoxJudgeRule.DropDownStyle = ComboBoxStyle.DropDownList;
+ comboBoxJudgeRule.FormattingEnabled = true;
+ comboBoxJudgeRule.Items.AddRange(new object[] { "AnyNG", "AllOK", "MajorityVote" });
+ comboBoxJudgeRule.Location = new Point(153, 43);
+ comboBoxJudgeRule.Name = "comboBoxJudgeRule";
+ comboBoxJudgeRule.Size = new Size(160, 29);
+ comboBoxJudgeRule.TabIndex = 3;
+ //
+ // checkBoxAutoReset
+ //
+ checkBoxAutoReset.AutoSize = true;
+ checkBoxAutoReset.Checked = true;
+ checkBoxAutoReset.CheckState = CheckState.Checked;
+ checkBoxAutoReset.Location = new Point(153, 83);
+ checkBoxAutoReset.Name = "checkBoxAutoReset";
+ checkBoxAutoReset.Size = new Size(161, 25);
+ checkBoxAutoReset.TabIndex = 4;
+ checkBoxAutoReset.Text = "瀹屾垚杞儙鑷姩閲嶇疆";
+ checkBoxAutoReset.UseVisualStyleBackColor = true;
+ //
+ // groupBoxStatistics
+ //
+ groupBoxStatistics.BackColor = Color.FromArgb(32, 41, 50);
+ groupBoxStatistics.Controls.Add(tableLayoutPanelStats);
+ groupBoxStatistics.Dock = DockStyle.Fill;
+ groupBoxStatistics.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ groupBoxStatistics.ForeColor = SystemColors.Control;
+ groupBoxStatistics.Location = new Point(0, 180);
+ groupBoxStatistics.Name = "groupBoxStatistics";
+ groupBoxStatistics.Size = new Size(586, 278);
+ groupBoxStatistics.TabIndex = 2;
+ groupBoxStatistics.TabStop = false;
+ groupBoxStatistics.Text = "缁熻淇℃伅";
+ //
+ // tableLayoutPanelStats
+ //
+ tableLayoutPanelStats.ColumnCount = 2;
+ tableLayoutPanelStats.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F));
+ tableLayoutPanelStats.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
+ tableLayoutPanelStats.Controls.Add(lblCurrentTyreID, 0, 0);
+ tableLayoutPanelStats.Controls.Add(txtCurrentTyreID, 1, 0);
+ tableLayoutPanelStats.Controls.Add(lblCurrentImageIndex, 0, 1);
+ tableLayoutPanelStats.Controls.Add(txtCurrentImageIndex, 1, 1);
+ tableLayoutPanelStats.Controls.Add(lblTyreTotal, 0, 2);
+ tableLayoutPanelStats.Controls.Add(txtTyreTotal, 1, 2);
+ tableLayoutPanelStats.Controls.Add(lblTyreOK, 0, 3);
+ tableLayoutPanelStats.Controls.Add(txtTyreOK, 1, 3);
+ tableLayoutPanelStats.Controls.Add(lblTyreNG, 0, 4);
+ tableLayoutPanelStats.Controls.Add(txtTyreNG, 1, 4);
+ tableLayoutPanelStats.Controls.Add(lblTyreRateOK, 0, 5);
+ tableLayoutPanelStats.Controls.Add(txtTyreRateOK, 1, 5);
+ tableLayoutPanelStats.Dock = DockStyle.Fill;
+ tableLayoutPanelStats.Location = new Point(3, 24);
+ tableLayoutPanelStats.Name = "tableLayoutPanelStats";
+ tableLayoutPanelStats.RowCount = 6;
+ tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
+ tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
+ tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
+ tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
+ tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
+ tableLayoutPanelStats.RowStyles.Add(new RowStyle(SizeType.Absolute, 35F));
+ tableLayoutPanelStats.Size = new Size(580, 251);
+ tableLayoutPanelStats.TabIndex = 0;
+ //
+ // lblCurrentTyreID
+ //
+ lblCurrentTyreID.AutoSize = true;
+ lblCurrentTyreID.Dock = DockStyle.Fill;
+ lblCurrentTyreID.Location = new Point(3, 0);
+ lblCurrentTyreID.Name = "lblCurrentTyreID";
+ lblCurrentTyreID.Size = new Size(144, 35);
+ lblCurrentTyreID.TabIndex = 0;
+ lblCurrentTyreID.Text = "褰撳墠杞儙ID:";
+ lblCurrentTyreID.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // txtCurrentTyreID
+ //
+ txtCurrentTyreID.BackColor = Color.FromArgb(32, 46, 50);
+ txtCurrentTyreID.BorderStyle = BorderStyle.FixedSingle;
+ txtCurrentTyreID.ForeColor = SystemColors.Control;
+ txtCurrentTyreID.Location = new Point(153, 3);
+ txtCurrentTyreID.Name = "txtCurrentTyreID";
+ txtCurrentTyreID.ReadOnly = true;
+ txtCurrentTyreID.Size = new Size(100, 29);
+ txtCurrentTyreID.TabIndex = 1;
+ txtCurrentTyreID.Text = "1";
+ //
+ // lblCurrentImageIndex
+ //
+ lblCurrentImageIndex.AutoSize = true;
+ lblCurrentImageIndex.Dock = DockStyle.Fill;
+ lblCurrentImageIndex.Location = new Point(3, 35);
+ lblCurrentImageIndex.Name = "lblCurrentImageIndex";
+ lblCurrentImageIndex.Size = new Size(144, 35);
+ lblCurrentImageIndex.TabIndex = 2;
+ lblCurrentImageIndex.Text = "褰撳墠鍥惧儚搴忓彿:";
+ lblCurrentImageIndex.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // txtCurrentImageIndex
+ //
+ txtCurrentImageIndex.BackColor = Color.FromArgb(32, 46, 50);
+ txtCurrentImageIndex.BorderStyle = BorderStyle.FixedSingle;
+ txtCurrentImageIndex.ForeColor = SystemColors.Control;
+ txtCurrentImageIndex.Location = new Point(153, 38);
+ txtCurrentImageIndex.Name = "txtCurrentImageIndex";
+ txtCurrentImageIndex.ReadOnly = true;
+ txtCurrentImageIndex.Size = new Size(100, 29);
+ txtCurrentImageIndex.TabIndex = 3;
+ txtCurrentImageIndex.Text = "0/8";
+ //
+ // lblTyreTotal
+ //
+ lblTyreTotal.AutoSize = true;
+ lblTyreTotal.Dock = DockStyle.Fill;
+ lblTyreTotal.Location = new Point(3, 70);
+ lblTyreTotal.Name = "lblTyreTotal";
+ lblTyreTotal.Size = new Size(144, 35);
+ lblTyreTotal.TabIndex = 4;
+ lblTyreTotal.Text = "杞儙鎬绘暟:";
+ lblTyreTotal.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // txtTyreTotal
+ //
+ txtTyreTotal.BackColor = Color.FromArgb(32, 46, 50);
+ txtTyreTotal.BorderStyle = BorderStyle.FixedSingle;
+ txtTyreTotal.ForeColor = SystemColors.Control;
+ txtTyreTotal.Location = new Point(153, 73);
+ txtTyreTotal.Name = "txtTyreTotal";
+ txtTyreTotal.ReadOnly = true;
+ txtTyreTotal.Size = new Size(100, 29);
+ txtTyreTotal.TabIndex = 5;
+ txtTyreTotal.Text = "0";
+ //
+ // lblTyreOK
+ //
+ lblTyreOK.AutoSize = true;
+ lblTyreOK.Dock = DockStyle.Fill;
+ lblTyreOK.ForeColor = Color.LightGreen;
+ lblTyreOK.Location = new Point(3, 105);
+ lblTyreOK.Name = "lblTyreOK";
+ lblTyreOK.Size = new Size(144, 35);
+ lblTyreOK.TabIndex = 6;
+ lblTyreOK.Text = "杞儙OK:";
+ lblTyreOK.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // txtTyreOK
+ //
+ txtTyreOK.BackColor = Color.FromArgb(32, 46, 50);
+ txtTyreOK.BorderStyle = BorderStyle.FixedSingle;
+ txtTyreOK.ForeColor = Color.LightGreen;
+ txtTyreOK.Location = new Point(153, 108);
+ txtTyreOK.Name = "txtTyreOK";
+ txtTyreOK.ReadOnly = true;
+ txtTyreOK.Size = new Size(100, 29);
+ txtTyreOK.TabIndex = 7;
+ txtTyreOK.Text = "0";
+ //
+ // lblTyreNG
+ //
+ lblTyreNG.AutoSize = true;
+ lblTyreNG.Dock = DockStyle.Fill;
+ lblTyreNG.ForeColor = Color.LightCoral;
+ lblTyreNG.Location = new Point(3, 140);
+ lblTyreNG.Name = "lblTyreNG";
+ lblTyreNG.Size = new Size(144, 35);
+ lblTyreNG.TabIndex = 8;
+ lblTyreNG.Text = "杞儙NG:";
+ lblTyreNG.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // txtTyreNG
+ //
+ txtTyreNG.BackColor = Color.FromArgb(32, 46, 50);
+ txtTyreNG.BorderStyle = BorderStyle.FixedSingle;
+ txtTyreNG.ForeColor = Color.LightCoral;
+ txtTyreNG.Location = new Point(153, 143);
+ txtTyreNG.Name = "txtTyreNG";
+ txtTyreNG.ReadOnly = true;
+ txtTyreNG.Size = new Size(100, 29);
+ txtTyreNG.TabIndex = 9;
+ txtTyreNG.Text = "0";
+ //
+ // lblTyreRateOK
+ //
+ lblTyreRateOK.AutoSize = true;
+ lblTyreRateOK.Dock = DockStyle.Fill;
+ lblTyreRateOK.Location = new Point(3, 175);
+ lblTyreRateOK.Name = "lblTyreRateOK";
+ lblTyreRateOK.Size = new Size(144, 35);
+ lblTyreRateOK.TabIndex = 10;
+ lblTyreRateOK.Text = "鑹搧鐜�:";
+ lblTyreRateOK.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // txtTyreRateOK
+ //
+ txtTyreRateOK.BackColor = Color.FromArgb(32, 46, 50);
+ txtTyreRateOK.BorderStyle = BorderStyle.FixedSingle;
+ txtTyreRateOK.ForeColor = SystemColors.Control;
+ txtTyreRateOK.Location = new Point(153, 178);
+ txtTyreRateOK.Name = "txtTyreRateOK";
+ txtTyreRateOK.ReadOnly = true;
+ txtTyreRateOK.Size = new Size(100, 29);
+ txtTyreRateOK.TabIndex = 11;
+ txtTyreRateOK.Text = "0.00%";
+ //
+ // groupBoxOutputs
+ //
+ groupBoxOutputs.BackColor = Color.FromArgb(32, 41, 50);
+ groupBoxOutputs.Controls.Add(groupBoxStatistics);
+ groupBoxOutputs.Controls.Add(groupBoxConfig);
+ groupBoxOutputs.Dock = DockStyle.Fill;
+ groupBoxOutputs.Font = new Font("Microsoft YaHei UI", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ groupBoxOutputs.ForeColor = SystemColors.Control;
+ groupBoxOutputs.Location = new Point(0, 0);
+ groupBoxOutputs.Name = "groupBoxOutputs";
+ groupBoxOutputs.Size = new Size(586, 458);
+ groupBoxOutputs.TabIndex = 0;
+ groupBoxOutputs.TabStop = false;
+ groupBoxOutputs.Text = "杈撳嚭涓庨厤缃�";
+ //
+ // dataGridOutputs
+ //
+ dataGridOutputs.BackgroundColor = Color.FromArgb(32, 46, 50);
+ dataGridOutputs.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ dataGridOutputs.Dock = DockStyle.Fill;
+ dataGridOutputs.GridColor = SystemColors.Control;
+ dataGridOutputs.Location = new Point(3, 24);
+ dataGridOutputs.Name = "dataGridOutputs";
+ dataGridOutputs.Size = new Size(580, 431);
+ dataGridOutputs.TabIndex = 0;
+ //
+ // topToolStrip
+ //
+ topToolStrip.BackColor = Color.FromArgb(32, 41, 50);
+ topToolStrip.GripStyle = ToolStripGripStyle.Hidden;
+ topToolStrip.Items.AddRange(new ToolStripItem[] { btnRun, btnSave, btnReset });
+ topToolStrip.Location = new Point(0, 0);
+ topToolStrip.Name = "topToolStrip";
+ topToolStrip.Size = new Size(884, 31);
+ topToolStrip.TabIndex = 1;
+ topToolStrip.Text = "toolStrip1";
+ //
+ // btnRun
+ //
+ btnRun.DisplayStyle = ToolStripItemDisplayStyle.Text;
+ btnRun.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ btnRun.ForeColor = SystemColors.Control;
+ btnRun.ImageTransparentColor = Color.Magenta;
+ btnRun.Name = "btnRun";
+ btnRun.Size = new Size(41, 28);
+ btnRun.Text = "杩愯";
+ btnRun.Click += btnRun_Click;
+ //
+ // btnSave
+ //
+ btnSave.DisplayStyle = ToolStripItemDisplayStyle.Text;
+ btnSave.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ btnSave.ForeColor = SystemColors.Control;
+ btnSave.ImageTransparentColor = Color.Magenta;
+ btnSave.Name = "btnSave";
+ btnSave.Size = new Size(41, 28);
+ btnSave.Text = "淇濆瓨";
+ btnSave.Click += btnSave_Click;
+ //
+ // btnReset
+ //
+ btnReset.DisplayStyle = ToolStripItemDisplayStyle.Text;
+ btnReset.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ btnReset.ForeColor = SystemColors.Control;
+ btnReset.ImageTransparentColor = Color.Magenta;
+ btnReset.Name = "btnReset";
+ btnReset.Size = new Size(73, 28);
+ btnReset.Text = "閲嶇疆璁℃暟";
+ btnReset.Click += btnReset_Click;
+ //
+ // statusStrip
+ //
+ statusStrip.BackColor = Color.FromArgb(32, 41, 50);
+ statusStrip.Items.AddRange(new ToolStripItem[] { lblResult, lblMsg });
+ statusStrip.Location = new Point(0, 489);
+ statusStrip.Name = "statusStrip";
+ statusStrip.Size = new Size(884, 30);
+ statusStrip.TabIndex = 2;
+ statusStrip.Text = "statusStrip1";
+ //
+ // lblResult
+ //
+ lblResult.AutoSize = false;
+ lblResult.BackColor = Color.FromArgb(32, 41, 50);
+ lblResult.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ lblResult.ForeColor = SystemColors.Control;
+ lblResult.Name = "lblResult";
+ lblResult.Size = new Size(100, 25);
+ lblResult.Text = "缁撴灉: --";
+ //
+ // lblMsg
+ //
+ lblMsg.BackColor = Color.FromArgb(32, 41, 50);
+ lblMsg.Font = new Font("Microsoft YaHei UI", 10F, FontStyle.Regular, GraphicsUnit.Point, 134);
+ lblMsg.ForeColor = SystemColors.Control;
+ lblMsg.Name = "lblMsg";
+ lblMsg.Size = new Size(769, 25);
+ lblMsg.Spring = true;
+ lblMsg.Text = "灏辩华";
+ lblMsg.TextAlign = ContentAlignment.MiddleLeft;
+ //
+ // TyreCounterProcessEdit
+ //
+ AutoScaleDimensions = new SizeF(9F, 20F);
+ AutoScaleMode = AutoScaleMode.Font;
+ BackColor = Color.FromArgb(32, 41, 50);
+ Controls.Add(splitContainer1);
+ Controls.Add(topToolStrip);
+ Controls.Add(statusStrip);
+ Name = "TyreCounterProcessEdit";
+ Size = new Size(884, 519);
+ Load += TyreCounterProcessEdit_Load;
+ splitContainer1.Panel1.ResumeLayout(false);
+ splitContainer1.Panel2.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
+ splitContainer1.ResumeLayout(false);
+ groupBoxInputs.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)dataGridInputs).EndInit();
+ groupBoxConfig.ResumeLayout(false);
+ tableLayoutPanelConfig.ResumeLayout(false);
+ tableLayoutPanelConfig.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)numericUpDownImagesPerTyre).EndInit();
+ groupBoxStatistics.ResumeLayout(false);
+ tableLayoutPanelStats.ResumeLayout(false);
+ tableLayoutPanelStats.PerformLayout();
+ groupBoxOutputs.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)dataGridOutputs).EndInit();
+ topToolStrip.ResumeLayout(false);
+ topToolStrip.PerformLayout();
+ statusStrip.ResumeLayout(false);
+ statusStrip.PerformLayout();
+ ResumeLayout(false);
+ statusStrip.PerformLayout();
+ }
+
+ #endregion
+
+ private SplitContainer splitContainer1;
+ private GroupBox groupBoxInputs;
+ private DataGridView dataGridInputs;
+ private GroupBox groupBoxOutputs;
+ private DataGridView dataGridOutputs;
+ private ToolStrip topToolStrip;
+ private ToolStripButton btnRun;
+ private ToolStripButton btnSave;
+ private ToolStripButton btnReset;
+ private StatusStrip statusStrip;
+ private ToolStripStatusLabel lblResult;
+ private ToolStripStatusLabel lblMsg;
+ private GroupBox groupBoxConfig;
+ private TableLayoutPanel tableLayoutPanelConfig;
+ private Label lblImagesPerTyre;
+ private NumericUpDown numericUpDownImagesPerTyre;
+ private Label lblJudgeRule;
+ private ComboBox comboBoxJudgeRule;
+ private CheckBox checkBoxAutoReset;
+ private GroupBox groupBoxStatistics;
+ private TableLayoutPanel tableLayoutPanelStats;
+ private Label lblCurrentTyreID;
+ private TextBox txtCurrentTyreID;
+ private Label lblCurrentImageIndex;
+ private TextBox txtCurrentImageIndex;
+ private Label lblTyreTotal;
+ private TextBox txtTyreTotal;
+ private Label lblTyreOK;
+ private TextBox txtTyreOK;
+ private Label lblTyreNG;
+ private TextBox txtTyreNG;
+ private Label lblTyreRateOK;
+ private TextBox txtTyreRateOK;
+ }
+}
diff --git a/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.cs b/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.cs
new file mode 100644
index 0000000..e93c114
--- /dev/null
+++ b/LB_VisionProcesses/Processes/TyreCounter/TyreCounterProcessEdit.cs
@@ -0,0 +1,161 @@
+using LB_VisionProcesses.Alogrithms;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace LB_VisionProcesses.Processes
+{
+ /// <summary>
+ /// 杞儙璁℃暟宸ュ叿缂栬緫鍣�
+ /// </summary>
+ public partial class TyreCounterProcessEdit : TAlgorithmEdit
+ {
+ DataTable DataTableInputs = new DataTable();
+ DataTable DataTableOutputs = new DataTable();
+
+ public TyreCounterProcessEdit(TyreCounterProcess subject = null)
+ {
+ InitializeComponent();
+ if (subject == null)
+ subject = new TyreCounterProcess();
+
+ this.Subject = subject;
+ }
+
+ private void TyreCounterProcessEdit_Load(object sender, EventArgs e)
+ {
+ LoadParas();
+ }
+
+ /// <summary>
+ /// 鍔犺浇鍙傛暟
+ /// </summary>
+ public override void LoadParas()
+ {
+ if (Subject is TyreCounterProcess counter)
+ {
+ // 鍔犺浇閰嶇疆鍙傛暟
+ numericUpDownImagesPerTyre.Value = counter.ImagesPerTyre;
+ comboBoxJudgeRule.SelectedItem = counter.JudgeRule.ToString();
+ checkBoxAutoReset.Checked = counter.AutoReset;
+
+ // 鍔犺浇缁熻淇℃伅
+ UpdateStatistics();
+
+ // 缁戝畾杈撳叆鍙傛暟
+ DataTableInputs.Columns.Add("Key", typeof(string));
+ DataTableInputs.Columns.Add("Value", typeof(object));
+ DataTableInputs.Rows.Clear();
+
+ var inputs = new Dictionary<string, object>
+ {
+ { "ImagesPerTyre", counter.ImagesPerTyre },
+ { "JudgeRule", counter.JudgeRule.ToString() },
+ { "AutoReset", counter.AutoReset }
+ };
+
+ foreach (var item in inputs)
+ DataTableInputs.Rows.Add(item.Key, item.Value);
+
+ dataGridInputs.DataSource = DataTableInputs;
+
+ // 缁戝畾杈撳嚭鍙傛暟
+ DataTableOutputs.Columns.Add("Key", typeof(string));
+ DataTableOutputs.Columns.Add("Value", typeof(object));
+ DataTableOutputs.Rows.Clear();
+
+ var outputs = new Dictionary<string, object>
+ {
+ { "CurrentTyreID", counter.CurrentTyreID },
+ { "CurrentImageIndex", counter.CurrentImageIndex },
+ { "IsTyreComplete", counter.IsTyreComplete },
+ { "TyreResult", counter.TyreResult },
+ { "TyreTotal", counter.TyreTotal },
+ { "TyreOK", counter.TyreOK },
+ { "TyreNG", counter.TyreNG },
+ { "TyreRateOK", counter.TyreRateOK }
+ };
+
+ foreach (var item in outputs)
+ DataTableOutputs.Rows.Add(item.Key, item.Value);
+
+ dataGridOutputs.DataSource = DataTableOutputs;
+
+ // 璁剧疆鐘舵�佹爮
+ lblResult.Text = $"缁撴灉: {(counter.Result ? "OK" : "NG")}";
+ lblResult.ForeColor = counter.Result ? Color.LightGreen : Color.LightCoral;
+ lblMsg.Text = counter.Msg;
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊缁熻淇℃伅鏄剧ず
+ /// </summary>
+ private void UpdateStatistics()
+ {
+ if (Subject is TyreCounterProcess counter)
+ {
+ txtCurrentTyreID.Text = counter.CurrentTyreID.ToString();
+ txtCurrentImageIndex.Text = $"{counter.CurrentImageIndex}/{counter.ImagesPerTyre}";
+ txtTyreTotal.Text = counter.TyreTotal.ToString();
+ txtTyreOK.Text = counter.TyreOK.ToString();
+ txtTyreNG.Text = counter.TyreNG.ToString();
+ txtTyreRateOK.Text = $"{counter.TyreRateOK:F2}%";
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊杈撳叆鍙傛暟
+ /// </summary>
+ public override void UpdataInputs()
+ {
+ if (Subject is TyreCounterProcess counter)
+ {
+ counter.ImagesPerTyre = (int)numericUpDownImagesPerTyre.Value;
+ counter.JudgeRule = (TyreJudgeRule)Enum.Parse(typeof(TyreJudgeRule), comboBoxJudgeRule.SelectedItem?.ToString() ?? "AnyNG");
+ counter.AutoReset = checkBoxAutoReset.Checked;
+
+ // 鏇存柊杈撳叆鍙傛暟琛�
+ Subject.Params.Inputs["ImagesPerTyre"] = counter.ImagesPerTyre;
+ Subject.Params.Inputs["JudgeRule"] = counter.JudgeRule.ToString();
+ Subject.Params.Inputs["AutoReset"] = counter.AutoReset;
+ }
+ }
+
+ private void btnSave_Click(object sender, EventArgs e)
+ {
+ UpdataInputs();
+ lblMsg.Text = "鍙傛暟宸蹭繚瀛�";
+ lblMsg.ForeColor = Color.LightGreen;
+ }
+
+ private void btnReset_Click(object sender, EventArgs e)
+ {
+ if (Subject is TyreCounterProcess counter)
+ {
+ counter.ResetTyreCount();
+ UpdateStatistics();
+ LoadParas();
+ lblMsg.Text = "璁℃暟鍣ㄥ凡閲嶇疆";
+ lblMsg.ForeColor = Color.LightGreen;
+ }
+ }
+
+ private void btnRun_Click(object sender, EventArgs e)
+ {
+ UpdataInputs();
+ Subject.Run();
+ UpdateStatistics();
+ LoadParas();
+ lblResult.Text = $"缁撴灉: {(Subject.Result ? "OK" : "NG")}";
+ lblResult.ForeColor = Subject.Result ? Color.LightGreen : Color.LightCoral;
+ lblMsg.Text = Subject.Msg;
+ }
+ }
+}
diff --git a/LB_VisionProcesses/Processes/TyreCounter/TyreStatistics.cs b/LB_VisionProcesses/Processes/TyreCounter/TyreStatistics.cs
new file mode 100644
index 0000000..6e1950c
--- /dev/null
+++ b/LB_VisionProcesses/Processes/TyreCounter/TyreStatistics.cs
@@ -0,0 +1,266 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace LB_VisionProcesses.Processes
+{
+ /// <summary>
+ /// 杞儙鍒ゅ畾瑙勫垯
+ /// </summary>
+ public enum TyreJudgeRule
+ {
+ /// <summary>
+ /// 浠讳竴NG鍒欐暣鑳嶯G
+ /// </summary>
+ AnyNG,
+
+ /// <summary>
+ /// 鍏ㄩ儴OK鎵嶆暣鑳嶰K
+ /// </summary>
+ AllOK,
+
+ /// <summary>
+ /// 澶氭暟琛ㄥ喅锛堣秴杩囧崐鏁癘K鍒橭K锛�
+ /// </summary>
+ MajorityVote
+ }
+
+ /// <summary>
+ /// 杞儙璁℃暟缁撴灉
+ /// </summary>
+ public class TyreCountResult
+ {
+ /// <summary>
+ /// 鏄惁瀹屾垚涓�涓疆鑳�
+ /// </summary>
+ public bool IsTyreComplete { get; set; }
+
+ /// <summary>
+ /// 杞儙ID
+ /// </summary>
+ public int TyreID { get; set; }
+
+ /// <summary>
+ /// 杞儙鏁翠綋缁撴灉
+ /// </summary>
+ public bool TyreResult { get; set; }
+
+ /// <summary>
+ /// 鍚勫浘鍍忕粨鏋滃垪琛�
+ /// </summary>
+ public List<bool> ImageResults { get; set; } = new List<bool>();
+
+ /// <summary>
+ /// 褰撳墠鍥惧儚搴忓彿锛�1~n锛�
+ /// </summary>
+ public int CurrentImageIndex { get; set; }
+
+ /// <summary>
+ /// 娑堟伅
+ /// </summary>
+ public string Message { get; set; }
+ }
+
+ /// <summary>
+ /// 杞儙缁熻鍣� - 鐢ㄤ簬绠$悊杞儙绾у埆鐨勮鏁板拰缁熻
+ /// </summary>
+ public class TyreStatistics
+ {
+ #region 閰嶇疆鍙傛暟
+
+ /// <summary>
+ /// 姣忓紶杞儙鎵�闇�鍥惧儚鏁帮紙榛樿8寮狅級
+ /// </summary>
+ public int ImagesPerTyre { get; set; } = 8;
+
+ /// <summary>
+ /// 鍒ゅ畾瑙勫垯
+ /// </summary>
+ public TyreJudgeRule JudgeRule { get; set; } = TyreJudgeRule.AnyNG;
+
+ #endregion
+
+ #region 缁熻鏁版嵁
+
+ /// <summary>
+ /// 杞儙鎬绘暟
+ /// </summary>
+ public int TyreTotal => TyreOK + TyreNG;
+
+ /// <summary>
+ /// 杞儙OK璁℃暟
+ /// </summary>
+ public int TyreOK { get; set; }
+
+ /// <summary>
+ /// 杞儙NG璁℃暟
+ /// </summary>
+ public int TyreNG { get; set; }
+
+ /// <summary>
+ /// 褰撳墠杞儙ID锛堜粠1寮�濮嬶級
+ /// </summary>
+ public int CurrentTyreID { get; set; } = 1;
+
+ /// <summary>
+ /// 褰撳墠杞儙鐨勫浘鍍忓簭鍙凤紙0~ImagesPerTyre-1锛�
+ /// </summary>
+ public int CurrentImageIndex { get; set; } = 0;
+
+ /// <summary>
+ /// 褰撳墠杞儙鐨勫悇鍥惧儚缁撴灉
+ /// </summary>
+ public List<bool> CurrentTyreResults { get; set; } = new List<bool>();
+
+ /// <summary>
+ /// 褰撳墠杞儙鐨勫悇鍥惧儚SN
+ /// </summary>
+ public List<string> CurrentTyreImageSNs { get; set; } = new List<string>();
+
+ /// <summary>
+ /// 杞儙鑹搧鐜�
+ /// </summary>
+ public double TyreRateOK => TyreTotal > 0 ? (TyreOK / (double)TyreTotal) * 100 : 0;
+
+ #endregion
+
+ #region 鏋勯�犳柟娉�
+
+ public TyreStatistics() { }
+
+ public TyreStatistics(int imagesPerTyre, TyreJudgeRule judgeRule = TyreJudgeRule.AnyNG)
+ {
+ ImagesPerTyre = imagesPerTyre;
+ JudgeRule = judgeRule;
+ }
+
+ #endregion
+
+ #region 鏍稿績鏂规硶
+
+ /// <summary>
+ /// 娣诲姞鍥惧儚妫�娴嬬粨鏋�
+ /// </summary>
+ /// <param name="isOK">鍥惧儚妫�娴嬬粨鏋�</param>
+ /// <param name="imageSN">鍥惧儚搴忓垪鍙凤紙鍙�夛級</param>
+ /// <returns>杞儙璁℃暟缁撴灉</returns>
+ public TyreCountResult AddImageResult(bool isOK, string imageSN = null)
+ {
+ // 娣诲姞鍒板綋鍓嶈疆鑳庣粨鏋滃垪琛�
+ CurrentTyreResults.Add(isOK);
+ CurrentTyreImageSNs.Add(imageSN);
+ CurrentImageIndex++;
+
+ var result = new TyreCountResult
+ {
+ CurrentImageIndex = CurrentImageIndex,
+ IsTyreComplete = false,
+ Message = $"褰撳墠杞儙绗� {CurrentImageIndex}/{ImagesPerTyre} 寮犲浘鍍�"
+ };
+
+ // 妫�鏌ユ槸鍚﹀畬鎴愪竴涓疆鑳�
+ if (CurrentImageIndex >= ImagesPerTyre)
+ {
+ // 璁$畻杞儙鏁翠綋缁撴灉
+ bool tyreResult = CalculateTyreResult();
+
+ // 鏇存柊缁熻
+ if (tyreResult)
+ TyreOK++;
+ else
+ TyreNG++;
+
+ // 鏋勫缓瀹屾垚缁撴灉
+ result.IsTyreComplete = true;
+ result.TyreID = CurrentTyreID;
+ result.TyreResult = tyreResult;
+ result.ImageResults = new List<bool>(CurrentTyreResults);
+ result.Message = $"瀹屾垚杞儙 #{CurrentTyreID}锛岀粨鏋�: {(tyreResult ? "OK" : "NG")}";
+
+ // 閲嶇疆褰撳墠杞儙鏁版嵁
+ ResetCurrentTyre();
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// 璁$畻杞儙鏁翠綋缁撴灉
+ /// </summary>
+ private bool CalculateTyreResult()
+ {
+ if (CurrentTyreResults.Count == 0)
+ return true;
+
+ switch (JudgeRule)
+ {
+ case TyreJudgeRule.AnyNG:
+ // n寮犱腑浠讳竴NG鍒欐暣鑳嶯G
+ return !CurrentTyreResults.Any(r => !r);
+
+ case TyreJudgeRule.AllOK:
+ // 鍏ㄩ儴OK鎵嶆暣鑳嶰K锛堜笌AnyNG鐩稿悓锛�
+ return CurrentTyreResults.All(r => r);
+
+ case TyreJudgeRule.MajorityVote:
+ // 澶氭暟琛ㄥ喅锛氳秴杩囧崐鏁癘K鍒橭K
+ int okCount = CurrentTyreResults.Count(r => r);
+ return okCount > (CurrentTyreResults.Count / 2.0);
+
+ default:
+ return !CurrentTyreResults.Any(r => !r);
+ }
+ }
+
+ /// <summary>
+ /// 閲嶇疆褰撳墠杞儙鏁版嵁
+ /// </summary>
+ private void ResetCurrentTyre()
+ {
+ CurrentTyreID++;
+ CurrentImageIndex = 0;
+ CurrentTyreResults.Clear();
+ CurrentTyreImageSNs.Clear();
+ }
+
+ /// <summary>
+ /// 閲嶇疆鎵�鏈夌粺璁�
+ /// </summary>
+ public void Reset()
+ {
+ TyreOK = 0;
+ TyreNG = 0;
+ CurrentTyreID = 1;
+ ResetCurrentTyre();
+ }
+
+ /// <summary>
+ /// 娓呯┖褰撳墠杞儙锛堢敤浜庡紓甯告儏鍐碉級
+ /// </summary>
+ public void ClearCurrentTyre()
+ {
+ ResetCurrentTyre();
+ }
+
+ /// <summary>
+ /// 鑾峰彇褰撳墠杩涘害淇℃伅
+ /// </summary>
+ public string GetProgressInfo()
+ {
+ if (ImagesPerTyre <= 1)
+ return $"杞儙 #{CurrentTyreID} (3D妯″紡)";
+
+ return $"杞儙 #{CurrentTyreID} - 绗� {CurrentImageIndex}/{ImagesPerTyre} 寮�";
+ }
+
+ /// <summary>
+ /// 鑾峰彇缁熻淇℃伅瀛楃涓�
+ /// </summary>
+ public string GetStatisticsInfo()
+ {
+ return $"杞儙鎬绘暟: {TyreTotal}, OK: {TyreOK}, NG: {TyreNG}, 鑹搧鐜�: {TyreRateOK:F2}%";
+ }
+
+ #endregion
+ }
+}
--
Gitblit v1.9.3