using System; using System.Reflection; using System.Text.Json; using Vinno.AI.AIDiagnosisSDK.Interfaces; using Vinno.AI.AIDiagnosisSDK.Models; using Vinno.AI.CommonSDK.Enums; using Vinno.AI.CommonSDK.Interfaces; using Vinno.AI.CommonSDK.Models; using Vinno.AI.CommonSDK.Tools; namespace Vinno.AI.AIDiagnosisSDK { public class AbdomenDiagnosis : IAIDiagnosis { private readonly IAIDiagnosisService _aiDiagnosisService; private readonly AIEnumModuleType _type = AIEnumModuleType.Abdomen; private IAIImageProvider _imageProvider; private bool _initialized; private bool _disposed; /// /// Used For Detect One Image /// private PipeClient _singleImagePipeClient; /// /// Used For Provide Raw Image /// private PipeClient _rawImageProviderPipeClient; /// /// Used For Provide Byte Image /// private PipeClient _byteImageProviderPipeClient; /// /// Raised when the image evaluation is started. /// public event EventHandler StartEvaluationNotification; /// /// Raised when the image evaluation is finished. /// public event EventHandler FinishEvaluationNotification; public AbdomenDiagnosis() { _aiDiagnosisService = AIManager.Instance.AIDiagnosisSystemJsonRpcClientManager?.GetService(); if (AIManager.Instance.AINotificationManager != null) { AIManager.Instance.AINotificationManager.NotificationReceived += OnNotificationReceived; } _singleImagePipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForAbdomenDiagnosisSingleImage); _singleImagePipeClient.LogMsgThrow += OnLogMsgThrow; _singleImagePipeClient.Start(); _rawImageProviderPipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForAbdomenDiagnosisRawImageProvider); _rawImageProviderPipeClient.LogMsgThrow += OnLogMsgThrow; _rawImageProviderPipeClient.Start(); _byteImageProviderPipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForAbdomenDiagnosisByteImageProvider); _byteImageProviderPipeClient.LogMsgThrow += OnLogMsgThrow; _byteImageProviderPipeClient.Start(); } /// /// 初始化AI Diagnosis /// /// AI Diagnosis Parameter /// Image Provider public void Initialize(AIDiagnosisParameter abdomenDiagnosisParameter, IAIImageProvider imageProvider = null) { try { if (!_initialized) { _imageProvider = imageProvider; _aiDiagnosisService.InitializeAbdomenDiagnosis(abdomenDiagnosisParameter, _imageProvider != null); _initialized = true; } } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// Start Image Provider /// public void Start() { if (_imageProvider != null) { _imageProvider.ByteImageProvided += OnByteImageProvided; _imageProvider.RawImageProvided += OnRawImageProvided; _imageProvider.Start(); _aiDiagnosisService.Start(); } } /// /// Stop Image Provider /// public void Stop() { if (_imageProvider != null) { _imageProvider.ByteImageProvided -= OnByteImageProvided; _imageProvider.RawImageProvided -= OnRawImageProvided; _imageProvider.Stop(); } _aiDiagnosisService.Stop(); } private void OnLogMsgThrow(object sender, AILogEventArgs e) { AIManager.Instance.AILogManager?.WriteLogInfo(e); } private void OnNotificationReceived(object sender, AINotificationArgs e) { switch (e.NotificationType) { case AIEnumNotificationType.AbdomenDiagnosisStartEvaluationRaised: StartEvaluationNotification?.Invoke(this, EventArgs.Empty); break; case AIEnumNotificationType.AbdomenDiagnosisFinishEvaluationRaised: var transAIDiagResultPerImg = JsonSerializer.Deserialize(e.Params?.ToString()); var aiDiagResultPerImg = AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(transAIDiagResultPerImg); FinishEvaluationNotification?.Invoke(this, aiDiagResultPerImg); break; } } /// /// 设置图片是否已裁剪 /// /// public void SetIsCropped(bool isCropped) { try { _aiDiagnosisService.SetIsCropped(_type, isCropped); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// 设置每秒图片吞吐量 /// /// 每秒图片吞吐量,必须大于0 public void SetDetectTps(int detectTps) { if (detectTps <= 0) { throw new ArgumentOutOfRangeException($"DetectTps Must > 0. DetectTps : {detectTps}"); } try { _aiDiagnosisService.SetDetectTps(_type, detectTps); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// 设置间隔时间 /// /// public void SetIntervalTime(int intervalTime) { try { _aiDiagnosisService.SetIntervalTime(_type, intervalTime); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// 设置检测模式 /// /// public void SetDetectMode(AIEnumDetectMode detectMode) { try { _aiDiagnosisService.SetDetectMode(_type, detectMode); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// 设置是否启用轮廓计算 /// /// public void SetEnableLesionSeg(bool enableLesionSeg) { try { _aiDiagnosisService.SetEnableLesionSeg(_type, enableLesionSeg); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// 设置是否启用描述 /// /// 是否启用病灶及脏器描述 public void SetEnableDescription(bool enableDescription) { try { _aiDiagnosisService.SetEnableDescription(_type, enableDescription, enableDescription); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// 设置是否启用描述 /// /// 是否启用病灶描述 /// 是否启用脏器描述 public void SetEnableDescription(bool enableLessionDescription, bool enableOrganDescription) { try { _aiDiagnosisService.SetEnableDescription(_type, enableLessionDescription, enableOrganDescription); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// 检测单张Byte Image /// /// /// public AIDiagResultPerImg DetectOneImage(byte[] byteImage) { if (byteImage == null) { throw new ArgumentNullException(nameof(byteImage)); } try { _singleImagePipeClient.SendBytes(byteImage); var result = _aiDiagnosisService.DetectOneByteImage(_type); return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); return null; } } /// /// 检测单张Byte Image,其中enableLesionSeg与enableDescription仅此次调用生效 /// /// /// 是否计算轮廓 /// 是否计算病灶及脏器描述结果 /// public AIDiagResultPerImg DetectOneImage(byte[] byteImage, bool enableLesionSeg, bool enableDescription) { if (byteImage == null) { throw new ArgumentNullException(nameof(byteImage)); } try { _singleImagePipeClient.SendBytes(byteImage); var result = _aiDiagnosisService.DetectOneByteImageWithTempSetting(_type, enableLesionSeg, enableDescription, enableDescription); return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); return null; } } /// /// 检测单张Byte Image,其中enableLesionSeg与enableLesionDescription,enableOrganDescription仅此次调用生效 /// /// /// 是否计算轮廓 /// 是否计算病灶描述结果 /// 是否计算脏器描述结果 /// public AIDiagResultPerImg DetectOneImage(byte[] byteImage, bool enableLesionSeg, bool enableLesionDescription, bool enableOrganDescription) { if (byteImage == null) { throw new ArgumentNullException(nameof(byteImage)); } try { _singleImagePipeClient.SendBytes(byteImage); var result = _aiDiagnosisService.DetectOneByteImageWithTempSetting(_type, enableLesionSeg, enableLesionDescription, enableOrganDescription); return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); return null; } } /// /// 检测单张Raw Image /// /// /// public AIDiagResultPerImg DetectOneImage(AIRawImage rawImage) { if (rawImage == null) { throw new ArgumentNullException(nameof(rawImage)); } try { _singleImagePipeClient.SendBytes(rawImage.DataBuffer); var result = _aiDiagnosisService.DetectOneRawImage(_type, rawImage.Height, rawImage.Width, rawImage.ColorType); return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); return null; } } /// /// 检测单张Raw Image,其中enableLesionSeg与enableDescription仅此次调用生效 /// /// /// 是否计算轮廓 /// 是否计算病灶及脏器描述结果 /// public AIDiagResultPerImg DetectOneImage(AIRawImage rawImage, bool enableLesionSeg, bool enableDescription) { if (rawImage == null) { throw new ArgumentNullException(nameof(rawImage)); } try { _singleImagePipeClient.SendBytes(rawImage.DataBuffer); var result = _aiDiagnosisService.DetectOneRawImageWithTempSetting(_type, rawImage.Height, rawImage.Width, rawImage.ColorType, enableLesionSeg, enableDescription, enableDescription); return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); return null; } } /// /// 检测单张Raw Image,其中enableLesionSeg与enableLesionDescription,enableOrganDescription仅此次调用生效 /// /// /// 是否计算轮廓 /// 是否计算病灶描述结果 /// 是否计算脏器描述结果 /// public AIDiagResultPerImg DetectOneImage(AIRawImage rawImage, bool enableLesionSeg, bool enableLesionDescription, bool enableOrganDescription = false) { if (rawImage == null) { throw new ArgumentNullException(nameof(rawImage)); } try { _singleImagePipeClient.SendBytes(rawImage.DataBuffer); var result = _aiDiagnosisService.DetectOneRawImageWithTempSetting(_type, rawImage.Height, rawImage.Width, rawImage.ColorType, enableLesionSeg, enableLesionDescription, enableOrganDescription); return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); return null; } } /// /// 评估单幅图像 ,图像计算完成后,使用者希望调整结果,使部分结果在选定的矩形框内。 /// /// 使用者给出的矩形框 /// 图像的初始计算结果 /// public AIDiagResultPerImg CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRect(byte[] bytesImage, AIRect aiRect, AIDiagResultPerImg aiDiagResultPerImg) { throw new NotSupportedException("CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRectWithBytesImage Only Support Cartoid Diagnosis"); } /// /// 评估单幅图像 ,图像计算完成后,使用者希望调整结果,使部分结果在选定的矩形框内。 /// /// 使用者给出的矩形框 /// 图像的初始计算结果 public AIDiagResultPerImg CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRect(AIRawImage rawImage, AIRect aiRect, AIDiagResultPerImg aiDiagResultPerImg) { throw new NotSupportedException("CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRectWithBytesImage Only Support Cartoid Diagnosis"); } private void OnByteImageProvided(object sender, byte[] byteImage) { try { if (byteImage == null) { return; } _byteImageProviderPipeClient?.SendBytes(byteImage); _aiDiagnosisService.SendByteImageData(_type); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } private void OnRawImageProvided(object sender, AIRawImage rawImage) { try { if (rawImage == null) { return; } _rawImageProviderPipeClient?.SendBytes(rawImage.DataBuffer); _aiDiagnosisService.SendRawImageData(_type, rawImage.Height, rawImage.Width, rawImage.ColorType); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } /// /// Close AI Diagnosis /// public void Close() { try { if (_disposed) { return; } _initialized = false; if (_imageProvider != null) { _imageProvider.ByteImageProvided -= OnByteImageProvided; _imageProvider.RawImageProvided -= OnRawImageProvided; _imageProvider.Stop(); _imageProvider = null; } _aiDiagnosisService.Close(_type); } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } public void Dispose() { try { if (!_disposed) { _initialized = false; if (AIManager.Instance.AINotificationManager != null) { AIManager.Instance.AINotificationManager.NotificationReceived -= OnNotificationReceived; } if (_imageProvider != null) { _imageProvider.ByteImageProvided -= OnByteImageProvided; _imageProvider.RawImageProvided -= OnRawImageProvided; _imageProvider.Stop(); _imageProvider = null; } if (_singleImagePipeClient != null) { _singleImagePipeClient.Dispose(); _singleImagePipeClient.LogMsgThrow -= OnLogMsgThrow; _singleImagePipeClient = null; } if (_rawImageProviderPipeClient != null) { _rawImageProviderPipeClient.Dispose(); _rawImageProviderPipeClient.LogMsgThrow -= OnLogMsgThrow; _rawImageProviderPipeClient = null; } if (_byteImageProviderPipeClient != null) { _byteImageProviderPipeClient.Dispose(); _byteImageProviderPipeClient.LogMsgThrow -= OnLogMsgThrow; _byteImageProviderPipeClient = null; } _disposed = true; } } catch (Exception ex) { AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}")); } } } }