ThyroidDiagnosis.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using WingInterfaceLibrary.Enum;
  4. namespace WingAIDiagnosisService.Manage
  5. {
  6. /// <summary>
  7. /// 甲状腺诊断
  8. /// </summary>
  9. public class ThyroidDiagnosis : BaseDiagnosis
  10. {
  11. private AIThyroidLabelEnum? _mimanLabel;
  12. private DiagnosisPerImageModel _mimanDiagnosisImage = null;
  13. public ThyroidDiagnosis(List<DiagnosisPerImageModel> recordResult, DiagnosisOrganEnum organ)
  14. : base(recordResult, organ)
  15. {
  16. }
  17. #region Private
  18. /// <summary>
  19. /// 判断是否弥漫性图像
  20. /// </summary>
  21. /// <param name="label"></param>
  22. /// <returns></returns>
  23. private bool IsMiMan(int label)
  24. {
  25. switch (label)
  26. {
  27. case (int)AIThyroidLabelEnum.DiffuseDisease://弥漫性图像,无描述
  28. return true;
  29. }
  30. return false;
  31. }
  32. private AIDetectedObject IsValidDetectedObjectInfo(AIDetectedObject detectedObjectInfo)
  33. {
  34. if (detectedObjectInfo.Label == 0)
  35. {
  36. return detectedObjectInfo;
  37. }
  38. if (IsMiMan(detectedObjectInfo.Label))
  39. {
  40. return detectedObjectInfo;
  41. }
  42. if (detectedObjectInfo.Descriptions == null || !detectedObjectInfo.Descriptions.Any())
  43. {
  44. return null;
  45. }
  46. var lesionSizeDescription = detectedObjectInfo.Descriptions.FirstOrDefault(d => d.Type == DiagnosisDescription.LesionSize && !string.IsNullOrWhiteSpace(d.Value));
  47. if (lesionSizeDescription == null)
  48. {
  49. return null;
  50. }
  51. var lessionSizeInfo = Newtonsoft.Json.JsonConvert.DeserializeObject<AIDiagnosisLesionSize>(lesionSizeDescription.Value);
  52. if (lessionSizeInfo.VerticalLengthInPixel == 0 || lessionSizeInfo.HorizontalLengthInPixel == 0)
  53. {
  54. return null;
  55. }
  56. return detectedObjectInfo;
  57. }
  58. private bool CheckIsThyroid(List<DiagnosisPerImageModel> result)
  59. {
  60. var thyroidCount = result.Where(a => a.PriorityScore > 0).Count();
  61. var totalCount = result.Count;
  62. var thyroidRate = thyroidCount * 1.0 / totalCount * 1.0;
  63. return thyroidRate > 1 / 3.0;
  64. }
  65. private bool ExistAIData(IEnumerable<AIDiagnosisResultPerOrgan> organDiagResults, AIThyroidLabelEnum label)
  66. {
  67. if (organDiagResults == null)
  68. return false;
  69. foreach (var record in organDiagResults)
  70. {
  71. if (record.DetectedObjects == null)
  72. continue;
  73. if (record.Organ != DiagnosisOrganEnum.Thyroid)
  74. continue;
  75. if (label == AIThyroidLabelEnum.TIRADS0)//TODO 是否未见异常
  76. {
  77. if (record.DetectedObjects.Any(a => a.Label == (int)label))
  78. return true;
  79. }
  80. else
  81. {
  82. if (record.DetectedObjects.Any(a => a.Label == (int)label) && record.DetectedObjects.All(d => IsValidDetectedObjectInfo(d) != null))
  83. return true;
  84. }
  85. }
  86. return false;
  87. }
  88. #endregion
  89. public override AIDiagnosisResultPerOrgan CheckResultValid(AIDiagnosisResultPerOrgan message)
  90. {
  91. if (message.Organ != DiagnosisOrganEnum.Thyroid)
  92. {
  93. return null;
  94. }
  95. var result = message;
  96. var validDetectedObjects = new List<AIDetectedObject>();
  97. foreach (var obj in message.DetectedObjects)
  98. {
  99. var obj_new = IsValidDetectedObjectInfo(obj);
  100. if (obj_new != null)
  101. {
  102. validDetectedObjects.Add(obj_new);
  103. }
  104. }
  105. if (validDetectedObjects.Any())
  106. {
  107. result.DetectedObjects = validDetectedObjects.ToList();
  108. return result;
  109. }
  110. return null;
  111. }
  112. public override DiagnosisConclusion GetAIStatus()
  113. {
  114. var status = DiagnosisConclusion.Unrecognized;
  115. bool existMalignant = false;
  116. bool existBenign = false;
  117. if (RecordDiagnosisResult != null && RecordDiagnosisResult.Any())
  118. {
  119. if (!CheckIsThyroid(RecordDiagnosisResult))
  120. return status;
  121. foreach (var diagResult in RecordDiagnosisResult)
  122. {
  123. if (existMalignant && existBenign)
  124. break;
  125. if (diagResult.DiagResultsForEachOrgan != null && diagResult.PriorityScore > 0)
  126. {
  127. foreach (var organ in diagResult.DiagResultsForEachOrgan)
  128. {
  129. if (organ.DetectedObjects != null)
  130. {
  131. if (!existMalignant)
  132. {
  133. if (organ.DetectedObjects.Any(a => a.Label >= 4))
  134. {
  135. existMalignant = true;
  136. }
  137. }
  138. if (!existBenign)
  139. {
  140. if (organ.DetectedObjects.Any(a => a.Label >= 1 && a.Label < 4))
  141. {
  142. existBenign = true;
  143. }
  144. }
  145. }
  146. }
  147. if (existMalignant)
  148. {
  149. status = existBenign ? DiagnosisConclusion.BenignAndMalignant : DiagnosisConclusion.Malignant;
  150. }
  151. else
  152. {
  153. status = existBenign ? DiagnosisConclusion.Benign : DiagnosisConclusion.NoObviousLesion;
  154. }
  155. }
  156. }
  157. }
  158. return status;
  159. }
  160. /// <summary>
  161. /// 是否恶性病灶
  162. /// </summary>
  163. /// <param name="label"></param>
  164. /// <returns></returns>
  165. protected override bool IsMalignant(AIDetectedObject detectedObject)
  166. {
  167. return (detectedObject.Label == (int)AIThyroidLabelEnum.TIRADS4a ||
  168. detectedObject.Label == (int)AIThyroidLabelEnum.TIRADS4b ||
  169. detectedObject.Label == (int)AIThyroidLabelEnum.TIRADS4c ||
  170. detectedObject.Label == (int)AIThyroidLabelEnum.TIRADS5);
  171. }
  172. public override List<DiagnosisPerImageModel> GetReportResults()
  173. {
  174. if (!RecordDiagnosisResult.Any())
  175. {
  176. return RecordDiagnosisResult;
  177. }
  178. var reportResults = new List<DiagnosisPerImageModel>();
  179. for (var i = 1; i <= (int)AIThyroidLabelEnum.DiffuseDisease; i++)
  180. {
  181. var label = (AIThyroidLabelEnum)i;
  182. var data = RecordDiagnosisResult.FirstOrDefault(a => ExistAIData(a.DiagResultsForEachOrgan, label));
  183. if (data != null)
  184. {
  185. if (!reportResults.Any(a => a.RemedicalCode == data.RemedicalCode && a.Index == data.Index))
  186. {
  187. reportResults.Add(data);
  188. }
  189. }
  190. }
  191. if (!reportResults.Any())
  192. {
  193. var label = AIThyroidLabelEnum.TIRADS0; //未见异常
  194. var data = RecordDiagnosisResult.FirstOrDefault(a => ExistAIData(a.DiagResultsForEachOrgan, label));
  195. if (data != null)
  196. {
  197. if (!reportResults.Any(a => a.RemedicalCode == data.RemedicalCode && a.Index == data.Index))
  198. {
  199. reportResults.Add(data);
  200. }
  201. }
  202. }
  203. RecordDiagnosisResult = reportResults;
  204. InitialAIImage();
  205. return RecordDiagnosisResult;
  206. }
  207. }
  208. }