VetHeartDiagnosisService.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. using AI.Common.Interface;
  2. using AIDiagnosis.Common.Enums;
  3. using AIDiagnosis.Common.Models;
  4. using System;
  5. using System.Collections.Concurrent;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Threading;
  9. using VetHeartDiagnosisSDK.Enums;
  10. using Vinno.AI.CommonSDK.Enums;
  11. using Vinno.AI.CommonSDK.Models;
  12. using Vinno.AI.CommonSDK.Models.Data;
  13. using Vinno.AI.CommonSDK.Tools;
  14. using Vinno.AI.Service.Common.Interfaces;
  15. using Vinno.AI.Service.Common.Models;
  16. using Vinno.AI.Service.Common.Tools;
  17. using Vinno.AI.VetHeartDiagnosisSDK.Enums;
  18. using Vinno.AI.VetHeartDiagnosisSDK.Interfaces;
  19. using Vinno.AI.VetHeartDiagnosisSDK.Models;
  20. using Vinno.AI.VetHeartDiagnosisService.Tools;
  21. using VetHeartDiagnosis = VetHeartDiagnosisSDK.VetHeartDiagnosis;
  22. namespace Vinno.AI.VetHeartDiagnosisService
  23. {
  24. public class VetHeartDiagnosisService : IVetHeartDiagnosisService, IDisposable, IEngine
  25. {
  26. private readonly ConcurrentStack<byte[]> _singleImageCache;
  27. private readonly string _modelFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks");
  28. private PipeServer _singleImagePipeServer;
  29. private ImageProviderV2 _imageProvider;
  30. private VetHeartDiagnosis _vetHeartDiagnosis;
  31. private bool _disposed;
  32. public static List<FunctionInfo> AllFunctions { get; }
  33. static VetHeartDiagnosisService()
  34. {
  35. AllFunctions = VetHeartDiagnosis.AllFunctions;
  36. }
  37. public static void Init(FunctionInfo enableFunction, FunctionInfo currentUsedFunction)
  38. {
  39. VetHeartDiagnosis.Init(enableFunction, currentUsedFunction);
  40. }
  41. public VetHeartDiagnosisService()
  42. {
  43. try
  44. {
  45. _singleImageCache = new ConcurrentStack<byte[]>();
  46. _singleImagePipeServer = new PipeServer(AIDiagnosisSystemConsts.PipeForVetHeartDiagnosisSingleImage);
  47. _singleImagePipeServer.LogMsgThrow += OnLogMsgThrow;
  48. _singleImagePipeServer.DataReceived += OnDataReceived;
  49. _singleImagePipeServer.StartAndReceive();
  50. _imageProvider = new ImageProviderV2(AIEnumType.VetHeartDiagnosis, AIEnumEngineType.VetHeartLVStudy);
  51. }
  52. catch (Exception ex)
  53. {
  54. Logger.Error($"VetHeartDiagnosisService-Constructor error:{ex}");
  55. }
  56. }
  57. private void OnDataReceived(object sender, byte[] e)
  58. {
  59. try
  60. {
  61. _singleImageCache.Push(e);
  62. }
  63. catch (Exception ex)
  64. {
  65. Logger.Error($"VetHeartDiagnosisService-OnDataReceived error:{ex}");
  66. }
  67. }
  68. public void Initialize(VetHeartDiagnosisParameter vetHeartMLineDiagnosisParameter, bool hasImageProvider)
  69. {
  70. try
  71. {
  72. CloseDiagnosis();
  73. var cpuNumber = vetHeartMLineDiagnosisParameter.CPUNumber;
  74. var detectMode = (EnumDetectMode)vetHeartMLineDiagnosisParameter.DetectMode;
  75. var detectTps = vetHeartMLineDiagnosisParameter.DetectTps;
  76. var intervalTime = vetHeartMLineDiagnosisParameter.IntervalTime;
  77. _vetHeartDiagnosis = new VetHeartDiagnosis();
  78. _vetHeartDiagnosis.StartEvaluation += OnStartEvaluation;
  79. _vetHeartDiagnosis.FinishEvaluation += OnFinishEvaluation;
  80. _vetHeartDiagnosis.NotifyLog += OnNotifyLog;
  81. _vetHeartDiagnosis.Init(Setting.Instance.IsSaveDetectImage, Setting.Instance.IsSaveAllImage, Logger.LogDir, hasImageProvider ? _imageProvider : null, cpuNumber, _modelFolder, detectMode, detectTps, intervalTime);
  82. }
  83. catch (Exception ex)
  84. {
  85. Logger.Error($"VetHeartDiagnosisService-Initialize error:{ex}");
  86. }
  87. }
  88. public string StartProcess(AIEnumVetHeartEngineType engineType)
  89. {
  90. try
  91. {
  92. return _vetHeartDiagnosis.StartProcess((EnumVetHeartDiagnosisEngineType)engineType);
  93. }
  94. catch (Exception ex)
  95. {
  96. Logger.Error($"VetHeartDiagnosisService-StartProcess Error:{ex}");
  97. return null;
  98. }
  99. }
  100. public List<TransAIResultInfo> PushOnePieceOfData(string processId, AIEnumVetHeartEngineType engineType, AIImageDataId aiImageDataId, AIImageExtraInfo aiImageExtraInfo, TransAIUltrasoundImageRegion transAIUltrasoundImageRegion, int height, int width, AIEnumColorType colorType)
  101. {
  102. try
  103. {
  104. byte[] byteImage = null;
  105. int retryCount = 0;
  106. while (!_singleImageCache.TryPop(out byteImage) && retryCount < 50)
  107. {
  108. Thread.Sleep(10);
  109. retryCount++;
  110. }
  111. if (byteImage == null)
  112. {
  113. Logger.Error($"VetHeartDiagnosisService-DetectOneRawImage Get Image Cache Fail");
  114. return null;
  115. }
  116. var rawImage = new RawImage(byteImage, width, height, (EnumColorType)colorType);
  117. Dictionary<string, object> extraInfoList = new Dictionary<string, object>();
  118. var imageDataId = AICommonServiceConvertHelperV2.ConvertAIImageDataIdToImageDataId(aiImageDataId);
  119. if (aiImageExtraInfo != null)
  120. {
  121. extraInfoList.Add(nameof(aiImageExtraInfo.CmPerPixel), aiImageExtraInfo.CmPerPixel);
  122. }
  123. if (transAIUltrasoundImageRegion != null)
  124. {
  125. var ultrasoundImageRegion = AICommonServiceConvertHelperV2.ConvertTransAIUltrasoundImageRegionToIUltrasoundImageRegion(transAIUltrasoundImageRegion);
  126. if (ultrasoundImageRegion != null)
  127. {
  128. extraInfoList.Add("UltrasoundImageRegion", ultrasoundImageRegion);
  129. }
  130. }
  131. var imageInputData = new ImageInputData(rawImage, imageDataId, extraInfoList);
  132. var result = _vetHeartDiagnosis.DetectOneImage((EnumVetHeartDiagnosisEngineType)engineType, processId, imageInputData);
  133. return AIConvertHelper.ConvertResultDictToTransResultList(result);
  134. }
  135. catch (Exception ex)
  136. {
  137. Logger.Error($"VetHeartDiagnosisService-DetectOneRawImage error:{ex}");
  138. return null;
  139. }
  140. }
  141. public void EndProcess(AIEnumVetHeartEngineType engineType, string processId)
  142. {
  143. try
  144. {
  145. _vetHeartDiagnosis.EndProcess((EnumVetHeartDiagnosisEngineType)engineType, processId);
  146. }
  147. catch (Exception ex)
  148. {
  149. Logger.Error($"VetHeartDiagnosisService-EndProcess Error:{ex}");
  150. }
  151. }
  152. public void SetCurrentEngine(AIEnumVetHeartEngineType engineType)
  153. {
  154. try
  155. {
  156. if (_imageProvider != null)
  157. {
  158. _imageProvider.SetEngineType(engineType.ToString());
  159. }
  160. }
  161. catch (Exception ex)
  162. {
  163. Logger.Error($"VetHeartDiagnosisService-SetCurrentEngine Error:{ex}");
  164. }
  165. }
  166. private void OnFinishEvaluation(object sender, IReadOnlyDictionary<IDataId, IReadOnlyList<IResultData>> e)
  167. {
  168. var transResultList = AIConvertHelper.ConvertResultDictToTransResultList(e);
  169. NotificationSender.SendNotification(new AINotificationArgs
  170. {
  171. NotificationType = AIEnumNotificationType.VetHeartMLineDiagnosisFinishEvaluationRaised,
  172. Params = transResultList
  173. });
  174. }
  175. /// <summary>
  176. /// 切换引擎
  177. /// </summary>
  178. /// <param name="functionInfo"></param>
  179. public void SwitchEngines(FunctionInfo functionInfo)
  180. {
  181. try
  182. {
  183. VetHeartDiagnosis.SwitchAIEngines(functionInfo);
  184. if (_vetHeartDiagnosis != null)
  185. {
  186. _vetHeartDiagnosis.SwitchAIEngines2(functionInfo);
  187. }
  188. }
  189. catch (Exception ex)
  190. {
  191. Logger.Error($"VetHeartDiagnosisService-SwitchEngines error:{ex}");
  192. }
  193. }
  194. public void Start()
  195. {
  196. try
  197. {
  198. if (_vetHeartDiagnosis != null)
  199. {
  200. _vetHeartDiagnosis.Start();
  201. }
  202. }
  203. catch (Exception ex)
  204. {
  205. Logger.Error($"VetHeartDiagnosisService-Start error:{ex}");
  206. }
  207. }
  208. public void Stop()
  209. {
  210. try
  211. {
  212. if (_vetHeartDiagnosis != null)
  213. {
  214. _vetHeartDiagnosis.Stop();
  215. }
  216. }
  217. catch (Exception ex)
  218. {
  219. Logger.Error($"VetHeartDiagnosisService-Stop error:{ex}");
  220. }
  221. }
  222. public void SetDetectTps(int detectTps)
  223. {
  224. try
  225. {
  226. if (_vetHeartDiagnosis != null)
  227. {
  228. _vetHeartDiagnosis.DetectTps = detectTps;
  229. }
  230. }
  231. catch (Exception ex)
  232. {
  233. Logger.Error($"VetHeartDiagnosisService-SetDetectTps error:{ex}");
  234. }
  235. }
  236. public void SetIntervalTime(int intervalTime)
  237. {
  238. try
  239. {
  240. if (_vetHeartDiagnosis != null)
  241. {
  242. _vetHeartDiagnosis.IntervalTime = intervalTime;
  243. }
  244. }
  245. catch (Exception ex)
  246. {
  247. Logger.Error($"VetHeartDiagnosisService-SetIntervalTime error:{ex}");
  248. }
  249. }
  250. public void SetDetectMode(AIEnumDetectMode detectMode)
  251. {
  252. try
  253. {
  254. if (_vetHeartDiagnosis != null)
  255. {
  256. _vetHeartDiagnosis.DetectMode = (EnumDetectMode)detectMode;
  257. }
  258. }
  259. catch (Exception ex)
  260. {
  261. Logger.Error($"VetHeartDiagnosisService-SetDetectMode error:{ex}");
  262. }
  263. }
  264. /// <summary>
  265. /// Send Raw Image Data For Pipe
  266. /// </summary>
  267. /// <param name="height"></param>
  268. /// <param name="width"></param>
  269. /// <param name="colorType"></param>
  270. public void SendImageData(AIImageDataId imageDataId, AIImageExtraInfo imageExtraInfo, TransAIUltrasoundImageRegion ultrasoundImageRegion, int height, int width, AIEnumColorType colorType)
  271. {
  272. try
  273. {
  274. _imageProvider?.ReceiveImageData(height, width, colorType, imageDataId, imageExtraInfo, ultrasoundImageRegion);
  275. }
  276. catch (Exception ex)
  277. {
  278. Logger.Error($"VetHeartDiagnosisService-SendRawImageData error:{ex}");
  279. }
  280. }
  281. public void Close()
  282. {
  283. try
  284. {
  285. Logger.Info($"VetHeartDiagnosisService-Close Invoke");
  286. CloseDiagnosis();
  287. }
  288. catch (Exception ex)
  289. {
  290. Logger.Error($"VetHeartDiagnosisService-Close error:{ex}");
  291. }
  292. }
  293. private void CloseDiagnosis()
  294. {
  295. if (_vetHeartDiagnosis != null)
  296. {
  297. _vetHeartDiagnosis.StartEvaluation -= OnStartEvaluation;
  298. _vetHeartDiagnosis.NotifyLog -= OnNotifyLog;
  299. _vetHeartDiagnosis.Close();
  300. _vetHeartDiagnosis = null;
  301. }
  302. }
  303. public void Dispose()
  304. {
  305. try
  306. {
  307. if (!_disposed)
  308. {
  309. Logger.Info($"VetHeartDiagnosisService-Start Dispose");
  310. CloseDiagnosis();
  311. if (_singleImagePipeServer != null)
  312. {
  313. _singleImagePipeServer.DataReceived -= OnDataReceived;
  314. _singleImagePipeServer.Dispose();
  315. _singleImagePipeServer.LogMsgThrow -= OnLogMsgThrow;
  316. _singleImagePipeServer = null;
  317. }
  318. _imageProvider.Dispose();
  319. _imageProvider = null;
  320. _disposed = true;
  321. Logger.Info($"VetHeartDiagnosisService Dispose End");
  322. }
  323. }
  324. catch (Exception ex)
  325. {
  326. Logger.Error($"VetHeartDiagnosisService-Dispose error:{ex}");
  327. }
  328. }
  329. private void OnStartEvaluation(object sender, EventArgs e)
  330. {
  331. NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.VetHeartMLineDiagnosisStartEvaluationRaised, Params = e });
  332. }
  333. private void OnNotifyLog(object sender, LogEventArgs e)
  334. {
  335. if (e == null)
  336. {
  337. return;
  338. }
  339. switch (e.LogType)
  340. {
  341. case EnumLogType.InfoLog:
  342. Logger.Info($"VetHeartDiagnosisService OnNotifyLog:{e.Msg}");
  343. break;
  344. case EnumLogType.WarnLog:
  345. Logger.Warning($"VetHeartDiagnosisService OnNotifyLog:{e.Msg}");
  346. break;
  347. case EnumLogType.ErrorLog:
  348. case EnumLogType.FatalLog:
  349. default:
  350. Logger.Error($"VetHeartDiagnosisService OnNotifyLog:{e.Msg}");
  351. break;
  352. }
  353. var logEventArgs = AICommonServiceConvertHelperV2.ConvertLogEventArgsToAILogEventArgs(e);
  354. NotificationSender.SendNotification(new AINotificationArgs() { NotificationType = AIEnumNotificationType.VetHeartMLineDiagnosisNotifyLogRaised, Params = logEventArgs });
  355. }
  356. private void OnLogMsgThrow(object sender, AILogEventArgs e)
  357. {
  358. if (e == null)
  359. {
  360. return;
  361. }
  362. switch (e.LogType)
  363. {
  364. case AIEnumLogType.ErrorLog:
  365. case AIEnumLogType.FatalLog:
  366. Logger.Error(e.Msg);
  367. break;
  368. case AIEnumLogType.WarnLog:
  369. Logger.Warning(e.Msg);
  370. break;
  371. case AIEnumLogType.InfoLog:
  372. default:
  373. Logger.Info(e.Msg);
  374. break;
  375. }
  376. }
  377. }
  378. }