150 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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("检测协调器已关闭。");
 | ||
|         }
 | ||
|     }
 | ||
| }
 |