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>
|
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
|
{
|
// 获取输入结果(从前置节点的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;
|
}
|
}
|
|
/// <summary>
|
/// 获取输入结果(从前置节点传递的Result)
|
/// </summary>
|
private void GetInputResult()
|
{
|
// 如果InputImage是bool类型,说明前置节点传递了结果
|
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
|
}
|
}
|