using AI.Common; using AI.Common.Log; using AIDiagnosis.Common.Enums; using AIDiagnosis.Common.Models; using CarotidArterySectionClassificationLib; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Threading; using Vinno.AI.CarotidClassificationSDK.Interfaces; using Vinno.AI.CarotidClassificationSDK.Models; using Vinno.AI.CarotidClassificationService.Tools; using Vinno.AI.CommonSDK.Enums; using Vinno.AI.CommonSDK.Models; using Vinno.AI.CommonSDK.Tools; using Vinno.AI.Service.Common.Interfaces; using Vinno.AI.Service.Common.Models; using Vinno.AI.Service.Common.Tools; using CarotidClassification = CarotidClassificationSDK.CarotidClassification; namespace Vinno.AI.CarotidClassificationService { public class CarotidClassificationService : ICarotidClassificationService, IDisposable, IEngine { private readonly ConcurrentStack _singleImageCache; private readonly string _modelFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks"); private PipeServer _singleImagePipeServer; private ImageProvider _imageProvider; private CarotidClassification _carotidClassification; private bool _disposed; public static List AllFunctions { get; } static CarotidClassificationService() { AllFunctions = CarotidClassification.AllFunctions; } public static void Init(FunctionInfo enableFunction, FunctionInfo currentUsedFunction) { CarotidClassification.Init(enableFunction, currentUsedFunction); } public CarotidClassificationService() { try { _singleImageCache = new ConcurrentStack(); _singleImagePipeServer = new PipeServer(AIDiagnosisSystemConsts.PipeForCarotidClassificationSingleImage); _singleImagePipeServer.LogMsgThrow += OnLogMsgThrow; _singleImagePipeServer.DataReceived += OnDataReceived; _singleImagePipeServer.StartAndReceive(); _imageProvider = new ImageProvider(AIEnumType.CarotidClassification); } catch (Exception ex) { Logger.Error($"CarotidClassificationService-Constructor error:{ex}"); } } public void Initialize(CarotidClassificationParameter carotidClassificationParameter, bool hasImageProvider) { try { CloseDiagnosis(); var cpuNumber = carotidClassificationParameter.CPUNumber; var detectMode = (EnumDetectMode)carotidClassificationParameter.DetectMode; var detectTps = carotidClassificationParameter.DetectTps; var intervalTime = carotidClassificationParameter.IntervalTime; var isIncludeContour = carotidClassificationParameter.IsIncludeContour; _carotidClassification = new CarotidClassification(Setting.Instance.IsSaveDetectImage, Setting.Instance.IsSaveAllImage, Logger.LogDir, hasImageProvider ? _imageProvider : null, cpuNumber, _modelFolder, detectMode, detectTps, intervalTime, isIncludeContour); _carotidClassification.StartEvaluation += OnStartEvaluation; _carotidClassification.FinishEvaluation += OnFinishEvaluation; _carotidClassification.NotifyError += OnNotifyError; _carotidClassification.NotifyLog += OnNotifyLog; } catch (Exception ex) { Logger.Error($"CarotidClassificationService-Initialize error:{ex}"); } } /// /// 切换引擎 /// /// public void SwitchEngines(FunctionInfo functionInfo) { try { CarotidClassification.SwitchAIEngines(functionInfo); if (_carotidClassification != null) { _carotidClassification.SwitchAIEngines2(functionInfo); } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-SwitchEngines error:{ex}"); } } public void Start() { try { if (_carotidClassification != null) { _carotidClassification.Start(); } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-Start error:{ex}"); } } public void Stop() { try { if (_carotidClassification != null) { _carotidClassification.Stop(); } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-Stop error:{ex}"); } } public void SetDetectTps(int detectTps) { try { if (_carotidClassification != null) { _carotidClassification.DetectTps = detectTps; } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-SetDetectTps error:{ex}"); } } public void SetIntervalTime(int intervalTime) { try { if (_carotidClassification != null) { _carotidClassification.IntervalTime = intervalTime; } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-SetIntervalTime error:{ex}"); } } public void SetDetectMode(AIEnumDetectMode detectMode) { try { if (_carotidClassification != null) { _carotidClassification.DetectMode = (EnumDetectMode)detectMode; } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-SetDetectMode error:{ex}"); } } public void SetIsIncludeContour(bool isIncludeContour) { try { if (_carotidClassification != null) { _carotidClassification.IsIncludeContour = isIncludeContour; } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-SetIsIncludeContour error:{ex}"); } } /// /// 检测单张Byte Image /// /// public AICarotidArterySectionClassificationResults DetectOneByteImage() { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"CarotidClassificationService-DetectOneByteImage Get Image Cache Fail"); return null; } var carotidArterySectionClassificationResults = _carotidClassification.DetectOneImage(byteImage); return AIConvertHelper.ConvertCarotidArterySectionClassificationResultsToAICarotidArterySectionClassificationResults(carotidArterySectionClassificationResults); } catch (Exception ex) { Logger.Error($"CarotidClassificationService-DetectOneByteImage error:{ex}"); return null; } } public AICarotidArterySectionClassificationResults DetectOneRawImage(int height, int width, AIEnumColorType colorType) { try { byte[] byteImage = null; int retryCount = 0; while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50) { Thread.Sleep(10); retryCount++; } if (byteImage == null) { Logger.Error($"CarotidClassificationService-DetectOneRawImage Get Image Cache Fail"); return null; } var rawImage = new RawImage(byteImage, width, height, (EnumColorType)colorType); var carotidArterySectionClassificationResults = _carotidClassification.DetectOneImage(rawImage); return AIConvertHelper.ConvertCarotidArterySectionClassificationResultsToAICarotidArterySectionClassificationResults(carotidArterySectionClassificationResults); } catch (Exception ex) { Logger.Error($"CarotidClassificationService-DetectOneRawImage error:{ex}"); return null; } } /// /// Send Raw Image Data For Pipe /// /// /// /// public void SendRawImageData(int height, int width, AIEnumColorType colorType) { try { _imageProvider?.ReceiveRawImageData(height, width, (EnumColorType)colorType); } catch (Exception ex) { Logger.Error($"CarotidClassificationService-SendRawImageData error:{ex}"); } } /// /// Send Byte Image Data For Pipe /// public void SendByteImageData() { try { _imageProvider?.ReceiveByteImageData(); } catch (Exception ex) { Logger.Error($"CarotidClassificationService-SendByteImageData error:{ex}"); } } public void Close() { try { Logger.Info($"CarotidClassificationService-Close Invoke"); CloseDiagnosis(); } catch (Exception ex) { Logger.Error($"CarotidClassificationService-Close error:{ex}"); } } private void CloseDiagnosis() { if (_carotidClassification != null) { _carotidClassification.StartEvaluation -= OnStartEvaluation; _carotidClassification.FinishEvaluation -= OnFinishEvaluation; _carotidClassification.NotifyError -= OnNotifyError; _carotidClassification.NotifyLog -= OnNotifyLog; _carotidClassification.Close(); _carotidClassification = null; } } public void Dispose() { try { if (!_disposed) { Logger.Info($"CarotidClassificationService-Start Dispose"); CloseDiagnosis(); if (_singleImagePipeServer != null) { _singleImagePipeServer.DataReceived -= OnDataReceived; _singleImagePipeServer.Dispose(); _singleImagePipeServer.LogMsgThrow -= OnLogMsgThrow; _singleImagePipeServer = null; } _imageProvider.Dispose(); _imageProvider = null; _disposed = true; Logger.Info($"CarotidClassificationService Dispose End"); } } catch (Exception ex) { Logger.Error($"CarotidClassificationService-Dispose error:{ex}"); } } private void OnStartEvaluation(object sender, EventArgs e) { NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.CarotidClassificationStartEvaluationRaised, Params = e }); } private void OnFinishEvaluation(object sender, CarotidArterySectionClassificationResults e) { var aiCarotidArterySectionClassificationResults = AIConvertHelper.ConvertCarotidArterySectionClassificationResultsToAICarotidArterySectionClassificationResults(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.CarotidClassificationFinishEvaluationRaised, Params = aiCarotidArterySectionClassificationResults }); } private void OnNotifyLog(object sender, LogEventArgs e) { if (e == null) { return; } switch (e.LogType) { case EnumLogType.InfoLog: Logger.Info($"CarotidClassificationService OnNotifyLog:{e.Msg}"); break; case EnumLogType.WarnLog: Logger.Warning($"CarotidClassificationService OnNotifyLog:{e.Msg}"); break; case EnumLogType.ErrorLog: case EnumLogType.FatalLog: default: Logger.Error($"CarotidClassificationService OnNotifyLog:{e.Msg}"); break; } var logEventArgs = AICommonServiceConvertHelper.ConvertLogEventArgsToAILogEventArgs(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.CarotidClassificationNotifyLogRaised, Params = logEventArgs }); } private void OnNotifyError(object sender, ErrorEventArgs e) { Logger.Error($"CarotidClassificationService OnNotifyError:{e.GetException()}"); var logEventArgs = AICommonServiceConvertHelper.ConvertErrorEventArgsToAILogEventArgs(e); NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.CarotidClassificationNotifyLogRaised, Params = logEventArgs }); } private void OnLogMsgThrow(object sender, AILogEventArgs e) { if (e == null) { return; } switch (e.LogType) { case AIEnumLogType.ErrorLog: case AIEnumLogType.FatalLog: Logger.Error(e.Msg); break; case AIEnumLogType.WarnLog: Logger.Warning(e.Msg); break; case AIEnumLogType.InfoLog: default: Logger.Info(e.Msg); break; } } private void OnDataReceived(object sender, byte[] e) { try { _singleImageCache.Push(e); } catch (Exception ex) { Logger.Error($"CarotidClassificationService-OnDataReceived error:{ex}"); } } } }