using System;
using System.Reflection;
using System.Text.Json;
using Vinno.AI.CommonSDK.Enums;
using Vinno.AI.CommonSDK.Interfaces;
using Vinno.AI.CommonSDK.Models;
using Vinno.AI.CommonSDK.Tools;
using Vinno.AI.MyocardialDiagnosisSDK.Enums;
using Vinno.AI.MyocardialDiagnosisSDK.Interfaces;
using Vinno.AI.MyocardialDiagnosisSDK.Models;
namespace Vinno.AI.MyocardialDiagnosisSDK
{
public class MyocardialDiagnosis : IMyocardialDiagnosis
{
private readonly IMyocardialDiagnosisService _myocardialDiagnosisService;
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 MyocardialDiagnosis()
{
_myocardialDiagnosisService = AIManager.Instance.AIDiagnosisSystemJsonRpcClientManager?.GetService();
if (AIManager.Instance.AINotificationManager != null)
{
AIManager.Instance.AINotificationManager.NotificationReceived += OnNotificationReceived;
}
_singleImagePipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForMyocardialDiagnosisSingleImage);
_singleImagePipeClient.LogMsgThrow += OnLogMsgThrow;
_singleImagePipeClient.Start();
_rawImageProviderPipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForMyocardialDiagnosisRawImageProvider);
_rawImageProviderPipeClient.LogMsgThrow += OnLogMsgThrow;
_rawImageProviderPipeClient.Start();
_byteImageProviderPipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForMyocardialDiagnosisByteImageProvider);
_byteImageProviderPipeClient.LogMsgThrow += OnLogMsgThrow;
_byteImageProviderPipeClient.Start();
}
///
/// 初始化Myocardial Diagnosis
///
/// Myocardial Parameter
/// Image Provider
public void Initialize(MyocardialDiagnosisParameter myocardialParameter, IAIImageProvider imageProvider = null)
{
try
{
if (!_initialized)
{
_imageProvider = imageProvider;
_myocardialDiagnosisService.Initialize(myocardialParameter, _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)
{
_myocardialDiagnosisService.Start();
_imageProvider.ByteImageProvided += OnByteImageProvided;
_imageProvider.RawImageProvided += OnRawImageProvided;
_imageProvider.Start();
}
}
///
/// Stop Image Provider
///
public void Stop()
{
if (_imageProvider != null)
{
_imageProvider.ByteImageProvided -= OnByteImageProvided;
_imageProvider.RawImageProvided -= OnRawImageProvided;
_imageProvider.Stop();
}
_myocardialDiagnosisService.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.MyocardialDiagnosisStartEvaluationRaised:
StartEvaluationNotification?.Invoke(this, EventArgs.Empty);
break;
case AIEnumNotificationType.MyocardialDiagnosisFinishEvaluationRaised:
var transAIDetectedObject = JsonSerializer.Deserialize(e.Params?.ToString());
var detectedObject = AICommonConvertHelper.ConvertTransAIDetectedObjectToAIDetectedObject(transAIDetectedObject);
FinishEvaluationNotification?.Invoke(this, detectedObject);
break;
case AIEnumNotificationType.MyocardialDiagnosisNotifyLogRaised:
var logEventArgs = JsonSerializer.Deserialize(e.Params?.ToString());
AIManager.Instance.AILogManager?.WriteLogInfo(logEventArgs);
break;
}
}
///
/// 设置每秒图片吞吐量
///
/// 每秒图片吞吐量,必须大于0
public void SetDetectTps(int detectTps)
{
if (detectTps <= 0)
{
throw new ArgumentOutOfRangeException($"DetectTps Must > 0. DetectTps : {detectTps}");
}
try
{
_myocardialDiagnosisService.SetDetectTps(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
{
_myocardialDiagnosisService.SetIntervalTime(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
{
_myocardialDiagnosisService.SetDetectMode(detectMode);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
}
}
///
/// 设置是否对心肌圆形轮廓进行补全
///
///
public void SetIsCompleteMyocardialImg(bool isCompleteMyocardiaImg)
{
try
{
_myocardialDiagnosisService.SetIsCompleteMyocardialImg(isCompleteMyocardiaImg);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
}
}
///
/// 检测单张Raw Image
///
/// 图像资源
/// 是否是基底类图片
///
public AIDetectedObject DetectOneImage(AIRawImage rawImage, bool isCircle)
{
if (rawImage == null)
{
throw new ArgumentNullException(nameof(rawImage));
}
try
{
_singleImagePipeClient.SendBytes(rawImage.DataBuffer);
var result = _myocardialDiagnosisService.DetectOneRawImage(rawImage.Height, rawImage.Width, rawImage.ColorType, isCircle);
return AICommonConvertHelper.ConvertTransAIDetectedObjectToAIDetectedObject(result);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
return null;
}
}
///
/// 检测单张Byte Image
///
/// 图像资源
/// 是否是基底类图片
///
public AIDetectedObject DetectOneImage(byte[] byteImage, bool isCircle)
{
if (byteImage == null)
{
throw new ArgumentNullException(nameof(byteImage));
}
try
{
_singleImagePipeClient.SendBytes(byteImage);
var result = _myocardialDiagnosisService.DetectOneByteImage(isCircle);
return AICommonConvertHelper.ConvertTransAIDetectedObjectToAIDetectedObject(result);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
return null;
}
}
///
/// 检测出心肌轮廓后,判断单帧图的心肌轮廓是否能够补全成完整圆
///
/// 心肌检测结果
///
public bool AbleToBeCompleted(AIDetectedObject inferResult)
{
if (inferResult == null)
{
throw new ArgumentNullException(nameof(inferResult));
}
try
{
var transAIDetectedObject = AICommonConvertHelper.ConvertAIDetectedObjectToTransAIDetectedObject(inferResult);
return _myocardialDiagnosisService.AbleToBeCompleted(transAIDetectedObject);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
return false;
}
}
///
/// 检测心肌图片,给出补全完整的心肌轮廓。
///
/// 心肌轮廓检测结果,是DetectOneImage方法得出的不补全的检测结果
///
public AIDetectedObject CompleteOneImage(AIDetectedObject segResult)
{
if (segResult == null)
{
throw new ArgumentNullException(nameof(segResult));
}
try
{
var transAIDetectedObject = AICommonConvertHelper.ConvertAIDetectedObjectToTransAIDetectedObject(segResult);
var result = _myocardialDiagnosisService.CompleteOneImage(transAIDetectedObject);
return AICommonConvertHelper.ConvertTransAIDetectedObjectToAIDetectedObject(result);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
return null;
}
}
///
/// 根据分割结果,提取相应内外轮廓的值
///
/// 心肌轮廓检测结果
///
public AIDetectedObject ExtractContours(AIDetectedObject segResult)
{
if (segResult == null)
{
throw new ArgumentNullException(nameof(segResult));
}
try
{
var transAIDetectedObject = AICommonConvertHelper.ConvertAIDetectedObjectToTransAIDetectedObject(segResult);
var result = _myocardialDiagnosisService.ExtractContours(transAIDetectedObject);
return AICommonConvertHelper.ConvertTransAIDetectedObjectToAIDetectedObject(result);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
return null;
}
}
///
/// 对心肌的EDES帧的内外轮廓做后处理,当前仅供人的心肌使用
///
/// 分割结果,使用其中的轮廓点
/// 输入的心肌切面的类型
/// 最终的图像内外轮廓经过后处理的结果,比原始分割的心肌轮廓更接近真实轮廓,0表示外轮廓、1表示内轮廓
public AIDetectedObject ModifyEDESFrame(AIDetectedObject segResult, AIEnumMyocardialType type)
{
if (segResult == null)
{
throw new ArgumentNullException(nameof(segResult));
}
try
{
var transAIDetectedObject = AICommonConvertHelper.ConvertAIDetectedObjectToTransAIDetectedObject(segResult);
var result = _myocardialDiagnosisService.ModifyEDESFrame(transAIDetectedObject, type);
return AICommonConvertHelper.ConvertTransAIDetectedObjectToAIDetectedObject(result);
}
catch (Exception ex)
{
AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
return null;
}
}
private void OnByteImageProvided(object sender, byte[] byteImage)
{
try
{
if (byteImage == null)
{
return;
}
_byteImageProviderPipeClient?.SendBytes(byteImage);
_myocardialDiagnosisService.SendByteImageData();
}
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);
_myocardialDiagnosisService.SendRawImageData(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 Myocardial Diagnosis
///
public void Close()
{
try
{
if (_disposed)
{
return;
}
_initialized = false;
if (_imageProvider != null)
{
_imageProvider.ByteImageProvided -= OnByteImageProvided;
_imageProvider.RawImageProvided -= OnRawImageProvided;
_imageProvider.Stop();
_imageProvider = null;
}
_myocardialDiagnosisService.Close();
}
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}"));
}
}
}
}