Files
CheckDevice/Check.Main/Infer/DetectionCoordinator.cs
17860779768 2e46747ba9 视觉修改
2025-08-25 16:33:58 +08:00

150 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Check.Main.Camera;
using Check.Main.Common;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Check.Main.Infer
{
public static class DetectionCoordinator
{
/// <summary>
/// 定义存储所有相机处理器的字典
/// 键是相机的唯一编号 (CameraIndex),值是对应的处理器实例。
/// </summary>
private static ConcurrentDictionary<int, CameraProcessor> _processors = new ConcurrentDictionary<int, CameraProcessor>();
/// <summary>
/// 用于在产品组装时进行同步,确保线程安全
/// </summary>
private static ConcurrentDictionary<long, ProductAssembly> _productAssemblies = new ConcurrentDictionary<long, ProductAssembly>();
/// <summary>
/// 可用的相机数量
/// </summary>
private static int _enabledCameraCount = 0;
public static event EventHandler<DetectionResultEventArgs> OnDetectionCompleted;
public static bool IsDetectionRunning { get; private set; } = false;
// OnDetectionCompleted 事件现在也属于这里
//public static event EventHandler<DetectionResultEventArgs> OnDetectionCompleted;
public static void StartDetection()
{
if (!IsDetectionRunning)
{
IsDetectionRunning = true;
ThreadSafeLogger.Log("检测统计已启动。");
}
}
public static void StopDetection()
{
if (IsDetectionRunning)
{
IsDetectionRunning = false;
ThreadSafeLogger.Log("检测统计已停止。");
}
}
public static void Initialize(List<CameraSettings> cameraSettings, List<ModelSettings> modelSettings)
{
Shutdown(); // 先关闭旧的
var enabledCameras = cameraSettings.Where(c => c.IsEnabled).ToList();
_enabledCameraCount = enabledCameras.Count;
if (_enabledCameraCount == 0) return;
foreach (var camSetting in enabledCameras)
{
// 找到与相机编号匹配的模型
var model = modelSettings.FirstOrDefault(m => m.Id == camSetting.ModelID);
if (model == null)
{
ThreadSafeLogger.Log($"[警告] 找不到与相机 #{camSetting.CameraIndex} 匹配的模型,该相机将无法处理图像。");
continue;
}
var processor = new CameraProcessor(camSetting.CameraIndex,camSetting.ModelID);
_processors.TryAdd(camSetting.CameraIndex, processor);
processor.Start();
}
ThreadSafeLogger.Log($"检测协调器已初始化,启动了 {_processors.Count} 个相机处理线程。");
}
public static void EnqueueImage(int cameraIndex, Bitmap bmp)
{
if (_processors.TryGetValue(cameraIndex, out var processor))
{
processor.EnqueueImage(bmp);
}
else
{
// 如果找不到处理器必须释放Bitmap防止泄漏
bmp?.Dispose();
}
}
// 供 CameraProcessor 回调,用以组装产品
public static void AssembleProduct(ImageData data, string result)
{
var assembly = _productAssemblies.GetOrAdd(data.ProductId, (id) => new ProductAssembly(id, _enabledCameraCount));
if (assembly.AddResult(data.CameraIndex, result))
{
string finalResult = assembly.GetFinalResult();
ThreadSafeLogger.Log($"产品 #{assembly.ProductId} 已检测完毕,最终结果: {finalResult}");
// 只有在检测运行时,才触发事件
if (IsDetectionRunning)
{
OnDetectionCompleted?.Invoke(null, new DetectionResultEventArgs(finalResult == "OK"));
}
if (_productAssemblies.TryRemove(assembly.ProductId, out var finishedAssembly))
{
finishedAssembly.Dispose();
}
}
}
/// <summary>
/// 命令所有活动的相机处理器重置它们的内部计数器。
/// </summary>
public static void ResetAllCounters()
{
foreach (var processor in _processors.Values)
{
processor.ResetCounter();
}
ThreadSafeLogger.Log("所有相机处理器的产品计数器已重置。");
}
public static CameraProcessor GetProcessor(int cameraIndex)
{
_processors.TryGetValue(cameraIndex, out var p);
return p;
}
public static IEnumerable<CameraProcessor> GetAllProcessors()
{
return _processors.Values;
}
public static void Shutdown()
{
foreach (var processor in _processors.Values)
{
processor.Dispose();
}
_processors.Clear();
foreach (var assembly in _productAssemblies.Values)
{
assembly.Dispose();
}
_productAssemblies.Clear();
ThreadSafeLogger.Log("检测协调器已关闭。");
}
}
}