AbdomenDiagnosis.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. using System;
  2. using System.Reflection;
  3. using System.Text.Json;
  4. using Vinno.AI.AIDiagnosisSDK.Interfaces;
  5. using Vinno.AI.AIDiagnosisSDK.Models;
  6. using Vinno.AI.CommonSDK.Enums;
  7. using Vinno.AI.CommonSDK.Interfaces;
  8. using Vinno.AI.CommonSDK.Models;
  9. using Vinno.AI.CommonSDK.Tools;
  10. namespace Vinno.AI.AIDiagnosisSDK
  11. {
  12. public class AbdomenDiagnosis : IAIDiagnosis
  13. {
  14. private readonly IAIDiagnosisService _aiDiagnosisService;
  15. private readonly AIEnumModuleType _type = AIEnumModuleType.Abdomen;
  16. private IAIImageProvider _imageProvider;
  17. private bool _initialized;
  18. private bool _disposed;
  19. /// <summary>
  20. /// Used For Detect One Image
  21. /// </summary>
  22. private PipeClient _singleImagePipeClient;
  23. /// <summary>
  24. /// Used For Provide Raw Image
  25. /// </summary>
  26. private PipeClient _rawImageProviderPipeClient;
  27. /// <summary>
  28. /// Used For Provide Byte Image
  29. /// </summary>
  30. private PipeClient _byteImageProviderPipeClient;
  31. /// <summary>
  32. /// Raised when the image evaluation is started.
  33. /// </summary>
  34. public event EventHandler StartEvaluationNotification;
  35. /// <summary>
  36. /// Raised when the image evaluation is finished.
  37. /// </summary>
  38. public event EventHandler<AIDiagResultPerImg> FinishEvaluationNotification;
  39. public AbdomenDiagnosis()
  40. {
  41. _aiDiagnosisService = AIManager.Instance.AIDiagnosisSystemJsonRpcClientManager?.GetService<IAIDiagnosisService>();
  42. if (AIManager.Instance.AINotificationManager != null)
  43. {
  44. AIManager.Instance.AINotificationManager.NotificationReceived += OnNotificationReceived;
  45. }
  46. _singleImagePipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForAbdomenDiagnosisSingleImage);
  47. _singleImagePipeClient.LogMsgThrow += OnLogMsgThrow;
  48. _singleImagePipeClient.Start();
  49. _rawImageProviderPipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForAbdomenDiagnosisRawImageProvider);
  50. _rawImageProviderPipeClient.LogMsgThrow += OnLogMsgThrow;
  51. _rawImageProviderPipeClient.Start();
  52. _byteImageProviderPipeClient = new PipeClient(AIDiagnosisSystemConsts.PipeForAbdomenDiagnosisByteImageProvider);
  53. _byteImageProviderPipeClient.LogMsgThrow += OnLogMsgThrow;
  54. _byteImageProviderPipeClient.Start();
  55. }
  56. /// <summary>
  57. /// 初始化AI Diagnosis
  58. /// </summary>
  59. /// <param name="abdomenDiagnosisParameter">AI Diagnosis Parameter</param>
  60. /// <param name="imageProvider">Image Provider</param>
  61. public void Initialize(AIDiagnosisParameter abdomenDiagnosisParameter, IAIImageProvider imageProvider = null)
  62. {
  63. try
  64. {
  65. if (!_initialized)
  66. {
  67. _imageProvider = imageProvider;
  68. _aiDiagnosisService.InitializeAbdomenDiagnosis(abdomenDiagnosisParameter, _imageProvider != null);
  69. _initialized = true;
  70. }
  71. }
  72. catch (Exception ex)
  73. {
  74. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  75. }
  76. }
  77. /// <summary>
  78. /// Start Image Provider
  79. /// </summary>
  80. public void Start()
  81. {
  82. if (_imageProvider != null)
  83. {
  84. _imageProvider.ByteImageProvided += OnByteImageProvided;
  85. _imageProvider.RawImageProvided += OnRawImageProvided;
  86. _imageProvider.Start();
  87. _aiDiagnosisService.Start();
  88. }
  89. }
  90. /// <summary>
  91. /// Stop Image Provider
  92. /// </summary>
  93. public void Stop()
  94. {
  95. if (_imageProvider != null)
  96. {
  97. _imageProvider.ByteImageProvided -= OnByteImageProvided;
  98. _imageProvider.RawImageProvided -= OnRawImageProvided;
  99. _imageProvider.Stop();
  100. }
  101. _aiDiagnosisService.Stop();
  102. }
  103. private void OnLogMsgThrow(object sender, AILogEventArgs e)
  104. {
  105. AIManager.Instance.AILogManager?.WriteLogInfo(e);
  106. }
  107. private void OnNotificationReceived(object sender, AINotificationArgs e)
  108. {
  109. switch (e.NotificationType)
  110. {
  111. case AIEnumNotificationType.AbdomenDiagnosisStartEvaluationRaised:
  112. StartEvaluationNotification?.Invoke(this, EventArgs.Empty);
  113. break;
  114. case AIEnumNotificationType.AbdomenDiagnosisFinishEvaluationRaised:
  115. var transAIDiagResultPerImg = JsonSerializer.Deserialize<TransAIDiagResultPerImg>(e.Params?.ToString());
  116. var aiDiagResultPerImg = AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(transAIDiagResultPerImg);
  117. FinishEvaluationNotification?.Invoke(this, aiDiagResultPerImg);
  118. break;
  119. }
  120. }
  121. /// <summary>
  122. /// 设置图片是否已裁剪
  123. /// </summary>
  124. /// <param name="isCropped"></param>
  125. public void SetIsCropped(bool isCropped)
  126. {
  127. try
  128. {
  129. _aiDiagnosisService.SetIsCropped(_type, isCropped);
  130. }
  131. catch (Exception ex)
  132. {
  133. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  134. }
  135. }
  136. /// <summary>
  137. /// 设置每秒图片吞吐量
  138. /// </summary>
  139. /// <param name="detectTps">每秒图片吞吐量,必须大于0</param>
  140. public void SetDetectTps(int detectTps)
  141. {
  142. if (detectTps <= 0)
  143. {
  144. throw new ArgumentOutOfRangeException($"DetectTps Must > 0. DetectTps : {detectTps}");
  145. }
  146. try
  147. {
  148. _aiDiagnosisService.SetDetectTps(_type, detectTps);
  149. }
  150. catch (Exception ex)
  151. {
  152. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  153. }
  154. }
  155. /// <summary>
  156. /// 设置间隔时间
  157. /// </summary>
  158. /// <param name="intervalTime"></param>
  159. public void SetIntervalTime(int intervalTime)
  160. {
  161. try
  162. {
  163. _aiDiagnosisService.SetIntervalTime(_type, intervalTime);
  164. }
  165. catch (Exception ex)
  166. {
  167. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  168. }
  169. }
  170. /// <summary>
  171. /// 设置检测模式
  172. /// </summary>
  173. /// <param name="detectMode"></param>
  174. public void SetDetectMode(AIEnumDetectMode detectMode)
  175. {
  176. try
  177. {
  178. _aiDiagnosisService.SetDetectMode(_type, detectMode);
  179. }
  180. catch (Exception ex)
  181. {
  182. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  183. }
  184. }
  185. /// <summary>
  186. /// 设置是否启用轮廓计算
  187. /// </summary>
  188. /// <param name="enableLesionSeg"></param>
  189. public void SetEnableLesionSeg(bool enableLesionSeg)
  190. {
  191. try
  192. {
  193. _aiDiagnosisService.SetEnableLesionSeg(_type, enableLesionSeg);
  194. }
  195. catch (Exception ex)
  196. {
  197. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  198. }
  199. }
  200. /// <summary>
  201. /// 设置是否启用描述
  202. /// </summary>
  203. /// <param name="enableDescription">是否启用病灶及脏器描述</param>
  204. public void SetEnableDescription(bool enableDescription)
  205. {
  206. try
  207. {
  208. _aiDiagnosisService.SetEnableDescription(_type, enableDescription, enableDescription);
  209. }
  210. catch (Exception ex)
  211. {
  212. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  213. }
  214. }
  215. /// <summary>
  216. /// 设置是否启用描述
  217. /// </summary>
  218. /// <param name="enableLessionDescription">是否启用病灶描述</param>
  219. /// <param name="enableOrganDescription">是否启用脏器描述</param>
  220. public void SetEnableDescription(bool enableLessionDescription, bool enableOrganDescription)
  221. {
  222. try
  223. {
  224. _aiDiagnosisService.SetEnableDescription(_type, enableLessionDescription, enableOrganDescription);
  225. }
  226. catch (Exception ex)
  227. {
  228. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  229. }
  230. }
  231. /// <summary>
  232. /// 检测单张Byte Image
  233. /// </summary>
  234. /// <param name="byteImage"></param>
  235. /// <returns></returns>
  236. public AIDiagResultPerImg DetectOneImage(byte[] byteImage)
  237. {
  238. if (byteImage == null)
  239. {
  240. throw new ArgumentNullException(nameof(byteImage));
  241. }
  242. try
  243. {
  244. _singleImagePipeClient.SendBytes(byteImage);
  245. var result = _aiDiagnosisService.DetectOneByteImage(_type);
  246. return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result);
  247. }
  248. catch (Exception ex)
  249. {
  250. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  251. return null;
  252. }
  253. }
  254. /// <summary>
  255. /// 检测单张Byte Image,其中enableLesionSeg与enableDescription仅此次调用生效
  256. /// </summary>
  257. /// <param name="byteImage"></param>
  258. /// <param name="enableLesionSeg">是否计算轮廓</param>
  259. /// <param name="enableDescription">是否计算病灶及脏器描述结果</param>
  260. /// <returns></returns>
  261. public AIDiagResultPerImg DetectOneImage(byte[] byteImage, bool enableLesionSeg, bool enableDescription)
  262. {
  263. if (byteImage == null)
  264. {
  265. throw new ArgumentNullException(nameof(byteImage));
  266. }
  267. try
  268. {
  269. _singleImagePipeClient.SendBytes(byteImage);
  270. var result = _aiDiagnosisService.DetectOneByteImageWithTempSetting(_type, enableLesionSeg, enableDescription, enableDescription);
  271. return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result);
  272. }
  273. catch (Exception ex)
  274. {
  275. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  276. return null;
  277. }
  278. }
  279. /// <summary>
  280. /// 检测单张Byte Image,其中enableLesionSeg与enableLesionDescription,enableOrganDescription仅此次调用生效
  281. /// </summary>
  282. /// <param name="byteImage"></param>
  283. /// <param name="enableLesionSeg">是否计算轮廓</param>
  284. /// <param name="enableLesionDescription">是否计算病灶描述结果</param>
  285. /// <param name="enableOrganDescription">是否计算脏器描述结果</param>
  286. /// <returns></returns>
  287. public AIDiagResultPerImg DetectOneImage(byte[] byteImage, bool enableLesionSeg, bool enableLesionDescription, bool enableOrganDescription)
  288. {
  289. if (byteImage == null)
  290. {
  291. throw new ArgumentNullException(nameof(byteImage));
  292. }
  293. try
  294. {
  295. _singleImagePipeClient.SendBytes(byteImage);
  296. var result = _aiDiagnosisService.DetectOneByteImageWithTempSetting(_type, enableLesionSeg, enableLesionDescription, enableOrganDescription);
  297. return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result);
  298. }
  299. catch (Exception ex)
  300. {
  301. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  302. return null;
  303. }
  304. }
  305. /// <summary>
  306. /// 检测单张Raw Image
  307. /// </summary>
  308. /// <param name="rawImage"></param>
  309. /// <returns></returns>
  310. public AIDiagResultPerImg DetectOneImage(AIRawImage rawImage)
  311. {
  312. if (rawImage == null)
  313. {
  314. throw new ArgumentNullException(nameof(rawImage));
  315. }
  316. try
  317. {
  318. _singleImagePipeClient.SendBytes(rawImage.DataBuffer);
  319. var result = _aiDiagnosisService.DetectOneRawImage(_type, rawImage.Height, rawImage.Width, rawImage.ColorType);
  320. return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result);
  321. }
  322. catch (Exception ex)
  323. {
  324. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  325. return null;
  326. }
  327. }
  328. /// <summary>
  329. /// 检测单张Raw Image,其中enableLesionSeg与enableDescription仅此次调用生效
  330. /// </summary>
  331. /// <param name="rawImage"></param>
  332. /// <param name="enableLesionSeg">是否计算轮廓</param>
  333. /// <param name="enableDescription">是否计算病灶及脏器描述结果</param>
  334. /// <returns></returns>
  335. public AIDiagResultPerImg DetectOneImage(AIRawImage rawImage, bool enableLesionSeg, bool enableDescription)
  336. {
  337. if (rawImage == null)
  338. {
  339. throw new ArgumentNullException(nameof(rawImage));
  340. }
  341. try
  342. {
  343. _singleImagePipeClient.SendBytes(rawImage.DataBuffer);
  344. var result = _aiDiagnosisService.DetectOneRawImageWithTempSetting(_type, rawImage.Height, rawImage.Width, rawImage.ColorType, enableLesionSeg, enableDescription, enableDescription);
  345. return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result);
  346. }
  347. catch (Exception ex)
  348. {
  349. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  350. return null;
  351. }
  352. }
  353. /// <summary>
  354. /// 检测单张Raw Image,其中enableLesionSeg与enableLesionDescription,enableOrganDescription仅此次调用生效
  355. /// </summary>
  356. /// <param name="rawImage"></param>
  357. /// <param name="enableLesionSeg">是否计算轮廓</param>
  358. /// <param name="enableLesionDescription">是否计算病灶描述结果</param>
  359. /// <param name="enableOrganDescription">是否计算脏器描述结果</param>
  360. /// <returns></returns>
  361. public AIDiagResultPerImg DetectOneImage(AIRawImage rawImage, bool enableLesionSeg, bool enableLesionDescription, bool enableOrganDescription = false)
  362. {
  363. if (rawImage == null)
  364. {
  365. throw new ArgumentNullException(nameof(rawImage));
  366. }
  367. try
  368. {
  369. _singleImagePipeClient.SendBytes(rawImage.DataBuffer);
  370. var result = _aiDiagnosisService.DetectOneRawImageWithTempSetting(_type, rawImage.Height, rawImage.Width, rawImage.ColorType, enableLesionSeg, enableLesionDescription, enableOrganDescription);
  371. return AICommonConvertHelper.ConvertTransAIDiagResultPerImgToAIDiagResultPerImg(result);
  372. }
  373. catch (Exception ex)
  374. {
  375. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  376. return null;
  377. }
  378. }
  379. /// <summary>
  380. /// 评估单幅图像 ,图像计算完成后,使用者希望调整结果,使部分结果在选定的矩形框内。
  381. /// </summary>
  382. /// <param name="aiRect">使用者给出的矩形框</param>
  383. /// <param name="aiDiagResultPerImg">图像的初始计算结果</param>
  384. /// <summary>
  385. public AIDiagResultPerImg CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRect(byte[] bytesImage, AIRect aiRect, AIDiagResultPerImg aiDiagResultPerImg)
  386. {
  387. throw new NotSupportedException("CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRectWithBytesImage Only Support Cartoid Diagnosis");
  388. }
  389. /// <summary>
  390. /// 评估单幅图像 ,图像计算完成后,使用者希望调整结果,使部分结果在选定的矩形框内。
  391. /// </summary>
  392. /// <param name="aiRect">使用者给出的矩形框</param>
  393. /// <param name="aiDiagResultPerImg">图像的初始计算结果</param>
  394. public AIDiagResultPerImg CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRect(AIRawImage rawImage, AIRect aiRect, AIDiagResultPerImg aiDiagResultPerImg)
  395. {
  396. throw new NotSupportedException("CalculateCarotidInnerDiameterAndIntimaMediaThicknessInSpecifiedRectWithBytesImage Only Support Cartoid Diagnosis");
  397. }
  398. private void OnByteImageProvided(object sender, byte[] byteImage)
  399. {
  400. try
  401. {
  402. if (byteImage == null)
  403. {
  404. return;
  405. }
  406. _byteImageProviderPipeClient?.SendBytes(byteImage);
  407. _aiDiagnosisService.SendByteImageData(_type);
  408. }
  409. catch (Exception ex)
  410. {
  411. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  412. }
  413. }
  414. private void OnRawImageProvided(object sender, AIRawImage rawImage)
  415. {
  416. try
  417. {
  418. if (rawImage == null)
  419. {
  420. return;
  421. }
  422. _rawImageProviderPipeClient?.SendBytes(rawImage.DataBuffer);
  423. _aiDiagnosisService.SendRawImageData(_type, rawImage.Height, rawImage.Width, rawImage.ColorType);
  424. }
  425. catch (Exception ex)
  426. {
  427. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  428. }
  429. }
  430. /// <summary>
  431. /// Close AI Diagnosis
  432. /// </summary>
  433. public void Close()
  434. {
  435. try
  436. {
  437. if (_disposed)
  438. {
  439. return;
  440. }
  441. _initialized = false;
  442. if (_imageProvider != null)
  443. {
  444. _imageProvider.ByteImageProvided -= OnByteImageProvided;
  445. _imageProvider.RawImageProvided -= OnRawImageProvided;
  446. _imageProvider.Stop();
  447. _imageProvider = null;
  448. }
  449. _aiDiagnosisService.Close(_type);
  450. }
  451. catch (Exception ex)
  452. {
  453. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  454. }
  455. }
  456. public void Dispose()
  457. {
  458. try
  459. {
  460. if (!_disposed)
  461. {
  462. _initialized = false;
  463. if (AIManager.Instance.AINotificationManager != null)
  464. {
  465. AIManager.Instance.AINotificationManager.NotificationReceived -= OnNotificationReceived;
  466. }
  467. if (_imageProvider != null)
  468. {
  469. _imageProvider.ByteImageProvided -= OnByteImageProvided;
  470. _imageProvider.RawImageProvided -= OnRawImageProvided;
  471. _imageProvider.Stop();
  472. _imageProvider = null;
  473. }
  474. if (_singleImagePipeClient != null)
  475. {
  476. _singleImagePipeClient.Dispose();
  477. _singleImagePipeClient.LogMsgThrow -= OnLogMsgThrow;
  478. _singleImagePipeClient = null;
  479. }
  480. if (_rawImageProviderPipeClient != null)
  481. {
  482. _rawImageProviderPipeClient.Dispose();
  483. _rawImageProviderPipeClient.LogMsgThrow -= OnLogMsgThrow;
  484. _rawImageProviderPipeClient = null;
  485. }
  486. if (_byteImageProviderPipeClient != null)
  487. {
  488. _byteImageProviderPipeClient.Dispose();
  489. _byteImageProviderPipeClient.LogMsgThrow -= OnLogMsgThrow;
  490. _byteImageProviderPipeClient = null;
  491. }
  492. _disposed = true;
  493. }
  494. }
  495. catch (Exception ex)
  496. {
  497. AIManager.Instance.AILogManager?.WriteLogInfo(new AILogEventArgs(AIEnumLogType.ErrorLog, $"错误方法名:{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}, 错误信息:{ex}"));
  498. }
  499. }
  500. }
  501. }