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 { /// /// 轮胎计数工具 - 用于流程节点中统计轮胎数量 /// public class TyreCounterProcess : BaseProcess { #region 配置属性 /// /// 每张轮胎所需图像数 /// public int ImagesPerTyre { get { if (Params.Inputs.ContainsKey("ImagesPerTyre")) return Convert.ToInt32(Params.Inputs["ImagesPerTyre"]); return 8; } set { Params.Inputs["ImagesPerTyre"] = value; } } /// /// 判定规则 /// 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(); } } /// /// 是否自动重置(完成一个轮胎后自动重置计数) /// public bool AutoReset { get { if (Params.Inputs.ContainsKey("AutoReset")) return Convert.ToBoolean(Params.Inputs["AutoReset"]); return true; } set { Params.Inputs["AutoReset"] = value; } } #endregion #region 输出属性 /// /// 当前轮胎ID /// public int CurrentTyreID { get { if (Params.Outputs.ContainsKey("CurrentTyreID")) return Convert.ToInt32(Params.Outputs["CurrentTyreID"]); return 1; } private set { Params.Outputs["CurrentTyreID"] = value; } } /// /// 当前图像序号(1~n) /// public int CurrentImageIndex { get { if (Params.Outputs.ContainsKey("CurrentImageIndex")) return Convert.ToInt32(Params.Outputs["CurrentImageIndex"]); return 0; } private set { Params.Outputs["CurrentImageIndex"] = value; } } /// /// 是否完成轮胎 /// public bool IsTyreComplete { get { if (Params.Outputs.ContainsKey("IsTyreComplete")) return Convert.ToBoolean(Params.Outputs["IsTyreComplete"]); return false; } private set { Params.Outputs["IsTyreComplete"] = value; } } /// /// 轮胎结果 /// public bool TyreResult { get { if (Params.Outputs.ContainsKey("TyreResult")) return Convert.ToBoolean(Params.Outputs["TyreResult"]); return false; } private set { Params.Outputs["TyreResult"] = value; } } /// /// 轮胎总数 /// public int TyreTotal { get { if (Params.Outputs.ContainsKey("TyreTotal")) return Convert.ToInt32(Params.Outputs["TyreTotal"]); return 0; } private set { Params.Outputs["TyreTotal"] = value; } } /// /// 轮胎OK数 /// public int TyreOK { get { if (Params.Outputs.ContainsKey("TyreOK")) return Convert.ToInt32(Params.Outputs["TyreOK"]); return 0; } private set { Params.Outputs["TyreOK"] = value; } } /// /// 轮胎NG数 /// public int TyreNG { get { if (Params.Outputs.ContainsKey("TyreNG")) return Convert.ToInt32(Params.Outputs["TyreNG"]); return 0; } private set { Params.Outputs["TyreNG"] = value; } } /// /// 良品率 /// 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 私有字段 /// /// 轮胎统计器实例 /// private TyreStatistics? _tyreStatistics; /// /// 输入的图像结果(从前置节点获取) /// private bool _inputImageResult = true; #endregion #region 构造方法 public TyreCounterProcess() { strProcessClass = "LB_VisionProcesses.Processes.TyreCounterProcess"; _tyreStatistics = new TyreStatistics(); InitParams(); } /// /// 初始化参数 /// 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 核心方法 /// /// 运行轮胎计数逻辑 /// public override bool Run() { DateTime startTime = DateTime.Now; try { // 获取输入结果(从前置节点的Result参数) 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; } } /// /// 获取输入结果(从前置节点传递的Result) /// private void GetInputResult() { // 如果InputImage是bool类型,说明前置节点传递了结果 if (InputImage is bool boolResult) { _inputImageResult = boolResult; } else { // 默认认为OK _inputImageResult = true; } } /// /// 更新输出参数 /// 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; } /// /// 初始化运行参数 /// public override void InitRunParams() { base.InitRunParams(); _inputImageResult = true; } /// /// 重置轮胎计数 /// public void ResetTyreCount() { _tyreStatistics?.Reset(); UpdateOutputs(new TyreCountResult()); } /// /// 获取统计信息 /// public string GetStatisticsInfo() { return _tyreStatistics?.GetStatisticsInfo() ?? "统计器未初始化"; } /// /// 获取进度信息 /// 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 } }