MainWindow.xaml.cs 132 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using System.Collections.Generic;
  5. using System.Windows;
  6. using System.Windows.Shapes;
  7. using System.Windows.Input;
  8. using System.Drawing;
  9. using System.Data.SQLite;
  10. using Newtonsoft.Json;
  11. using System.Security.Cryptography;
  12. using System.Windows.Media.Imaging;
  13. using System.Windows.Controls;
  14. using System.Drawing.Imaging;
  15. using System.Windows.Threading;
  16. using Microsoft.Win32;
  17. using AI.Common.Interface;
  18. using RawImageShowUtilsLib;
  19. using AIModuleResultShowUtilsLib;
  20. using System.Xml.Linq;
  21. using AI.Common.Implements;
  22. using static System.Windows.Forms.AxHost;
  23. using System.Security.Policy;
  24. using System.Windows.Media;
  25. using System.ComponentModel;
  26. using System.Windows.Forms;
  27. namespace AILesionDescriptionGTGenerator
  28. {
  29. /// <summary>
  30. /// Canvas上绘制的目标有几种类型
  31. /// </summary>
  32. public enum EnumCanvasItemType
  33. {
  34. Drawing,
  35. Choosed,
  36. Existed,
  37. }
  38. /// <summary>
  39. /// 线的种类
  40. /// </summary>
  41. public enum EnumCanvasLineType
  42. {
  43. Horizontal,
  44. Vertical,
  45. }
  46. /// <summary>
  47. /// 鼠标状态
  48. /// </summary>
  49. public enum EnumMouseOperType
  50. {
  51. None,
  52. DrawingContour,
  53. DrawingHorizonLines,
  54. DrawingVerticalLines,
  55. DrawingPoint,
  56. }
  57. public enum EnumDesShapeValue
  58. {
  59. /// <summary>
  60. /// 椭圆形
  61. /// </summary>
  62. Oval,
  63. /// <summary>
  64. /// 类圆形
  65. /// </summary>
  66. Round,
  67. /// <summary>
  68. /// 不规则形
  69. /// </summary>
  70. Irregular,
  71. }
  72. /// <summary>
  73. /// 方向描述可能的结果值
  74. /// </summary>
  75. public enum EnumDesOrientationValue
  76. {
  77. /// <summary>
  78. /// 平行
  79. /// </summary>
  80. Parallel,
  81. /// <summary>
  82. /// 非平行
  83. /// </summary>
  84. NonParallel,
  85. }
  86. /// <summary>
  87. /// 内部回声描述可能的结果
  88. /// </summary>
  89. public enum EnumDesEchoPatternValue
  90. {
  91. /// <summary>
  92. /// 无回声
  93. /// </summary>
  94. Anechoic,
  95. /// <summary>
  96. /// 低回声
  97. /// </summary>
  98. Hypoechoic,
  99. /// <summary>
  100. /// 等回声
  101. /// </summary>
  102. Isoechoic,
  103. /// <summary>
  104. /// 高回声
  105. /// </summary>
  106. Hyperechoic,
  107. /// <summary>
  108. /// 混合回声
  109. /// </summary>
  110. Complex,
  111. /// <summary>
  112. /// 强回声
  113. /// </summary>
  114. Strongechoic,
  115. }
  116. /// <summary>
  117. /// 病灶边界描述可能的结果
  118. /// </summary>
  119. public enum EnumDesLesionBoundaryValue
  120. {
  121. /// <summary>
  122. /// 清晰
  123. /// </summary>
  124. AbruptInterface,
  125. /// <summary>
  126. /// 模糊
  127. /// </summary>
  128. EchogenicHalo,
  129. }
  130. /// <summary>
  131. /// 病灶边缘描述的可能结果
  132. /// </summary>
  133. public enum EnumDesMarginValue
  134. {
  135. /// <summary>
  136. /// 光整
  137. /// </summary>
  138. Circumscribed,
  139. /// <summary>
  140. /// 不光整
  141. /// </summary>
  142. NonCircumscribed,
  143. }
  144. /// <summary>
  145. /// 病灶信息
  146. /// </summary>
  147. public class LesionInfo
  148. {
  149. /// <summary>
  150. /// 病灶轮廓
  151. /// </summary>
  152. public List<Point2D> Contour { get; set; } = new List<Point2D>();
  153. /// <summary>
  154. /// 病灶形状
  155. /// </summary>
  156. public EnumDesShapeValue Shape { get; set; } = EnumDesShapeValue.Oval;
  157. /// <summary>
  158. /// 方向
  159. /// </summary>
  160. public EnumDesOrientationValue Orientation { get; set; } = EnumDesOrientationValue.Parallel;
  161. /// <summary>
  162. /// 回声类型
  163. /// </summary>
  164. public EnumDesEchoPatternValue EchoPattern { get; set; } = EnumDesEchoPatternValue.Hypoechoic;
  165. /// <summary>
  166. /// 边界清晰不清晰
  167. /// </summary>
  168. public EnumDesLesionBoundaryValue Boundary { get; set; } = EnumDesLesionBoundaryValue.AbruptInterface;
  169. /// <summary>
  170. /// 边缘光整不光整
  171. /// </summary>
  172. public EnumDesMarginValue Margin { get; set; } = EnumDesMarginValue.Circumscribed;
  173. /// <summary>
  174. /// 横径起点
  175. /// </summary>
  176. public Point2D HorizontalPoint1 { get; set; } = new Point2D();
  177. /// <summary>
  178. /// 横径终点
  179. /// </summary>
  180. public Point2D HorizontalPoint2 { get; set; } = new Point2D();
  181. /// <summary>
  182. /// 纵径起点
  183. /// </summary>
  184. public Point2D VerticalPoint1 { get; set; } = new Point2D();
  185. /// <summary>
  186. /// 纵径终点
  187. /// </summary>
  188. public Point2D VerticalPoint2 { get; set; } = new Point2D();
  189. /// <summary>
  190. /// 内容完整
  191. /// </summary>
  192. public bool IsCompleted
  193. {
  194. get
  195. {
  196. return Contour.Count > 0 && HorizontalPoint1 != HorizontalPoint2 &&
  197. VerticalPoint1 != VerticalPoint2;
  198. }
  199. }
  200. }
  201. /// <summary>
  202. /// 病灶描述GT图像信息
  203. /// </summary>
  204. public class LesionDesGTImgInfo
  205. {
  206. public string ImageId { get; set; }
  207. /// <summary>
  208. /// 病灶分级
  209. /// </summary>
  210. public List<int> Label { get; set; }
  211. /// <summary>
  212. /// 该图上所有病灶的标准描述
  213. /// </summary>
  214. public List<LesionInfo> Lesions { get; set; }
  215. }
  216. /// <summary>
  217. /// MainWindow.xaml 的交互逻辑
  218. /// </summary>
  219. public partial class MainWindow : Window
  220. {
  221. #region private variables
  222. private readonly string _dataFolder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(
  223. AppDomain.CurrentDomain.BaseDirectory)),"LesionDescriptionGTDatas");
  224. private readonly string _dbPath;
  225. private readonly string _imageDataFolder;
  226. private readonly string _dbModelPath;
  227. private List<LesionDesGTImgInfo> _allImages = new List<LesionDesGTImgInfo>();
  228. private volatile int _imgIndex = 0;
  229. private List<LesionInfo> _lesions = new List<LesionInfo>();
  230. private volatile int _lesionIndex = 0;
  231. private volatile bool _modified = false;
  232. private BitmapImage _origimg = null;
  233. private BitmapImage _drawimg = null;
  234. // 鼠标动作
  235. private volatile EnumMouseOperType _mouseOper = EnumMouseOperType.None;
  236. private volatile bool _mouseLeftBtnPressed = false;
  237. // 鼠标绘制的起始位置(画横轴,纵轴时需要)
  238. private System.Windows.Point _mouseStartPos;
  239. // 绘制中的所有轮廓点的集合
  240. private List<System.Windows.Point> _drawingPoints = new List<System.Windows.Point>();
  241. private volatile bool _canAutoFinish = false;
  242. //private DataBase _creatBd = new DataBase();
  243. private Bitmap _image = null;
  244. private BitmapImage _dstImgWin = null;
  245. private LesionDesGTImgInfo _modelResult = new LesionDesGTImgInfo(); //模型检测出的病灶结果
  246. private volatile bool _showModelResult = false;
  247. private volatile int _lesionOriModelIndex = 0;//左侧界面病灶ID
  248. private List<int> _lesionsLabels = new List<int>();
  249. //private List<int> _lesionsModelLabels = new List<int>();
  250. private volatile int _lesionLabelIndex = 0;
  251. private volatile bool _showDrawingResult = false;
  252. private volatile int _num = 0;
  253. private IModule _module;
  254. private string _currentPath;
  255. private InferenceConfig _inferConfig = new InferenceConfig();
  256. private string _netDir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks");
  257. private volatile string _processId = string.Empty;
  258. private volatile string _caseId = string.Empty;
  259. private volatile string _dataId = string.Empty;
  260. private volatile bool _readingVideo;
  261. private volatile int _frameIndex;
  262. IDetectedObject[] _newModelResult;
  263. //回声
  264. private int _Anechoic_Anechoic_num = 0; //无回声 判为 无回声 的数目
  265. private int _Anechoic_Hypoechoic_num = 0; //无回声 判为 低回声 的数目
  266. private int _Anechoic_Isoechoic_num = 0; //无回声 判为 等回声 的数目
  267. private int _Anechoic_Hyperechoic_num = 0; //无回声 判为 高回声 的数目
  268. private int _Anechoic_Complex_num = 0; //无回声 判为 Complex 的数目
  269. private int _Hyperechoic_Hyperechoic_num = 0; //高回声 判为 高回声
  270. private int _Hyperechoic_Anechoic_num = 0;
  271. private int _Hyperechoic_Isoechoic_num = 0;
  272. private int _Hyperechoic_Hypoechoic_num = 0;
  273. private int _Hyperechoic_Complex_num = 0;
  274. private int _Isoechoic_Isoechoic_num = 0; //等回声 判为 等回声
  275. private int _Isoechoic_Anechoic_num = 0;
  276. private int _Isoechoic_Hyperechoic_num = 0;
  277. private int _Isoechoic_Hypoechoic_num = 0;
  278. private int _Isoechoic_Complex_num = 0;
  279. private int _Hypoechoic_Hypoechoic_num = 0; //低回声 判为 低回声
  280. private int _Hypoechoic_Anechoic_num = 0;
  281. private int _Hypoechoic_Hyperechoic_num = 0;
  282. private int _Hypoechoic_Isoechoic_num = 0;
  283. private int _Hypoechoic_Complex_num = 0;
  284. private int _Complex_Complex_num = 0; //极低回声 判为 极低回声
  285. private int _Complex_Anechoic_num = 0;
  286. private int _Complex_Hyperechoic_num = 0;
  287. private int _Complex_Isoechoic_num = 0;
  288. private int _Complex_Hypoechoic_num = 0;
  289. //形状
  290. private int _Oval_Oval_num = 0; //椭圆形 判为 椭圆形
  291. private int _Oval_Round_num = 0; //椭圆形 判为 类圆形
  292. private int _Oval_Irregular_num = 0; //椭圆形 判为 不规则形
  293. private int _Round_Round_num = 0; //类圆形 判为 类圆形
  294. private int _Round_Oval_num = 0; //类圆形 判为 椭圆形
  295. private int _Round_Irregular_num = 0; //类圆形 判为 不规则形
  296. private int _Irregular_Irregular_num = 0; //不规则形 判为 不规则形
  297. private int _Irregular_Oval_num = 0; //不规则形 判为 椭圆形
  298. private int _Irregular_Round_num = 0; //不规则形 判为 类圆形
  299. //边缘
  300. private int _Circumscribed_Circumscribed_num = 0; //光整 判为 不光整
  301. private int _Circumscribed_NonCircumscribed_num = 0;
  302. private int _NonCircumscribed_NonCircumscribed_num = 0; //不光整 判为 光整
  303. private int _NonCircumscribed_Circumscribed_num = 0;
  304. //边界
  305. private int _AbruptInterface_AbruptInterface_num; //清晰--清晰
  306. private int _AbruptInterface_EchogenicHalo_num; //清晰--模糊
  307. private int _EchogenicHalo_EchogenicHalo_num; //模糊--模糊
  308. private int _EchogenicHalo_AbruptInterface_num; //模糊--清晰
  309. //方向
  310. private int _Parallel_Parallel_num; //平行--平行
  311. private int _Parallel_NonParallel_num; //平行--非平行
  312. private int _NonParallel_NonParallel_num; //非平行--非平行
  313. private int _NonParallel_Parallel_num; //非平行--平行
  314. #endregion
  315. #region 用户界面响应
  316. public MainWindow()
  317. {
  318. InitializeComponent();
  319. InitializeComboBoxLesionsLabel();
  320. _dbPath = System.IO.Path.Combine(_dataFolder, "lesion_des_gt_datas.db");
  321. _imageDataFolder = System.IO.Path.Combine(_dataFolder, "Images");
  322. _currentPath = System.Environment.CurrentDirectory;
  323. _module = new AI.Vaid.Modules.BreastLesionDetect.BreastLesionDetect(_netDir, _inferConfig, EnumDeviceType.CPU);
  324. bool existDb = CreateDataBase();
  325. if(existDb)
  326. {
  327. AddNewImages(_imageDataFolder);
  328. }
  329. UserControlLesionSelected.NotifyLesionInfoEventArgs += OnLesionInfoSelectorEventOccur;
  330. ReadDataBase();
  331. DrawImage.Source = _drawimg;
  332. OrigImage.Source = _origimg;
  333. DetectImage(_image);
  334. }
  335. /// <summary>
  336. /// 点击 "前一幅图"
  337. /// </summary>
  338. /// <param name="sender"></param>
  339. /// <param name="e"></param>
  340. private void OnBtnPreviousImageClicked(object sender, RoutedEventArgs e)
  341. {
  342. // 查看当前图的ROI是否已经绘制完毕
  343. if (_lesions.Count > 0)
  344. {
  345. if (_lesions.Count != _lesionsLabels.Count)
  346. {
  347. System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
  348. return;
  349. }
  350. foreach (var lesion in _lesions)
  351. {
  352. if (!lesion.IsCompleted)
  353. {
  354. System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
  355. return;
  356. }
  357. }
  358. for (int i = 0; i < _lesionsLabels.Count; i++)//add
  359. {
  360. //if (_lesionsLabels[i] < 1)
  361. //{
  362. // string str = "请先将当前图像的描述的第:" + i.ToString() + "个病灶等级添加完整";
  363. // MessageBox.Show(str);
  364. // return;
  365. //}
  366. }
  367. }
  368. // 保存当前图的结果
  369. if (_modified)
  370. {
  371. SetLesions(_allImages[_imgIndex].ImageId, _lesions);
  372. SetLesionsLabels(_allImages[_imgIndex].ImageId, _lesionsLabels);
  373. }
  374. // 如果已经OK,则更新记录
  375. if (_imgIndex <= 0)
  376. {
  377. System.Windows.MessageBox.Show("已是第一个");
  378. return;
  379. }
  380. _imgIndex = _imgIndex - 1;
  381. _dstImgWin = null;
  382. _modelResult = null;
  383. _modelResult = new LesionDesGTImgInfo();
  384. CurrentImgIndexUpdated();
  385. _drawingPoints.Clear();//
  386. _lesionOriModelIndex = 0;
  387. DetectImage(_image);
  388. }
  389. /// <summary>
  390. /// 点击 "后一幅图"
  391. /// </summary>
  392. /// <param name="sender"></param>
  393. /// <param name="e"></param>
  394. private void OnBtnNextImageClicked(object sender, RoutedEventArgs e)
  395. {
  396. // 查看当前图像的ROI是否已经绘制完毕
  397. if (_lesions.Count > 0)
  398. {
  399. if (_lesions.Count != _lesionsLabels.Count)
  400. {
  401. System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
  402. return;
  403. }
  404. foreach (var lesion in _lesions)
  405. {
  406. if (!lesion.IsCompleted)
  407. {
  408. System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
  409. return;
  410. }
  411. }
  412. for(int i =0; i < _lesionsLabels.Count; i++)//add
  413. {
  414. //if (_lesionsLabels[i] <1)
  415. //{
  416. // string str = "请先将当前图像的描述的第:" + i.ToString() + "个病灶等级添加完整";
  417. // MessageBox.Show(str);
  418. // return;
  419. //}
  420. }
  421. }
  422. // 保存当前图的结果
  423. if (_modified)
  424. {
  425. SetLesions(_allImages[_imgIndex].ImageId, _lesions);
  426. SetLesionsLabels(_allImages[_imgIndex].ImageId, _lesionsLabels);
  427. }
  428. // 如果已经OK,则更新记录
  429. if (_imgIndex >= _allImages.Count - 1)
  430. {
  431. System.Windows.MessageBox.Show("已是最后一个");
  432. return;
  433. }
  434. _imgIndex = _imgIndex + 1;
  435. _dstImgWin = null;
  436. _modelResult = null;
  437. _modelResult = new LesionDesGTImgInfo();
  438. CurrentImgIndexUpdated();
  439. _drawingPoints.Clear();//
  440. _lesionOriModelIndex = 0;
  441. DetectImage(_image);
  442. }
  443. /// <summary>
  444. /// 选中的病灶改变
  445. /// </summary>
  446. /// <param name="sender"></param>
  447. /// <param name="e"></param>
  448. private void OnLesionSelectionChanged(object sender, SelectionChangedEventArgs e)
  449. {
  450. _lesionIndex = ComboBoxLesions.SelectedIndex;
  451. //_lesionIndex = 0;//add ???
  452. LesionsUpdated();
  453. }
  454. /// <summary>
  455. /// 删除选中的病灶
  456. /// </summary>
  457. /// <param name="sender"></param>
  458. /// <param name="e"></param>
  459. private void OnBtnDeleteSelROIClicked(object sender, RoutedEventArgs e)
  460. {
  461. if (_lesionIndex < 0)
  462. {
  463. System.Windows.MessageBox.Show("请先选择一个待删除的病灶");
  464. return;
  465. }
  466. // 先清空画布上旧的显示内容
  467. for (int ni = 0; ni < _lesions.Count; ni++)
  468. {
  469. RemoveContourInCanvas(ni.ToString());
  470. RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
  471. RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
  472. }
  473. _lesions.RemoveAt(_lesionIndex);
  474. _lesionsLabels.RemoveAt(_lesionIndex);
  475. _modified = true;
  476. if (_lesionIndex >= _lesions.Count)
  477. {
  478. if (_lesions.Count > 0)
  479. {
  480. _lesionIndex = 0;
  481. }
  482. else
  483. {
  484. _lesionIndex = -1;
  485. }
  486. }
  487. _drawingPoints.Clear();
  488. LesionsUpdated();
  489. }
  490. /// <summary>
  491. /// 新增病灶
  492. /// </summary>
  493. /// <param name="sender"></param>
  494. /// <param name="e"></param>
  495. private void OnBtnAddNewROIClicked(object sender, RoutedEventArgs e)
  496. {
  497. if (!UserControlLesionSelected.IsEmpty)
  498. {
  499. if (!UserControlLesionSelected.Lesion.IsCompleted)
  500. {
  501. System.Windows.MessageBox.Show("请先将现有病灶的描述添加完整后再增加新的病灶");
  502. return;
  503. }
  504. if(_lesionLabelIndex < 1)
  505. {
  506. System.Windows.MessageBox.Show("请先将当前病灶等级添加完整");
  507. return;
  508. }
  509. }
  510. _lesionIndex = _lesions.Count;
  511. _lesions.Add(new LesionInfo());
  512. _lesionsLabels.Add(-1);
  513. _modified = true;
  514. _drawingPoints.Clear();
  515. LesionsUpdated();
  516. }
  517. /// <summary>
  518. /// 画布尺寸改变
  519. /// </summary>
  520. /// <param name="sender"></param>
  521. /// <param name="e"></param>
  522. private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
  523. {
  524. MyCanvasDraw.Width = GridDrawImg.ActualWidth;
  525. MyCanvasDraw.Height = GridDrawImg.ActualHeight;
  526. ImageUpdated();
  527. UpdateLesionsInCanvas();
  528. UpdateLesionsIndex();
  529. }
  530. /// <summary>
  531. /// 鼠标左键按下
  532. /// </summary>
  533. /// <param name="sender"></param>
  534. /// <param name="e"></param>
  535. private void Canvas_MouseLeftBtnDown(object sender, MouseButtonEventArgs e)
  536. {
  537. System.Windows.Point mousePosInCanvas = e.GetPosition((IInputElement)sender);
  538. _mouseStartPos = mousePosInCanvas;
  539. //////////////////
  540. if (_drawingPoints.Count <= 0)
  541. {
  542. _drawingPoints = new List<System.Windows.Point>();
  543. }
  544. else
  545. {
  546. }
  547. //var dd = _mouseOper;
  548. if (_mouseOper == EnumMouseOperType.DrawingPoint)
  549. {
  550. _drawingPoints.Add(mousePosInCanvas);
  551. }
  552. else if(_mouseOper == EnumMouseOperType.None)
  553. {
  554. _canAutoFinish = false;
  555. //_drawingPoints.Add(mousePosInCanvas);
  556. }
  557. else
  558. {
  559. _canAutoFinish = false;
  560. _drawingPoints.Add(mousePosInCanvas);
  561. }
  562. //_drawingPoints = new List<System.Windows.Point>();
  563. //_canAutoFinish = false;
  564. //_drawingPoints.Add(mousePosInCanvas);
  565. _mouseLeftBtnPressed = true;
  566. }
  567. /// <summary>
  568. /// 鼠标左键弹起
  569. /// </summary>
  570. /// <param name="sender"></param>
  571. /// <param name="e"></param>
  572. private void Canvas_MouseLeftBtnUp(object sender, MouseButtonEventArgs e)
  573. {
  574. _mouseLeftBtnPressed = false;
  575. System.Windows.Point mousePosInCanvas = e.GetPosition((IInputElement)sender);
  576. Point2D mousePosInOrigImg = GetPosInOrigImage(mousePosInCanvas);
  577. Point2D startPosInOrigImg = GetPosInOrigImage(_mouseStartPos);
  578. switch (_mouseOper)
  579. {
  580. case EnumMouseOperType.DrawingContour:
  581. // 如果现在绘制的轮廓还未结束,就直接连接起点终点,将现在绘制的轮廓线,转换成图像坐标,发送给LesionInfoSelector,_mouseOper重置成空
  582. if (_drawingPoints[_drawingPoints.Count - 1] != _drawingPoints[0])
  583. {
  584. _drawingPoints.Add(_drawingPoints[0]);
  585. }
  586. List<Point2D> contourInOrigImg = new List<Point2D>();
  587. foreach (var point in _drawingPoints)
  588. {
  589. contourInOrigImg.Add(GetPosInOrigImage(point));
  590. }
  591. _drawingPoints = new List<System.Windows.Point>();
  592. _mouseOper = EnumMouseOperType.None;
  593. RemoveContourInCanvas("drawing");
  594. UserControlLesionSelected.SetContour(contourInOrigImg);
  595. //_canAutoFinish = false;
  596. break;
  597. case EnumMouseOperType.DrawingPoint:
  598. //if (_drawingPoints[_drawingPoints.Count - 1] != _drawingPoints[0])
  599. {
  600. //_drawingPoints.Add(_drawingPoints[0]);
  601. DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawingPt");
  602. // 如果已经很靠近起始点,就自动结束
  603. if (PointDistance(_drawingPoints[_drawingPoints.Count - 1], _drawingPoints[0]) < 5)
  604. {
  605. if (_canAutoFinish)
  606. {
  607. _drawingPoints.Add(_drawingPoints[0]);
  608. List<Point2D> contourInOrigImgPt = new List<Point2D>();
  609. foreach (var point in _drawingPoints)
  610. {
  611. contourInOrigImgPt.Add(GetPosInOrigImage(point));
  612. }
  613. _drawingPoints = new List<System.Windows.Point>();
  614. _mouseOper = EnumMouseOperType.None;
  615. RemoveContourInCanvas("drawingPt");
  616. UserControlLesionSelected.SetContour(contourInOrigImgPt);
  617. //_canAutoFinish = false;
  618. }
  619. }
  620. else
  621. {
  622. if (!_canAutoFinish)
  623. {
  624. _canAutoFinish = true;
  625. }
  626. }
  627. }
  628. break;
  629. case EnumMouseOperType.DrawingHorizonLines:
  630. // 将当前绘制的横径起点终点,转换成图像坐标,发送给LesionInfoSelector,_mouseOper重置成空
  631. _mouseOper = EnumMouseOperType.None;
  632. RemoveLineInCanvas(EnumCanvasLineType.Horizontal,"drawing");
  633. UserControlLesionSelected.SetHorizontalAxis(startPosInOrigImg, mousePosInOrigImg);
  634. break;
  635. case EnumMouseOperType.DrawingVerticalLines:
  636. // 将当前绘制的纵径起点终点,转换成图像坐标,发送给LesionInfoSelector,_mouseOper重置成空
  637. _mouseOper = EnumMouseOperType.None;
  638. RemoveLineInCanvas(EnumCanvasLineType.Vertical, "drawing");
  639. UserControlLesionSelected.SetVerticalAxis(startPosInOrigImg, mousePosInOrigImg);
  640. break;
  641. }
  642. }
  643. /// <summary>
  644. /// 鼠标移动
  645. /// </summary>
  646. /// <param name="sender"></param>
  647. /// <param name="e"></param>
  648. private void Canvas_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
  649. {
  650. // 显示鼠标位置
  651. System.Windows.Point mousePosInCanvas = e.GetPosition((IInputElement)sender);
  652. Point2D mousePosInOrigImg = GetPosInOrigImage(mousePosInCanvas);
  653. TextBlockMousePosition.Text = mousePosInOrigImg.X.ToString() + "," + mousePosInOrigImg.Y.ToString();
  654. // 判断鼠标当前状态
  655. if (e.LeftButton == MouseButtonState.Pressed)
  656. {
  657. switch (_mouseOper)
  658. {
  659. case EnumMouseOperType.DrawingContour:
  660. _drawingPoints.Add(mousePosInCanvas);
  661. // 如果该图选中病灶已经有描述了,先清除Canvas上显示的,以免影响标注
  662. if(_lesions[_lesionIndex].Contour.Count > 0)
  663. {
  664. RemoveContourInCanvas(_lesionIndex.ToString());
  665. }
  666. // 更新显示正在绘制的轮廓线
  667. DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawing");
  668. // 如果已经很靠近起始点,就自动结束
  669. if (PointDistance(_drawingPoints[_drawingPoints.Count - 1], _drawingPoints[0]) < 5)
  670. {
  671. if (_canAutoFinish)
  672. {
  673. _drawingPoints.Add(_drawingPoints[0]);
  674. List<Point2D> contourInOrigImg = new List<Point2D>();
  675. foreach (var point in _drawingPoints)
  676. {
  677. contourInOrigImg.Add(GetPosInOrigImage(point));
  678. }
  679. _drawingPoints = new List<System.Windows.Point>();
  680. _mouseOper = EnumMouseOperType.None;
  681. RemoveContourInCanvas("drawing");
  682. UserControlLesionSelected.SetContour(contourInOrigImg);
  683. }
  684. }
  685. else
  686. {
  687. if (!_canAutoFinish)
  688. {
  689. _canAutoFinish = true;
  690. }
  691. }
  692. break;
  693. case EnumMouseOperType.DrawingPoint:
  694. //_drawingPoints.Add(mousePosInCanvas);
  695. //DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawing");
  696. break;
  697. case EnumMouseOperType.DrawingHorizonLines:
  698. // 如果该图选中病灶已经有横轴了,先清除Canvas上显示的,以免影响标注
  699. RemoveLineInCanvas(EnumCanvasLineType.Horizontal, _lesionIndex.ToString());
  700. // 更新显示正在绘制的横轴
  701. DrawLineInCanvas(_mouseStartPos, mousePosInCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Drawing, "drawing");
  702. break;
  703. case EnumMouseOperType.DrawingVerticalLines:
  704. // 如果该图选中病灶已经有纵轴了,先清除Canvas上显示的,以免影响标注
  705. RemoveLineInCanvas(EnumCanvasLineType.Vertical, _lesionIndex.ToString());
  706. // 更新显示正在绘制的纵轴
  707. DrawLineInCanvas(_mouseStartPos, mousePosInCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Drawing, "drawing");
  708. break;
  709. }
  710. }
  711. else
  712. {
  713. if (_mouseLeftBtnPressed)
  714. {
  715. Canvas_MouseLeftBtnUp(MyCanvasDraw, new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left));
  716. }
  717. }
  718. }
  719. #endregion
  720. #region public funcs
  721. /// <summary>
  722. /// 设置该图像的病灶
  723. /// </summary>
  724. /// <param name="imgId"></param>
  725. /// <param name="contour"></param>
  726. public void SetLesions(string imgId, List<LesionInfo> lesions)
  727. {
  728. try
  729. {
  730. SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
  731. dbCon.Open();
  732. SQLiteCommand dbCmd;
  733. dbCmd = dbCon.CreateCommand();
  734. string strLesions = JsonConvert.SerializeObject(lesions);
  735. dbCmd.CommandText = "update LesionDesGTDatas set Lesions='" + strLesions + "' where ImageId='" + imgId + "'";
  736. dbCmd.ExecuteNonQuery();
  737. dbCmd.Dispose();
  738. SQLiteDataReader dbreader;
  739. dbCmd = dbCon.CreateCommand();
  740. dbCmd.CommandText = "select * from LastModification";
  741. dbreader = dbCmd.ExecuteReader();
  742. if (dbreader.HasRows)
  743. {
  744. dbreader.Close();
  745. dbCmd.Dispose();
  746. // 更新
  747. dbCmd = dbCon.CreateCommand();
  748. dbCmd.CommandText = "update LastModification set ImageId='" + imgId + "'";
  749. dbCmd.ExecuteNonQuery();
  750. dbCmd.Dispose();
  751. }
  752. else
  753. {
  754. // 新增
  755. dbCmd = dbCon.CreateCommand();
  756. dbCmd.CommandText = "insert into LastModification(ImageId) select '" + imgId + "'";
  757. dbCmd.ExecuteNonQuery();
  758. dbCmd.Dispose();
  759. }
  760. dbCon.Close();
  761. dbCon.Dispose();
  762. }
  763. catch (Exception excep)
  764. {
  765. System.Windows.MessageBox.Show("保存结果时出错!" + excep);
  766. }
  767. }
  768. /// <summary>
  769. /// 保存label
  770. /// </summary>
  771. /// <param name="input"></param>
  772. /// <returns></returns>
  773. public void SetLesionsLabels(string imgId, List<int> lesionsLabels)
  774. {
  775. try
  776. {
  777. SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
  778. dbCon.Open();
  779. SQLiteCommand dbCmd;
  780. dbCmd = dbCon.CreateCommand();
  781. string strLesionsLabel = JsonConvert.SerializeObject(lesionsLabels);
  782. dbCmd.CommandText = "update LesionDesGTDatas set Label='" + strLesionsLabel + "' where ImageId='" + imgId + "'";
  783. dbCmd.ExecuteNonQuery();
  784. dbCmd.Dispose();
  785. SQLiteDataReader dbreader;
  786. dbCmd = dbCon.CreateCommand();
  787. dbCmd.CommandText = "select * from LastModification";
  788. dbreader = dbCmd.ExecuteReader();
  789. if (dbreader.HasRows)
  790. {
  791. dbreader.Close();
  792. dbCmd.Dispose();
  793. // 更新
  794. dbCmd = dbCon.CreateCommand();
  795. dbCmd.CommandText = "update LastModification set ImageId='" + imgId + "'";
  796. dbCmd.ExecuteNonQuery();
  797. dbCmd.Dispose();
  798. }
  799. else
  800. {
  801. // 新增
  802. dbCmd = dbCon.CreateCommand();
  803. dbCmd.CommandText = "insert into LastModification(ImageId) select '" + imgId + "'";
  804. dbCmd.ExecuteNonQuery();
  805. dbCmd.Dispose();
  806. }
  807. dbCon.Close();
  808. dbCon.Dispose();
  809. }
  810. catch (Exception excep)
  811. {
  812. System.Windows.MessageBox.Show("保存病灶分级时出错!" + excep);
  813. }
  814. }
  815. #endregion
  816. #region private funcs
  817. private string ComputeHashCode(byte[] input)
  818. {
  819. MD5 md5 = MD5.Create();
  820. byte[] hash = md5.ComputeHash(input);
  821. StringBuilder sb = new StringBuilder();
  822. foreach (var b in hash)
  823. {
  824. sb.Append(b.ToString("x2"));
  825. }
  826. string hashstr = sb.ToString();
  827. sb.Clear();
  828. return hashstr;
  829. }
  830. /// <summary>
  831. /// 读入数据库
  832. /// </summary>
  833. private void ReadDataBase()
  834. {
  835. try
  836. {
  837. if (!File.Exists(_dbPath))
  838. {
  839. System.Windows.MessageBox.Show("未找到存放待标注数据的文件:" + _dbPath);
  840. return;
  841. }
  842. SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
  843. dbCon.Open();
  844. SQLiteCommand dbCmd;
  845. dbCmd = dbCon.CreateCommand();
  846. dbCmd.CommandText = "select * from LesionDesGTDatas";
  847. SQLiteDataReader dbReader;
  848. dbReader = dbCmd.ExecuteReader();
  849. if (!dbReader.HasRows)
  850. {
  851. dbReader.Close();
  852. dbCmd.Dispose();
  853. dbCon.Close();
  854. dbCon.Dispose();
  855. System.Windows.MessageBox.Show("待标注的数据为空.");
  856. return;
  857. }
  858. int index = 0;
  859. while (dbReader.Read())
  860. {
  861. string imgId = ((string)dbReader[0]).TrimEnd();
  862. string strLesions = ((string)dbReader[1]).TrimEnd();
  863. List<LesionInfo> lesions = JsonConvert.DeserializeObject<List<LesionInfo>>(strLesions);
  864. string strLesionsLabels = ((string)dbReader[2]).TrimEnd();
  865. List<int> lesionsLabels = JsonConvert.DeserializeObject<List<int>>(strLesionsLabels);
  866. index += 1;
  867. _allImages.Add(new LesionDesGTImgInfo { ImageId = imgId, Lesions = lesions , Label = lesionsLabels });
  868. }
  869. dbReader.Close();
  870. dbCmd.Dispose();
  871. dbCmd = dbCon.CreateCommand();
  872. dbCmd.CommandText = "select * from LastModification";
  873. dbReader = dbCmd.ExecuteReader();
  874. if (!dbReader.HasRows)
  875. {
  876. _imgIndex = 0;
  877. }
  878. else
  879. {
  880. dbReader.Read();
  881. string imgId = ((string)dbReader[0]).TrimEnd();
  882. int imgIndex = _allImages.FindIndex(x => x.ImageId == imgId);
  883. if (imgIndex == -1)
  884. {
  885. _imgIndex = 0;
  886. }
  887. else
  888. {
  889. _imgIndex = imgIndex;
  890. }
  891. }
  892. dbReader.Close();
  893. dbCmd.Dispose();
  894. dbCon.Close();
  895. dbCon.Dispose();
  896. if (_allImages.Count > 0)
  897. {
  898. CurrentImgIndexUpdated();
  899. }
  900. }
  901. catch (Exception excep)
  902. {
  903. System.Windows.MessageBox.Show("读入数据库时出错:" + excep);
  904. }
  905. }
  906. /// <summary>
  907. /// 更新画布上显示的图像
  908. /// </summary>
  909. private void ImageUpdated()
  910. {
  911. if (null == _drawimg)
  912. {
  913. return;
  914. }
  915. if (null == _origimg)
  916. {
  917. return;
  918. }
  919. // 计算缩放比例
  920. double ratioW = GridDrawImg.ActualWidth / _drawimg.Width;
  921. double ratioH = GridDrawImg.ActualHeight / _drawimg.Height;
  922. double ratio = ratioW < ratioH ? ratioW : ratioH;
  923. DrawImgScaleTramsform.CenterX = 0;
  924. DrawImgScaleTramsform.CenterY = 0;
  925. DrawImgScaleTramsform.ScaleX = ratio;
  926. DrawImgScaleTramsform.ScaleY = ratio;
  927. OrigImgScaleTramsform.CenterX = 0;
  928. OrigImgScaleTramsform.CenterY = 0;
  929. OrigImgScaleTramsform.ScaleX = ratio;
  930. OrigImgScaleTramsform.ScaleY = ratio;
  931. // 使图像居中,需要平移
  932. double translateX = 0;
  933. double translateY = 0;
  934. if (Math.Abs(ratio - ratioW) < 0.0001)
  935. {
  936. translateY = 0.5 * (ratioH - ratio) * _drawimg.Height;
  937. }
  938. else
  939. {
  940. translateX = 0.5 * (ratioW - ratio) * _drawimg.Width;
  941. }
  942. // 更新画布尺寸,使其刚好只覆盖图像区域
  943. MyCanvasDraw.Width = ratio * _drawimg.Width;
  944. MyCanvasDraw.Height = ratio * _drawimg.Height;
  945. Canvas.SetLeft(MyCanvasDraw, translateX);
  946. Canvas.SetTop(MyCanvasDraw, translateY);
  947. MyCanvasDraw.ClipToBounds = true;
  948. MyCanvas.Width = ratio * _drawimg.Width;
  949. MyCanvas.Height = ratio * _drawimg.Height;
  950. Canvas.SetLeft(MyCanvas, translateX);
  951. Canvas.SetTop(MyCanvas, translateY);
  952. DrawImage.Source = _drawimg;
  953. OrigImage.Source = _origimg;
  954. if (_dstImgWin == null || CheckModelResult.IsChecked.Value == false)
  955. {
  956. OrigImage.Source = _origimg;
  957. }
  958. else
  959. {
  960. OrigImage.Source = _dstImgWin;
  961. }
  962. //if(_dstImgWin != null)
  963. //{
  964. // DrawImage.Source = _dstImgWin;
  965. //}
  966. }
  967. /// <summary>
  968. /// 更新显示已有的轮廓
  969. /// </summary>
  970. private void UpdateLesionsInCanvas()
  971. {
  972. if (_drawimg == null)
  973. {
  974. return;
  975. }
  976. RemoveContourInCanvas("drawing");
  977. RemoveLineInCanvas(EnumCanvasLineType.Horizontal, "drawing");
  978. RemoveLineInCanvas(EnumCanvasLineType.Vertical, "drawing");
  979. // 显示新的病灶
  980. if (_showDrawingResult)
  981. {
  982. for (int ni = 0; ni < _lesions.Count; ni++)
  983. {
  984. // 显示病灶轮廓, 注意,所有点需转到Canvas坐标系下
  985. List<Point2D> contour = _lesions[ni].Contour;
  986. if (contour.Count > 0)
  987. {
  988. List<System.Windows.Point> contourInCanvas = new List<System.Windows.Point>();
  989. for (int nj = 0; nj < contour.Count; nj++)
  990. {
  991. contourInCanvas.Add(GetPosInCanvas(contour[nj]));
  992. }
  993. if (ni == _lesionIndex)
  994. {
  995. DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Choosed, ni.ToString());
  996. }
  997. else
  998. {
  999. DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Existed, ni.ToString());
  1000. }
  1001. }
  1002. // 显示病灶横轴,注意,所有点需转到Canvas坐标系下
  1003. Point2D hP1 = _lesions[ni].HorizontalPoint1;
  1004. Point2D hP2 = _lesions[ni].HorizontalPoint2;
  1005. if (hP1 != null && hP2 != null)
  1006. {
  1007. System.Windows.Point hP1InCanvas = GetPosInCanvas(hP1);
  1008. System.Windows.Point hP2InCanvas = GetPosInCanvas(hP2);
  1009. if (ni == _lesionIndex)
  1010. {
  1011. DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Choosed, ni.ToString());
  1012. }
  1013. else
  1014. {
  1015. DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Existed, ni.ToString());
  1016. }
  1017. }
  1018. // 显示病灶纵轴,注意所有点需转到Canvas坐标系下
  1019. Point2D vP1 = _lesions[ni].VerticalPoint1;
  1020. Point2D vP2 = _lesions[ni].VerticalPoint2;
  1021. if (vP1 != null && vP2 != null)
  1022. {
  1023. System.Windows.Point vP1InCanvas = GetPosInCanvas(vP1);
  1024. System.Windows.Point vP2InCanvas = GetPosInCanvas(vP2);
  1025. if (ni == _lesionIndex)
  1026. {
  1027. DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Choosed, ni.ToString());
  1028. }
  1029. else
  1030. {
  1031. DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Existed, ni.ToString());
  1032. }
  1033. }
  1034. }
  1035. }
  1036. }
  1037. /// <summary>
  1038. /// 更新显示已有的病灶分级
  1039. /// </summary>
  1040. private void UpdateLesionsIndex()
  1041. {
  1042. ComboBoxLesionsLabel.SelectedIndex = -1;
  1043. for (int ni = 0; ni < _lesionsLabels.Count; ni++)
  1044. {
  1045. if (ni == _lesionIndex)
  1046. {
  1047. ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[ni];
  1048. }
  1049. else
  1050. {
  1051. //ComboBoxLesionsLabel.SelectedIndex = -1;
  1052. }
  1053. }
  1054. //ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex];
  1055. }
  1056. /// <summary>
  1057. /// 绘制轮廓
  1058. /// </summary>
  1059. /// <param name="contour"></param>
  1060. /// <param name="type"></param>
  1061. /// <param name="name"></param>
  1062. private void DrawContourInCanvas(List<System.Windows.Point> contour, EnumCanvasItemType type, string name)
  1063. {
  1064. if (_drawimg == null)
  1065. {
  1066. return;
  1067. }
  1068. RemoveContourInCanvas(name);
  1069. Polyline contourLines = new Polyline
  1070. {
  1071. StrokeThickness = 1,
  1072. Stroke = GetContourBrushColor(type),
  1073. Points = new System.Windows.Media.PointCollection(contour)
  1074. };
  1075. MyCanvasDraw.Children.Add(contourLines);
  1076. MyCanvasDraw.RegisterName("Contour_" + name, contourLines);
  1077. }
  1078. /// <summary>
  1079. /// 清除已绘制的轮廓
  1080. /// </summary>
  1081. /// <param name="name"></param>
  1082. private void RemoveContourInCanvas(string name)
  1083. {
  1084. string contourName = "Contour_" + name;
  1085. if (MyCanvasDraw.FindName(contourName) is Polyline contourExists)
  1086. {
  1087. MyCanvasDraw.Children.Remove(contourExists);
  1088. MyCanvasDraw.UnregisterName(contourName);
  1089. }
  1090. }
  1091. /// <summary>
  1092. /// 画线
  1093. /// </summary>
  1094. /// <param name="startPos"></param>
  1095. /// <param name="endPos"></param>
  1096. /// <param name="lineType"></param>
  1097. /// <param name="type"></param>
  1098. /// <param name="name"></param>
  1099. private void DrawLineInCanvas(System.Windows.Point startPos, System.Windows.Point endPos, EnumCanvasLineType lineType,
  1100. EnumCanvasItemType type, string name)
  1101. {
  1102. if (_drawimg == null)
  1103. {
  1104. return;
  1105. }
  1106. RemoveLineInCanvas(lineType, name);
  1107. System.Windows.Shapes.Line line = new System.Windows.Shapes.Line
  1108. {
  1109. X1 = startPos.X,
  1110. Y1 = startPos.Y,
  1111. X2 = endPos.X,
  1112. Y2 = endPos.Y,
  1113. StrokeThickness = 1,
  1114. Stroke = GetLineBrushColor(type, lineType)
  1115. };
  1116. MyCanvasDraw.Children.Add(line);
  1117. string lineName;
  1118. if (lineType == EnumCanvasLineType.Horizontal)
  1119. {
  1120. lineName = "Line_H_" + name;
  1121. }
  1122. else
  1123. {
  1124. lineName = "Line_V_" + name;
  1125. }
  1126. MyCanvasDraw.RegisterName(lineName, line);
  1127. }
  1128. /// <summary>
  1129. /// 移除已画的线
  1130. /// </summary>
  1131. /// <param name="lineType"></param>
  1132. /// <param name="name"></param>
  1133. private void RemoveLineInCanvas(EnumCanvasLineType lineType, string name)
  1134. {
  1135. string lineName;
  1136. if (lineType == EnumCanvasLineType.Horizontal)
  1137. {
  1138. lineName = "Line_H_" + name;
  1139. }
  1140. else
  1141. {
  1142. lineName = "Line_V_" + name;
  1143. }
  1144. if (MyCanvasDraw.FindName(lineName) is System.Windows.Shapes.Line lineExists)
  1145. {
  1146. MyCanvasDraw.Children.Remove(lineExists);
  1147. MyCanvasDraw.UnregisterName(lineName);
  1148. }
  1149. }
  1150. /// <summary>
  1151. /// 设置横轴纵轴线的颜色
  1152. /// </summary>
  1153. /// <param name="itemType"></param>
  1154. /// <param name="lineType"></param>
  1155. /// <returns></returns>
  1156. private System.Windows.Media.Brush GetLineBrushColor(EnumCanvasItemType itemType, EnumCanvasLineType lineType)
  1157. {
  1158. switch (itemType)
  1159. {
  1160. case EnumCanvasItemType.Drawing:
  1161. if (lineType == EnumCanvasLineType.Horizontal)
  1162. {
  1163. return System.Windows.Media.Brushes.DarkGreen;
  1164. }
  1165. else
  1166. {
  1167. return System.Windows.Media.Brushes.DarkBlue;
  1168. }
  1169. case EnumCanvasItemType.Existed:
  1170. if (lineType == EnumCanvasLineType.Horizontal)
  1171. {
  1172. return System.Windows.Media.Brushes.LightGreen;
  1173. }
  1174. else
  1175. {
  1176. return System.Windows.Media.Brushes.LightBlue;
  1177. }
  1178. default:
  1179. if (lineType == EnumCanvasLineType.Horizontal)
  1180. {
  1181. return System.Windows.Media.Brushes.Green;
  1182. }
  1183. else
  1184. {
  1185. return System.Windows.Media.Brushes.Blue;
  1186. }
  1187. }
  1188. }
  1189. /// <summary>
  1190. /// 设置轮廓线的颜色
  1191. /// </summary>
  1192. /// <param name="itemType"></param>
  1193. /// <returns></returns>
  1194. private System.Windows.Media.Brush GetContourBrushColor(EnumCanvasItemType itemType)
  1195. {
  1196. switch (itemType)
  1197. {
  1198. case EnumCanvasItemType.Drawing:
  1199. return System.Windows.Media.Brushes.OrangeRed;
  1200. case EnumCanvasItemType.Existed:
  1201. return System.Windows.Media.Brushes.LightYellow;
  1202. default:
  1203. return System.Windows.Media.Brushes.Orange;
  1204. }
  1205. }
  1206. /// <summary>
  1207. /// 更新该图上的病灶
  1208. /// </summary>
  1209. private void LesionsUpdated()
  1210. {
  1211. ComboBoxLesions.SelectionChanged -= OnLesionSelectionChanged;
  1212. ComboBoxLesions.Items.Clear();
  1213. for (int ni = 0; ni < _lesions.Count; ni++)
  1214. {
  1215. ComboBoxLesions.Items.Add("病灶 " + ni.ToString());
  1216. }
  1217. if (ComboBoxLesions.SelectedIndex != _lesionIndex)
  1218. {
  1219. ComboBoxLesions.SelectedIndex = _lesionIndex;
  1220. }
  1221. if (_lesionIndex < 0)
  1222. {
  1223. UserControlLesionSelected.SetLesionEmpty();
  1224. }
  1225. else
  1226. {
  1227. UserControlLesionSelected.SetLesion(_lesions[_lesionIndex]);
  1228. }
  1229. ComboBoxLesions.SelectionChanged += OnLesionSelectionChanged;
  1230. UpdateLesionsInCanvas();
  1231. UpdateLesionsIndex();
  1232. }
  1233. /// <summary>
  1234. /// 要加载的图像序号发生了改变
  1235. /// </summary>
  1236. private void CurrentImgIndexUpdated()
  1237. {
  1238. if (_imgIndex < 0 || _imgIndex >= _allImages.Count /*- 1*/)
  1239. {
  1240. throw new ArgumentOutOfRangeException("待更新的图像序号超出范围.");
  1241. }
  1242. TextBlockCurrentIndex.Text = _imgIndex.ToString();
  1243. LesionDesGTImgInfo imgInfo = _allImages[_imgIndex];
  1244. string imgPath = System.IO.Path.Combine(_imageDataFolder, imgInfo.ImageId + ".jpg");
  1245. //string imgPath = imgInfo.ImageId;
  1246. if (!File.Exists(imgPath))
  1247. {
  1248. throw new FileNotFoundException("找不到文件:" + imgPath);
  1249. }
  1250. _image = new Bitmap(imgPath);
  1251. _drawimg = RawImageShowUtils.BitmapToBitmapImage(_image);
  1252. _origimg = RawImageShowUtils.BitmapToBitmapImage(_image);
  1253. //image.Dispose();
  1254. ImageUpdated();
  1255. // 先清除所有已有显示
  1256. for (int ni = 0; ni < _lesions.Count; ni++)
  1257. {
  1258. RemoveContourInCanvas(ni.ToString());
  1259. RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
  1260. RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
  1261. }
  1262. int num = _drawingPoints.Count;
  1263. if (num > 0)
  1264. {
  1265. // 更新显示正在绘制的轮廓线
  1266. RemoveContourInCanvasForDrawPts("drawingPt");
  1267. }
  1268. // 再更新
  1269. _lesions = imgInfo.Lesions;
  1270. _lesionsLabels = imgInfo.Label;
  1271. _modified = false;
  1272. if (_lesions.Count <= 0)
  1273. {
  1274. _lesionIndex = -1;
  1275. ComboBoxLesionsLabel.SelectedIndex = -1;
  1276. }
  1277. else
  1278. {
  1279. _lesionIndex = 0;
  1280. ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex];
  1281. }
  1282. LesionsUpdated();
  1283. }
  1284. /// <summary>
  1285. /// 收到LesionInfoSelector发来的事件
  1286. /// </summary>
  1287. /// <param name="sender"></param>
  1288. /// <param name="e"></param>
  1289. private void OnLesionInfoSelectorEventOccur(object sender, LesionInfoEventArgs e)
  1290. {
  1291. switch (e.EventType)
  1292. {
  1293. case EnumLesionInfoEventType.LesionInfoUpdated:
  1294. _modified = true;
  1295. if (_lesions.Count <= 0 && _lesionIndex < 0)
  1296. {
  1297. _lesions.Add(UserControlLesionSelected.Lesion);
  1298. _lesionIndex = 0;
  1299. _lesionsLabels.Add(-1);
  1300. }
  1301. else
  1302. {
  1303. _lesions[_lesionIndex] = UserControlLesionSelected.Lesion;
  1304. //_lesionsLabels.Add(-1);
  1305. }
  1306. LesionsUpdated();
  1307. break;
  1308. case EnumLesionInfoEventType.DrawContour:
  1309. _mouseOper = EnumMouseOperType.DrawingContour;
  1310. break;
  1311. case EnumLesionInfoEventType.DrawHorizontal:
  1312. _mouseOper = EnumMouseOperType.DrawingHorizonLines;
  1313. break;
  1314. case EnumLesionInfoEventType.DrawVertical:
  1315. _mouseOper = EnumMouseOperType.DrawingVerticalLines;
  1316. break;
  1317. case EnumLesionInfoEventType.DrawPoint:
  1318. _mouseOper = EnumMouseOperType.DrawingPoint;
  1319. break;
  1320. }
  1321. }
  1322. /// <summary>
  1323. /// 将Canvas上的点转换到图像坐标系下
  1324. /// </summary>
  1325. /// <param name="mousePosInCanvas"></param>
  1326. /// <returns></returns>
  1327. private Point2D GetPosInOrigImage(System.Windows.Point posInCanvas)
  1328. {
  1329. if (_drawimg != null)
  1330. {
  1331. int x = Convert.ToInt32(posInCanvas.X / MyCanvasDraw.Width * _drawimg.Width);
  1332. int y = Convert.ToInt32(posInCanvas.Y / MyCanvasDraw.Height * _drawimg.Height);
  1333. return new Point2D(x, y);
  1334. }
  1335. else
  1336. {
  1337. return new Point2D(0, 0);
  1338. }
  1339. }
  1340. /// <summary>
  1341. /// 将图像上的点转换到Canvas坐标系下
  1342. /// </summary>
  1343. /// <param name="posInOrigImg"></param>
  1344. /// <returns></returns>
  1345. private System.Windows.Point GetPosInCanvas(Point2D posInOrigImg)
  1346. {
  1347. if (_drawimg != null)
  1348. {
  1349. int x = Convert.ToInt32(posInOrigImg.X / _drawimg.Width * MyCanvasDraw.Width);
  1350. int y = Convert.ToInt32(posInOrigImg.Y / _drawimg.Height * MyCanvasDraw.Height);
  1351. return new System.Windows.Point(x, y);
  1352. }
  1353. else
  1354. {
  1355. return new System.Windows.Point(0, 0);
  1356. }
  1357. }
  1358. /// <summary>
  1359. /// 计算两点之间的距离
  1360. /// </summary>
  1361. /// <param name="point1"></param>
  1362. /// <param name="point2"></param>
  1363. /// <returns></returns>
  1364. private double PointDistance(System.Windows.Point point1, System.Windows.Point point2)
  1365. {
  1366. return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2));
  1367. }
  1368. #endregion
  1369. #region 创建标准描述数据库相关的函数
  1370. /// <summary>
  1371. /// 创建数据库
  1372. /// </summary>
  1373. private bool CreateDataBase()
  1374. {
  1375. if (File.Exists(_dbPath))
  1376. {
  1377. //throw new Exception("数据库已存在,请检查.");
  1378. return false ;
  1379. }
  1380. // 创建数据库文件
  1381. SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
  1382. dbCon.Open();
  1383. SQLiteCommand dbCmd;
  1384. dbCmd = dbCon.CreateCommand();
  1385. dbCmd.CommandText = "create table if not exists LesionDesGTDatas(ImageId varchar(16),Lesions varchar(16),Label varchar(16))";
  1386. dbCmd.ExecuteNonQuery();
  1387. dbCmd.Dispose();
  1388. dbCmd = dbCon.CreateCommand();
  1389. dbCmd.CommandText = "create table if not exists LastModification(ImageId varchar(16))";
  1390. dbCmd.ExecuteNonQuery();
  1391. dbCmd.Dispose();
  1392. dbCon.Close();
  1393. dbCon.Dispose();
  1394. return true;
  1395. }
  1396. /// <summary>
  1397. /// 添加新的图像到数据集里
  1398. /// </summary>
  1399. /// <param name="origImageFolder"></param>
  1400. private void AddNewImages(string origImageFolder)
  1401. {
  1402. // 如果文件夹不存在,则创建
  1403. if (!Directory.Exists(_imageDataFolder))
  1404. {
  1405. Directory.CreateDirectory(_imageDataFolder);
  1406. }
  1407. // 已有多少图片
  1408. SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
  1409. dbCon.Open();
  1410. SQLiteCommand dbCmd;
  1411. SQLiteDataReader dbReader;
  1412. // 遍历该文件夹下所有图片
  1413. DirectoryInfo origImgDir = new DirectoryInfo(origImageFolder);
  1414. FileInfo[] files = origImgDir.GetFiles();
  1415. foreach (var file in files)
  1416. {
  1417. Bitmap image = new Bitmap(file.FullName);
  1418. RawImage rawImg = RawImageShowUtils.BitmapToRawImage(image);
  1419. //string hashCode = ComputeHashCode(rawImg.DataBuffer);
  1420. string temp;
  1421. int idx = file.FullName.LastIndexOf("\\");
  1422. temp = file.FullName.Substring(idx);
  1423. string[] strs1 = temp.Split('\\');
  1424. temp = strs1[1];
  1425. string[] strs2 = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
  1426. string ImgId = strs2[0];
  1427. string hashCode = ImgId;
  1428. image.Dispose();
  1429. rawImg.Dispose();
  1430. // 查找该图片是否已经存在
  1431. dbCmd = dbCon.CreateCommand();
  1432. dbCmd.CommandText = "select * from LesionDesGTDatas where ImageId='" + hashCode + "'";
  1433. dbReader = dbCmd.ExecuteReader();
  1434. if (dbReader.HasRows)
  1435. {
  1436. dbReader.Close();
  1437. dbCmd.Dispose();
  1438. continue;
  1439. }
  1440. // 以哈希值作为该图片的id,同时也作为图像名,复制原始图像到指定目录下
  1441. //string imgdstPath = System.IO.Path.Combine(_imageDataFolder, hashCode + ".jpg");
  1442. //File.Copy(file.FullName, imgdstPath);
  1443. // 将该图相关信息存到数据库里
  1444. List<LesionInfo> lesions = new List<LesionInfo>();
  1445. string strLesions = JsonConvert.SerializeObject(lesions);
  1446. List<int> LesionsLabel = new List<int>();
  1447. string strLesionsLabel = JsonConvert.SerializeObject(LesionsLabel);
  1448. dbCmd = dbCon.CreateCommand();
  1449. dbCmd.CommandText = "insert into LesionDesGTDatas(ImageId,Lesions,Label) select '" + hashCode + "','" + strLesions + "','" + strLesionsLabel + "'";
  1450. dbCmd.ExecuteNonQuery();
  1451. dbCmd.Dispose();
  1452. }
  1453. dbCon.Close();
  1454. dbCon.Dispose();
  1455. }
  1456. #endregion
  1457. private void OnBtnModelImageClicked(object sender, RoutedEventArgs e)
  1458. {
  1459. if(_image != null)
  1460. {
  1461. DetectImage(_image);
  1462. }
  1463. }
  1464. /// <summary>
  1465. /// 使用模型检测,并显示在标注结果界面上
  1466. /// </summary>
  1467. /// <param name="image"></param>
  1468. private void DetectImage(Bitmap image)
  1469. {
  1470. string name = _allImages[_imgIndex].ImageId;
  1471. RawImage rawImg = null;
  1472. //rawImg = RawImageShowUtils.BitmapToRawImage(image);
  1473. var rawImage = RawImageShowUtils.BitmapToRawImage(image);
  1474. _caseId = Guid.NewGuid().ToString();
  1475. _dataId = name;
  1476. _readingVideo = false;
  1477. var extendData = new Dictionary<string, object>();
  1478. extendData.Add("CaseId", _caseId);
  1479. extendData.Add("DataId", _dataId);
  1480. extendData.Add("IsVideo", _readingVideo);
  1481. extendData.Add("TimeStamp", (double)_frameIndex);
  1482. _processId = _module.StartProcess();
  1483. var input = new ImageInputData(rawImage, extendData);
  1484. IDetectedObject[] result = _module.PushOnePieceOfData(_processId, input);
  1485. _newModelResult = result;
  1486. _module.EndProcess(_processId);
  1487. //var diagResult = _diagSystem.EvaluateOneImage(rawImg);
  1488. if(result != null)
  1489. {
  1490. var dstimage = ShowDiagResultsOnImage(image, result);//
  1491. ModelResultShow();
  1492. _dstImgWin = RawImageShowUtils.BitmapToBitmapImage(dstimage);
  1493. Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
  1494. {
  1495. if (_dstImgWin == null || CheckModelResult.IsChecked.Value == false)
  1496. {
  1497. OrigImage.Source = _origimg;
  1498. }
  1499. else
  1500. {
  1501. OrigImage.Source = _dstImgWin;
  1502. }
  1503. }
  1504. ));
  1505. dstimage.Dispose();
  1506. }
  1507. else
  1508. {
  1509. System.Windows.MessageBox.Show("模型检测失败");
  1510. }
  1511. }
  1512. private Bitmap ShowDiagResultsOnImage(Bitmap image, IDetectedObject[] diagResult)
  1513. {
  1514. int breastLesionNum = 0;
  1515. Bitmap dstimage = image.Clone(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
  1516. //var organGt = diagResult.DiagResultsForEachOrgan;
  1517. foreach (var resultsPerOrgan in diagResult)
  1518. {
  1519. var Ilabel = resultsPerOrgan.Label;
  1520. var nameOrgan = Ilabel.GroupName;
  1521. int indexLabel = Ilabel.Index;
  1522. if (nameOrgan != "AI.Vaid.Breast.Lesion")
  1523. {
  1524. continue;
  1525. }
  1526. //if (resultsPerOrgan.Organ == EnumOrgans.Breast)
  1527. {
  1528. using (var g = Graphics.FromImage(dstimage))
  1529. {
  1530. int num = 0;
  1531. string strDescriptionShape = string.Empty;
  1532. string strDescriptionOrientation = string.Empty;
  1533. string strDescriptionEcho = string.Empty;
  1534. string strDescriptionBound = string.Empty;
  1535. string strDescriptionMargin = string.Empty;
  1536. System.Drawing.Brush brush = System.Drawing.Brushes.Green;
  1537. List<LesionInfo> CurImageLesion = new List<LesionInfo>();
  1538. if (_modelResult != null)
  1539. {
  1540. _modelResult = null;
  1541. _modelResult = new LesionDesGTImgInfo();
  1542. _modelResult.Lesions = new List<LesionInfo>();
  1543. _modelResult.Label = new List<int>();
  1544. }
  1545. var resultConversion = AIModuleResultShowUtils.GetObjectStr(resultsPerOrgan);
  1546. if (resultsPerOrgan.Contour?.Contours.Length > 0)
  1547. {
  1548. //ShowContour(moduleResult.Contour, brush, null, transform);
  1549. int count = resultsPerOrgan.Contour.Contours.Length;
  1550. LesionInfo lesion = new LesionInfo();
  1551. for (int i = 0; i < count; i++)
  1552. {
  1553. var contourPoints = resultsPerOrgan.Contour.Contours[i];
  1554. int pointCount = contourPoints.Points.Length;
  1555. //var points = new List<System.Windows.Point>();
  1556. System.Drawing.PointF[] lesionContour = new PointF[pointCount];
  1557. List<Point2D> points = new List<Point2D>();
  1558. for (int j = 0; j < pointCount; j++)
  1559. {
  1560. var point = new System.Windows.Point(contourPoints.Points[j].X, contourPoints.Points[j].Y);
  1561. lesionContour[j].X = contourPoints.Points[j].X;
  1562. lesionContour[j].Y = contourPoints.Points[j].Y;
  1563. Point2D pt = new Point2D(contourPoints.Points[j].X, contourPoints.Points[j].Y);
  1564. points.Add(pt);
  1565. lesion.Contour.Add(pt);
  1566. }
  1567. g.DrawPolygon(new System.Drawing.Pen(brush, 2), lesionContour);
  1568. var desResult = resultsPerOrgan.Description;
  1569. var type = desResult.GetType();
  1570. string strDescription = string.Empty;
  1571. //if (type == typeof(BreastLesionDescription))
  1572. {
  1573. foreach (var key in desResult.Descriptions.Keys)
  1574. {
  1575. if (key == "Shape")
  1576. {
  1577. EnumDesShapeValue sss = new EnumDesShapeValue();
  1578. string des = string.Empty;
  1579. switch (desResult.Descriptions[key])
  1580. {
  1581. case "Oval":
  1582. des = "椭圆形";
  1583. sss = EnumDesShapeValue.Oval;
  1584. break;
  1585. case "Round":
  1586. des = "类圆形";
  1587. sss = EnumDesShapeValue.Round;
  1588. break;
  1589. case "Irregular":
  1590. des = "不规则形";
  1591. sss = EnumDesShapeValue.Irregular;
  1592. break;
  1593. }
  1594. lesion.Shape = sss;
  1595. strDescription += "形状:" + des + Environment.NewLine;
  1596. }
  1597. if (key == "Orientation")
  1598. {
  1599. EnumDesOrientationValue sss = new EnumDesOrientationValue();
  1600. string des = string.Empty;
  1601. switch (desResult.Descriptions[key])
  1602. {
  1603. case "Parallel":
  1604. des = "平行";
  1605. sss = EnumDesOrientationValue.Parallel;
  1606. break;
  1607. case "NonParallel":
  1608. des = "非平行";
  1609. sss = EnumDesOrientationValue.NonParallel;
  1610. break;
  1611. }
  1612. lesion.Orientation = sss;
  1613. strDescription += "生长方向:" + des + Environment.NewLine;
  1614. }
  1615. if (key == "EchoPattern")
  1616. {
  1617. EnumDesEchoPatternValue sss = new EnumDesEchoPatternValue();
  1618. string des = string.Empty;
  1619. switch (desResult.Descriptions[key])
  1620. {
  1621. case "Anechoic":
  1622. des = "无回声";
  1623. sss = EnumDesEchoPatternValue.Anechoic;
  1624. break;
  1625. case "Hypoechoic":
  1626. des = "低回声";
  1627. sss = EnumDesEchoPatternValue.Hypoechoic;
  1628. break;
  1629. case "Isoechoic":
  1630. des = "等回声";
  1631. sss = EnumDesEchoPatternValue.Isoechoic;
  1632. break;
  1633. case "Hyperechoic":
  1634. des = "高回声";
  1635. sss = EnumDesEchoPatternValue.Hyperechoic;
  1636. break;
  1637. case "Complex":
  1638. des = "混合回声";
  1639. sss = EnumDesEchoPatternValue.Complex;
  1640. break;
  1641. }
  1642. lesion.EchoPattern = sss;
  1643. strDescription += "回声类型:" + des + Environment.NewLine;
  1644. }
  1645. if (key == "Boundary")
  1646. {
  1647. EnumDesLesionBoundaryValue sss = new EnumDesLesionBoundaryValue();
  1648. string des = string.Empty;
  1649. switch (desResult.Descriptions[key])
  1650. {
  1651. case "AbruptInterface":
  1652. des = "清晰";
  1653. sss = EnumDesLesionBoundaryValue.AbruptInterface;
  1654. break;
  1655. case "EchogenicHalo":
  1656. des = "模糊";
  1657. sss = EnumDesLesionBoundaryValue.EchogenicHalo;
  1658. break;
  1659. }
  1660. lesion.Boundary = sss;
  1661. strDescription += "边界:" + des + Environment.NewLine;
  1662. }
  1663. if (key == "Margin")
  1664. {
  1665. EnumDesMarginValue sss = new EnumDesMarginValue();
  1666. string des = string.Empty;
  1667. switch (desResult.Descriptions[key])
  1668. {
  1669. case "Circumscribed":
  1670. des = "光整";
  1671. sss = EnumDesMarginValue.Circumscribed;
  1672. break;
  1673. case "NonCircumscribed":
  1674. des = "不光整";
  1675. sss = EnumDesMarginValue.NonCircumscribed;
  1676. break;
  1677. }
  1678. lesion.Margin = sss;
  1679. strDescription += "边缘:" + des + Environment.NewLine;
  1680. }
  1681. }
  1682. }
  1683. var rect = resultsPerOrgan.BoundingBox.Contour.BoundingBox();
  1684. var roiBox = resultsPerOrgan.BoundingBox;
  1685. var ss = roiBox.Contour.Points;
  1686. var lesionSize = Array.Find(resultsPerOrgan.Measurements, x => x.GetType() == typeof(TransverseLongitudinalDiameterMeasurement));
  1687. var size = (TransverseLongitudinalDiameterMeasurement)lesionSize;
  1688. var pointLineH1 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineStart.X, size.TransverseDiameterMarkPosition.LineStart.Y);
  1689. var pointLineH2 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineEnd.X, size.TransverseDiameterMarkPosition.LineEnd.Y);
  1690. var pointLineV1 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineStart.X, size.LongitudinalDiameterMarkPosition.LineStart.Y);
  1691. var pointLineV2 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineEnd.X, size.LongitudinalDiameterMarkPosition.LineEnd.Y);
  1692. System.Drawing.Point[] axisH = new System.Drawing.Point[2];
  1693. System.Drawing.Point[] axisV = new System.Drawing.Point[2];
  1694. axisH[0].X = (int)pointLineH1.X;
  1695. axisH[0].Y = (int)pointLineH1.Y;
  1696. axisH[1].X = (int)pointLineH2.X;
  1697. axisH[1].Y = (int)pointLineH2.Y;
  1698. axisV[0].X = (int)pointLineV1.X;
  1699. axisV[0].Y = (int)pointLineV1.Y;
  1700. axisV[1].X = (int)pointLineV2.X;
  1701. axisV[1].Y = (int)pointLineV2.Y;
  1702. System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2);
  1703. g.DrawLines(pen_h, axisH); //横轴,浅绿色
  1704. System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1);
  1705. g.DrawLines(pen_v, axisV); //纵轴,红色
  1706. var Measurements = resultsPerOrgan.Measurements;
  1707. var len = Measurements.Length;
  1708. if(len > 0)
  1709. {
  1710. var marks = Measurements[0].MeasureMarks;
  1711. int lenM = marks.Length;
  1712. var con = marks[0].Contour.Points;
  1713. int numC = con.Length;
  1714. }
  1715. }
  1716. _modelResult.Lesions.Add(lesion);
  1717. _modelResult.Label.Add(indexLabel);
  1718. num++;
  1719. }
  1720. g.Dispose();
  1721. }
  1722. }
  1723. }
  1724. if (breastLesionNum == 0)
  1725. {
  1726. //MessageBox.Show("未检测出病灶");
  1727. }
  1728. else
  1729. {
  1730. _lesionOriModelIndex = 0;
  1731. ModelComboBoxOriUpdated();
  1732. }
  1733. return dstimage;
  1734. }
  1735. /// <summary>
  1736. /// 复制模型结果
  1737. /// </summary>
  1738. /// <param name="sender"></param>
  1739. /// <param name="e"></param>
  1740. private void OnBtnCopyModelResultClicked(object sender, RoutedEventArgs e)
  1741. {
  1742. // 保存当前图的结果
  1743. //_modified = true;
  1744. //if (_modified)
  1745. {
  1746. if(_allImages[_imgIndex].Lesions.Count > 0)
  1747. {
  1748. System.Windows.MessageBox.Show("已存在病灶信息,请先删除右图标注数据");
  1749. return;
  1750. }
  1751. if(_modelResult.Lesions.Count > 0)
  1752. {
  1753. if (_modelResult.Lesions[0].Contour.Count >0)
  1754. {
  1755. _lesions = _modelResult.Lesions;
  1756. _lesionsLabels = _modelResult.Label;// _lesionsModelLabels;
  1757. _allImages[_imgIndex].Lesions = _lesions;
  1758. _allImages[_imgIndex].Label = _lesionsLabels;
  1759. CopyModelToCurrentImgUpdated();
  1760. _lesionIndex = ComboBoxLesions.SelectedIndex;
  1761. //_lesionsLabels = _lesionsModelLabels; //分级
  1762. ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex] ;
  1763. _modified = true;
  1764. }
  1765. }
  1766. else
  1767. {
  1768. if (_image != null)
  1769. {
  1770. DetectImage(_image);
  1771. }
  1772. if (_modelResult.Lesions[0].Contour.Count > 0)
  1773. {
  1774. _lesions = _modelResult.Lesions;
  1775. _lesionsLabels = _modelResult.Label;// _lesionsModelLabels;
  1776. _allImages[_imgIndex].Lesions = _lesions;
  1777. _allImages[_imgIndex].Label = _lesionsLabels;
  1778. CopyModelToCurrentImgUpdated();
  1779. _lesionIndex = ComboBoxLesions.SelectedIndex;
  1780. //_lesionsLabels = _lesionsModelLabels; //分级
  1781. ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex];
  1782. _modified = true;
  1783. }
  1784. return;
  1785. }
  1786. }
  1787. }
  1788. /// <summary>
  1789. /// 复制模型结果显示到右边界面
  1790. /// </summary>
  1791. private void CopyModelToCurrentImgUpdated()
  1792. {
  1793. if (_imgIndex < 0 || _imgIndex >= _allImages.Count/* - 1*/)
  1794. {
  1795. throw new ArgumentOutOfRangeException("待更新的图像序号超出范围.");
  1796. }
  1797. TextBlockCurrentIndex.Text = _imgIndex.ToString();
  1798. LesionDesGTImgInfo imgInfo = _allImages[_imgIndex];
  1799. string imgPath = System.IO.Path.Combine(_imageDataFolder, imgInfo.ImageId + ".jpg");
  1800. //string imgPath = imgInfo.ImageId;
  1801. if (!File.Exists(imgPath))
  1802. {
  1803. throw new FileNotFoundException("找不到文件:" + imgPath);
  1804. }
  1805. _image = new Bitmap(imgPath);
  1806. _drawimg = RawImageShowUtils.BitmapToBitmapImage(_image);
  1807. _origimg = RawImageShowUtils.BitmapToBitmapImage(_image);
  1808. //image.Dispose();
  1809. ImageUpdated();
  1810. // 先清除所有已有显示
  1811. for (int ni = 0; ni < _lesions.Count; ni++)
  1812. {
  1813. RemoveContourInCanvas(ni.ToString());
  1814. RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
  1815. RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
  1816. }
  1817. // 再更新
  1818. if (_lesions.Count <= 0)
  1819. {
  1820. _lesionIndex = -1;
  1821. }
  1822. else
  1823. {
  1824. _lesionIndex = 0;
  1825. }
  1826. ModelLesionsUpdated();
  1827. }
  1828. /// <summary>
  1829. /// 将模型结果更新到图上的病灶
  1830. /// </summary>
  1831. private void ModelLesionsUpdated()
  1832. {
  1833. ComboBoxLesions.SelectionChanged -= OnLesionSelectionChanged;
  1834. ComboBoxLesions.Items.Clear();
  1835. for (int ni = 0; ni < _modelResult.Lesions.Count; ni++)
  1836. {
  1837. ComboBoxLesions.Items.Add("病灶 " + ni.ToString());
  1838. }
  1839. if (ComboBoxLesions.SelectedIndex != _lesionIndex)
  1840. {
  1841. ComboBoxLesions.SelectedIndex = _lesionIndex;
  1842. }
  1843. _lesionIndex = 0;//强制为0
  1844. if (_lesionIndex < 0)
  1845. {
  1846. UserControlLesionSelected.SetLesionEmpty();
  1847. }
  1848. else
  1849. {
  1850. //病灶数据此时由模型给出,将病灶信息赋给LesionInfoSelector::UserControlLesionSelected
  1851. UserControlLesionSelected.SetLesion(_modelResult.Lesions[_lesionIndex]);
  1852. }
  1853. ComboBoxLesions.SelectionChanged += OnLesionSelectionChanged;
  1854. UpdateModelLesionsInCanvas();
  1855. //_lesionIndex = -1;
  1856. }
  1857. /// <summary>
  1858. /// 更新显示已有的轮廓
  1859. /// </summary>
  1860. private void UpdateModelLesionsInCanvas()
  1861. {
  1862. if (_drawimg == null)
  1863. {
  1864. return;
  1865. }
  1866. RemoveContourInCanvas("drawing");
  1867. RemoveLineInCanvas(EnumCanvasLineType.Horizontal, "drawing");
  1868. RemoveLineInCanvas(EnumCanvasLineType.Vertical, "drawing");
  1869. // 显示新的病灶
  1870. if(_showDrawingResult)
  1871. {
  1872. for (int ni = 0; ni < _modelResult.Lesions.Count; ni++)
  1873. {
  1874. // 显示病灶轮廓, 注意,所有点需转到Canvas坐标系下
  1875. List<Point2D> contour = _modelResult.Lesions[ni].Contour;
  1876. if (contour.Count > 0)
  1877. {
  1878. List<System.Windows.Point> contourInCanvas = new List<System.Windows.Point>();
  1879. for (int nj = 0; nj < contour.Count; nj++)
  1880. {
  1881. contourInCanvas.Add(GetPosInCanvas(contour[nj]));
  1882. }
  1883. if (ni == _lesionIndex)
  1884. {
  1885. DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Choosed, ni.ToString());
  1886. }
  1887. else
  1888. {
  1889. DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Existed, ni.ToString());
  1890. }
  1891. }
  1892. // 显示病灶横轴,注意,所有点需转到Canvas坐标系下
  1893. Point2D hP1 = _modelResult.Lesions[ni].HorizontalPoint1;
  1894. Point2D hP2 = _modelResult.Lesions[ni].HorizontalPoint2;
  1895. if (hP1 != null && hP2 != null)
  1896. {
  1897. System.Windows.Point hP1InCanvas = GetPosInCanvas(hP1);
  1898. System.Windows.Point hP2InCanvas = GetPosInCanvas(hP2);
  1899. if (ni == _lesionIndex)
  1900. {
  1901. DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Choosed, ni.ToString());
  1902. }
  1903. else
  1904. {
  1905. DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Existed, ni.ToString());
  1906. }
  1907. }
  1908. // 显示病灶纵轴,注意所有点需转到Canvas坐标系下
  1909. Point2D vP1 = _modelResult.Lesions[ni].VerticalPoint1;
  1910. Point2D vP2 = _modelResult.Lesions[ni].VerticalPoint2;
  1911. if (vP1 != null && vP2 != null)
  1912. {
  1913. System.Windows.Point vP1InCanvas = GetPosInCanvas(vP1);
  1914. System.Windows.Point vP2InCanvas = GetPosInCanvas(vP2);
  1915. if (ni == _lesionIndex)
  1916. {
  1917. DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Choosed, ni.ToString());
  1918. }
  1919. else
  1920. {
  1921. DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Existed, ni.ToString());
  1922. }
  1923. }
  1924. }
  1925. }
  1926. }
  1927. /// <summary>
  1928. /// 将模型检测出的结果,显示在AI结果界面上
  1929. /// </summary>
  1930. //private void ShowModelResult()
  1931. //{
  1932. // if (_image != null)
  1933. // {
  1934. // DetectImage(_image);
  1935. // if (_modelResult.Lesions.Count > 0)
  1936. // {
  1937. // _lesions = _modelResult.Lesions;
  1938. // _lesionsLabels = _modelResult.Label;// _lesionsModelLabels;
  1939. // if (_lesions.Count <= 0)
  1940. // {
  1941. // _lesionIndex = -1;
  1942. // }
  1943. // else
  1944. // {
  1945. // _lesionIndex = 0;
  1946. // }
  1947. // ComboBoxLesions.SelectedIndex = _lesionIndex;
  1948. // ModelLesionsUpdated();
  1949. // //_lesionIndex = ComboBoxLesions.SelectedIndex;
  1950. // }
  1951. // }
  1952. //}
  1953. private void OnCheckedCheckModelResult(object sender, RoutedEventArgs e)
  1954. {
  1955. _showModelResult = true;
  1956. OrigImage.Source = _dstImgWin;
  1957. }
  1958. private void OnUncheckedCheckModelResult(object sender, RoutedEventArgs e)
  1959. {
  1960. _showModelResult = false;
  1961. OrigImage.Source = _origimg;
  1962. }
  1963. private void OnModelLesionSelectionChanged(object sender, SelectionChangedEventArgs e)
  1964. {
  1965. _lesionOriModelIndex = ComboBoxOriLesions.SelectedIndex;
  1966. ModelResultShow();
  1967. ModelComboBoxOriUpdated();
  1968. }
  1969. /// <summary>
  1970. /// 显示对应的模型检测结果
  1971. /// </summary>
  1972. private void ModelComboBoxOriUpdated()
  1973. {
  1974. ComboBoxOriLesions.SelectionChanged -= OnModelLesionSelectionChanged;
  1975. ComboBoxOriLesions.Items.Clear();
  1976. for (int ni = 0; ni < _modelResult.Lesions.Count; ni++)
  1977. {
  1978. ComboBoxOriLesions.Items.Add("病灶 " + ni.ToString());
  1979. }
  1980. if (ComboBoxOriLesions.SelectedIndex != _lesionOriModelIndex)
  1981. {
  1982. ComboBoxOriLesions.SelectedIndex = _lesionOriModelIndex;
  1983. }
  1984. ComboBoxOriLesions.SelectionChanged += OnModelLesionSelectionChanged;
  1985. //UpdateModelLesionsInCanvas();
  1986. }
  1987. private void ModelResultShow()
  1988. {
  1989. if (_modelResult.Lesions != null)
  1990. {
  1991. if (_modelResult.Lesions.Count > 0)
  1992. {
  1993. var lesionCur = _modelResult.Lesions[_lesionOriModelIndex];
  1994. int lesionLabel = _modelResult.Label[_lesionOriModelIndex];
  1995. string strLabel = string.Empty;
  1996. switch (lesionLabel)
  1997. {
  1998. case 0:
  1999. strLabel = "0";
  2000. break;
  2001. case 1:
  2002. strLabel = "脂肪瘤";
  2003. break;
  2004. case 2:
  2005. strLabel = "2级";
  2006. break;
  2007. case 3:
  2008. strLabel = "3级";
  2009. break;
  2010. case 4:
  2011. strLabel = "4a级";
  2012. break;
  2013. case 5:
  2014. strLabel = "4b级";
  2015. break;
  2016. case 6:
  2017. strLabel = "4c级";
  2018. break;
  2019. case 7:
  2020. strLabel = "5级";
  2021. break;
  2022. }
  2023. string strShape = string.Empty;
  2024. switch (lesionCur.Shape)
  2025. {
  2026. case EnumDesShapeValue.Oval:
  2027. strShape = "椭圆形";
  2028. break;
  2029. case EnumDesShapeValue.Round:
  2030. strShape = "圆形";
  2031. break;
  2032. case EnumDesShapeValue.Irregular:
  2033. strShape = "不规则";
  2034. break;
  2035. }
  2036. string strOrientation = string.Empty;
  2037. switch (lesionCur.Orientation)
  2038. {
  2039. case EnumDesOrientationValue.Parallel:
  2040. strOrientation = "平行";
  2041. break;
  2042. case EnumDesOrientationValue.NonParallel:
  2043. strOrientation = "非平行";
  2044. break;
  2045. }
  2046. string strMargin = string.Empty;
  2047. switch (lesionCur.Margin)
  2048. {
  2049. case EnumDesMarginValue.Circumscribed:
  2050. strMargin = "光整";
  2051. break;
  2052. case EnumDesMarginValue.NonCircumscribed:
  2053. strMargin = "不光整";
  2054. break;
  2055. }
  2056. string strEcho = string.Empty;
  2057. switch (lesionCur.EchoPattern)
  2058. {
  2059. case EnumDesEchoPatternValue.Anechoic:
  2060. strEcho = "无回声";
  2061. break;
  2062. case EnumDesEchoPatternValue.Hypoechoic:
  2063. strEcho = "低回声";
  2064. break;
  2065. case EnumDesEchoPatternValue.Hyperechoic:
  2066. strEcho = "高回声";
  2067. break;
  2068. case EnumDesEchoPatternValue.Strongechoic:
  2069. strEcho = "强回声";
  2070. break;
  2071. case EnumDesEchoPatternValue.Complex:
  2072. strEcho = "混合回声";
  2073. break;
  2074. case EnumDesEchoPatternValue.Isoechoic:
  2075. strEcho = "等回声";
  2076. break;
  2077. }
  2078. string strBound = string.Empty;
  2079. switch (lesionCur.Boundary)
  2080. {
  2081. case EnumDesLesionBoundaryValue.AbruptInterface:
  2082. strBound = "清晰";
  2083. break;
  2084. case EnumDesLesionBoundaryValue.EchogenicHalo:
  2085. strBound = "模糊";
  2086. break;
  2087. }
  2088. Point2D horPt1 = lesionCur.HorizontalPoint1;
  2089. Point2D horPt2 = lesionCur.HorizontalPoint2;
  2090. Point2D verPt1 = lesionCur.VerticalPoint1;
  2091. Point2D verPt2 = lesionCur.VerticalPoint2;
  2092. strLabel = "0"; //add
  2093. TextBlockLabel.Text = "等级:" + strLabel;
  2094. TextBlockShape.Text = "形状:" + strShape;
  2095. TextBlockOrientation.Text = "生长方向:" + strOrientation;
  2096. TextBlockEcho.Text = "回声类型:" + strEcho;
  2097. TextBlockBound.Text = "边界:" + strBound;
  2098. TextBlockMargin.Text = "边缘:" + strMargin;
  2099. TextBlockHorizontal.Text = "横径:" + "{" + horPt1.X + "," + horPt1.Y + "}" + "{" + horPt2.X + "," + horPt2.Y + "}";
  2100. TextBlockVertical.Text = "纵径:" + "{" + verPt1.X + "," + verPt1.Y + "}" + "{" + verPt2.X + "," + verPt2.Y + "}";
  2101. };
  2102. }
  2103. }
  2104. private void OnLesionSelectionLabelChanged(object sender, SelectionChangedEventArgs e)
  2105. {
  2106. _lesionLabelIndex = ComboBoxLesionsLabel.SelectedIndex;
  2107. if(_lesionsLabels.Count >0)
  2108. {
  2109. if (_lesionsLabels[_lesionIndex] < 0)
  2110. {
  2111. _lesionsLabels[_lesionIndex] = _lesionLabelIndex;
  2112. }
  2113. else
  2114. {
  2115. if(_lesionLabelIndex >0)
  2116. {
  2117. _lesionsLabels[_lesionIndex] = _lesionLabelIndex;
  2118. }
  2119. }
  2120. //_lesionsLabels[_lesionIndex] = _lesionLabelIndex;
  2121. }
  2122. else
  2123. {
  2124. ComboBoxLesionsLabel.SelectedIndex = -1;
  2125. _lesionLabelIndex = 0;
  2126. }
  2127. }
  2128. private void InitializeComboBoxLesionsLabel()
  2129. {
  2130. // 分级
  2131. ComboBoxLesionsLabel.Items.Add("0");
  2132. ComboBoxLesionsLabel.Items.Add("脂肪瘤");
  2133. ComboBoxLesionsLabel.Items.Add("2级");
  2134. ComboBoxLesionsLabel.Items.Add("3级");
  2135. ComboBoxLesionsLabel.Items.Add("4a级");
  2136. ComboBoxLesionsLabel.Items.Add("4b级");
  2137. ComboBoxLesionsLabel.Items.Add("4c级");
  2138. ComboBoxLesionsLabel.Items.Add("5级");
  2139. }
  2140. private void OnCheckedCheckDrawingResult(object sender, RoutedEventArgs e)
  2141. {
  2142. _showDrawingResult = true;
  2143. //_image = new Bitmap(imgPath);
  2144. //_drawingPoints;
  2145. UpdateLesionsInCanvas();
  2146. ShowDrawingPts();
  2147. }
  2148. private void ShowDrawingPts()
  2149. {
  2150. int num = _drawingPoints.Count;
  2151. if (num > 0)
  2152. {
  2153. // 更新显示正在绘制的轮廓线
  2154. DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawingPt");
  2155. }
  2156. }
  2157. private void OnUncheckedCheckDrawingResult(object sender, RoutedEventArgs e)
  2158. {
  2159. _showDrawingResult = false;;
  2160. RemoveContourLine();
  2161. }
  2162. private void RemoveContourLine()
  2163. {
  2164. if (_drawimg == null)
  2165. {
  2166. return;
  2167. }
  2168. // 先清空画布上旧的显示内容
  2169. for (int ni = 0; ni < _lesions.Count; ni++)
  2170. {
  2171. RemoveContourInCanvas(ni.ToString());
  2172. RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
  2173. RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
  2174. }
  2175. int num = _drawingPoints.Count;
  2176. if (num > 0)
  2177. {
  2178. // 更新显示正在绘制的轮廓线
  2179. RemoveContourInCanvasForDrawPts("drawingPt");
  2180. }
  2181. }
  2182. private void RemoveContourInCanvasForDrawPts(string name)
  2183. {
  2184. string contourName = "Contour_" + name;
  2185. if (MyCanvasDraw.FindName(contourName) is Polyline contourExists)
  2186. {
  2187. MyCanvasDraw.Children.Remove(contourExists);
  2188. MyCanvasDraw.UnregisterName(contourName);
  2189. }
  2190. }
  2191. private void OnBtnSaveResultClicked(object sender, RoutedEventArgs e)
  2192. {
  2193. Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
  2194. openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg";
  2195. openFileDialog.Multiselect = true;
  2196. openFileDialog.Title = "选择一幅或多幅图像";
  2197. if (openFileDialog.ShowDialog() ?? false)
  2198. {
  2199. foreach (string filename in openFileDialog.FileNames)
  2200. {
  2201. Bitmap img = new Bitmap(filename);
  2202. string imgName = System.IO.Path.GetFileNameWithoutExtension(filename);
  2203. string temp;
  2204. int idx = filename.LastIndexOf("\\");
  2205. temp = filename.Substring(idx);
  2206. string[] strs1 = temp.Split('\\');
  2207. temp = strs1[1];
  2208. //string[] strs2 = temp.Split(new char[4] { '.', 'j', 'p', 'g' }, 2);
  2209. string[] strs2 = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
  2210. string ImgId = strs2[0];
  2211. int imgIdx = _allImages.FindIndex(x => x.ImageId == ImgId);
  2212. int imageId = imgIdx;
  2213. //_showImg = img;
  2214. if (imageId >= 0)
  2215. {
  2216. SaveModel(img, imageId, ImgId);
  2217. Save(img, imageId, ImgId);
  2218. JudgeResult(imageId);
  2219. }
  2220. }
  2221. }
  2222. }
  2223. private void JudgeResult(int imageId)
  2224. {
  2225. if (_modelResult.Lesions.Count > 0 && _allImages[imageId].Lesions.Count > 0)
  2226. {
  2227. if (_modelResult.Lesions.Count != _allImages[imageId].Lesions.Count)
  2228. {
  2229. return;
  2230. }
  2231. else if(_modelResult.Lesions.Count==1 && _allImages[imageId].Lesions.Count ==1)
  2232. {
  2233. var shapeGt = _allImages[imageId].Lesions[0].Shape;
  2234. var shapeModel = _modelResult.Lesions[0].Shape;
  2235. if (shapeGt == EnumDesShapeValue.Oval && shapeModel == EnumDesShapeValue.Oval)
  2236. {
  2237. _Oval_Oval_num++;
  2238. }
  2239. else if (shapeGt == EnumDesShapeValue.Oval && shapeModel == EnumDesShapeValue.Round)
  2240. {
  2241. _Oval_Round_num++;
  2242. }
  2243. else if (shapeGt == EnumDesShapeValue.Oval && shapeModel == EnumDesShapeValue.Irregular)
  2244. {
  2245. _Oval_Irregular_num++;
  2246. }
  2247. if (shapeGt == EnumDesShapeValue.Round && shapeModel == EnumDesShapeValue.Oval)
  2248. {
  2249. _Round_Oval_num++;
  2250. }
  2251. else if (shapeGt == EnumDesShapeValue.Round && shapeModel == EnumDesShapeValue.Round)
  2252. {
  2253. _Round_Round_num++;
  2254. }
  2255. else if (shapeGt == EnumDesShapeValue.Round && shapeModel == EnumDesShapeValue.Irregular)
  2256. {
  2257. _Round_Irregular_num++;
  2258. }
  2259. if (shapeGt == EnumDesShapeValue.Irregular && shapeModel == EnumDesShapeValue.Oval)
  2260. {
  2261. _Irregular_Oval_num++;
  2262. }
  2263. else if (shapeGt == EnumDesShapeValue.Irregular && shapeModel == EnumDesShapeValue.Round)
  2264. {
  2265. _Irregular_Round_num++;
  2266. }
  2267. else if (shapeGt == EnumDesShapeValue.Irregular && shapeModel == EnumDesShapeValue.Irregular)
  2268. {
  2269. _Irregular_Irregular_num++;
  2270. }
  2271. var orientationGt = _allImages[imageId].Lesions[0].Orientation;
  2272. var orientationModel = _modelResult.Lesions[0].Orientation;
  2273. if (orientationGt == EnumDesOrientationValue.Parallel && orientationModel == EnumDesOrientationValue.Parallel)
  2274. {
  2275. _Parallel_Parallel_num++;
  2276. }
  2277. else if(orientationGt == EnumDesOrientationValue.Parallel && orientationModel == EnumDesOrientationValue.NonParallel)
  2278. {
  2279. _Parallel_NonParallel_num++;
  2280. }
  2281. if (orientationGt == EnumDesOrientationValue.NonParallel && orientationModel == EnumDesOrientationValue.Parallel)
  2282. {
  2283. _NonParallel_Parallel_num++;
  2284. }
  2285. else if (orientationGt == EnumDesOrientationValue.NonParallel && orientationModel == EnumDesOrientationValue.NonParallel)
  2286. {
  2287. _NonParallel_NonParallel_num++;
  2288. }
  2289. var echoGt = _allImages[imageId].Lesions[0].EchoPattern;
  2290. var echoModel = _modelResult.Lesions[0].EchoPattern;
  2291. if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
  2292. {
  2293. _Anechoic_Anechoic_num++;
  2294. }
  2295. else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
  2296. {
  2297. _Anechoic_Hypoechoic_num++;
  2298. }
  2299. else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
  2300. {
  2301. _Anechoic_Isoechoic_num++;
  2302. }
  2303. else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
  2304. {
  2305. _Anechoic_Hyperechoic_num++;
  2306. }
  2307. else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Complex)
  2308. {
  2309. _Anechoic_Complex_num++;
  2310. }
  2311. if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
  2312. {
  2313. _Hypoechoic_Anechoic_num++;
  2314. }
  2315. else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
  2316. {
  2317. _Hypoechoic_Hypoechoic_num++;
  2318. }
  2319. else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
  2320. {
  2321. _Hypoechoic_Isoechoic_num++;
  2322. }
  2323. else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
  2324. {
  2325. _Hypoechoic_Hyperechoic_num++;
  2326. }
  2327. else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Complex)
  2328. {
  2329. _Hypoechoic_Complex_num++;
  2330. }
  2331. if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
  2332. {
  2333. _Isoechoic_Anechoic_num++;
  2334. }
  2335. else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
  2336. {
  2337. _Isoechoic_Hypoechoic_num++;
  2338. }
  2339. else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
  2340. {
  2341. _Isoechoic_Isoechoic_num++;
  2342. }
  2343. else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
  2344. {
  2345. _Isoechoic_Hyperechoic_num++;
  2346. }
  2347. else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Complex)
  2348. {
  2349. _Isoechoic_Complex_num++;
  2350. }
  2351. if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
  2352. {
  2353. _Hyperechoic_Anechoic_num++;
  2354. }
  2355. else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
  2356. {
  2357. _Hyperechoic_Hypoechoic_num++;
  2358. }
  2359. else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
  2360. {
  2361. _Hyperechoic_Isoechoic_num++;
  2362. }
  2363. else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
  2364. {
  2365. _Hyperechoic_Hyperechoic_num++;
  2366. }
  2367. else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Complex)
  2368. {
  2369. _Hyperechoic_Complex_num++;
  2370. }
  2371. if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Anechoic)
  2372. {
  2373. _Complex_Anechoic_num++;
  2374. }
  2375. else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Hypoechoic)
  2376. {
  2377. _Complex_Hypoechoic_num++;
  2378. }
  2379. else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Isoechoic)
  2380. {
  2381. _Complex_Isoechoic_num++;
  2382. }
  2383. else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Hyperechoic)
  2384. {
  2385. _Complex_Hyperechoic_num++;
  2386. }
  2387. else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Complex)
  2388. {
  2389. _Complex_Complex_num++;
  2390. }
  2391. var boundGt = _allImages[imageId].Lesions[0].Boundary;
  2392. var boundModel = _modelResult.Lesions[0].Boundary;
  2393. if (boundGt == EnumDesLesionBoundaryValue.AbruptInterface && boundModel == EnumDesLesionBoundaryValue.AbruptInterface)
  2394. {
  2395. _AbruptInterface_AbruptInterface_num++;
  2396. }
  2397. else if (boundGt == EnumDesLesionBoundaryValue.AbruptInterface && boundModel == EnumDesLesionBoundaryValue.EchogenicHalo)
  2398. {
  2399. _AbruptInterface_EchogenicHalo_num++;
  2400. }
  2401. if (boundGt == EnumDesLesionBoundaryValue.EchogenicHalo && boundModel == EnumDesLesionBoundaryValue.AbruptInterface)
  2402. {
  2403. _EchogenicHalo_AbruptInterface_num++;
  2404. }
  2405. else if (boundGt == EnumDesLesionBoundaryValue.EchogenicHalo && boundModel == EnumDesLesionBoundaryValue.EchogenicHalo)
  2406. {
  2407. _EchogenicHalo_EchogenicHalo_num++;
  2408. }
  2409. var marginGt = _allImages[imageId].Lesions[0].Margin;
  2410. var marginModel = _modelResult.Lesions[0].Margin;
  2411. if (marginGt == EnumDesMarginValue.Circumscribed && marginModel == EnumDesMarginValue.Circumscribed)
  2412. {
  2413. _Circumscribed_NonCircumscribed_num++;
  2414. }
  2415. else if (marginGt == EnumDesMarginValue.Circumscribed && marginModel == EnumDesMarginValue.NonCircumscribed)
  2416. {
  2417. _Circumscribed_NonCircumscribed_num++;
  2418. }
  2419. if (marginGt == EnumDesMarginValue.NonCircumscribed && marginModel == EnumDesMarginValue.Circumscribed)
  2420. {
  2421. _NonCircumscribed_Circumscribed_num++;
  2422. }
  2423. else if (marginGt == EnumDesMarginValue.NonCircumscribed && marginModel == EnumDesMarginValue.NonCircumscribed)
  2424. {
  2425. _NonCircumscribed_NonCircumscribed_num++;
  2426. }
  2427. }
  2428. }
  2429. }
  2430. public void SaveModel(Bitmap image, int imageId, string imageName)
  2431. {
  2432. string currentPath = System.Environment.CurrentDirectory;
  2433. string newPath = System.IO.Path.Combine(currentPath, "result");
  2434. RawImage rawImg = null;
  2435. rawImg = RawImageShowUtils.BitmapToRawImage(image);
  2436. if(_newModelResult == null)
  2437. {
  2438. string name = _allImages[_imgIndex].ImageId;
  2439. _caseId = Guid.NewGuid().ToString();
  2440. _dataId = name;
  2441. _readingVideo = false;
  2442. var extendData = new Dictionary<string, object>();
  2443. extendData.Add("CaseId", _caseId);
  2444. extendData.Add("DataId", _dataId);
  2445. extendData.Add("IsVideo", _readingVideo);
  2446. extendData.Add("TimeStamp", (double)_frameIndex);
  2447. _processId = _module.StartProcess();
  2448. var input = new ImageInputData(rawImg, extendData);
  2449. IDetectedObject[] result = _module.PushOnePieceOfData(_processId, input);
  2450. _newModelResult = result;
  2451. _module.EndProcess(_processId);
  2452. }
  2453. else
  2454. {
  2455. }
  2456. //var diagResult = _diagSystem.EvaluateOneImage(rawImg);
  2457. int breastLesionNum = 0;
  2458. Bitmap dstimage = image.Clone(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
  2459. if (_newModelResult != null)
  2460. {
  2461. foreach (var moduleResult in _newModelResult)
  2462. {
  2463. var label = moduleResult.Label;
  2464. var nameOrgan = label.GroupName;
  2465. var Ilabel = moduleResult.Label;
  2466. int indexLabel = Ilabel.Index;
  2467. if (nameOrgan == "AI.Vaid.Breast.Lesion")
  2468. {
  2469. using (var g = Graphics.FromImage(dstimage))
  2470. {
  2471. int num = 0;
  2472. string strDescriptionShape = string.Empty;
  2473. string strDescriptionOrientation = string.Empty;
  2474. string strDescriptionEcho = string.Empty;
  2475. string strDescriptionBound = string.Empty;
  2476. string strDescriptionMargin = string.Empty;
  2477. System.Drawing.Brush brush = System.Drawing.Brushes.Green;
  2478. List<LesionInfo> CurImageLesion = new List<LesionInfo>();
  2479. if (moduleResult.Contour?.Contours.Length > 0)
  2480. {
  2481. int count = moduleResult.Contour.Contours.Length;
  2482. for (int i = 0; i < count; i++)
  2483. {
  2484. brush = System.Drawing.Brushes.Green;
  2485. int labelName = indexLabel;
  2486. LesionInfo lesion = new LesionInfo();
  2487. var contourPoints = moduleResult.Contour.Contours[i];
  2488. int pointCount = contourPoints.Points.Length;
  2489. var points = new List<Point2D>();
  2490. System.Drawing.PointF[] lesionContour = new PointF[pointCount];
  2491. for (int j = 0; j < pointCount; j++)
  2492. {
  2493. var point = new System.Windows.Point(contourPoints.Points[j].X, contourPoints.Points[j].Y);
  2494. lesionContour[j].X = contourPoints.Points[j].X;
  2495. lesionContour[j].Y = contourPoints.Points[j].Y;
  2496. Point2D pt = new Point2D(contourPoints.Points[j].X, contourPoints.Points[j].Y);
  2497. points.Add(pt);
  2498. lesion.Contour.Add(pt);
  2499. }
  2500. g.DrawPolygon(new System.Drawing.Pen(brush, 2), lesionContour);
  2501. var desResult = moduleResult.Description;
  2502. var type = desResult.GetType();
  2503. string strDescription = string.Empty;
  2504. {
  2505. foreach (var key in desResult.Descriptions.Keys)
  2506. {
  2507. if (key == "Shape")
  2508. {
  2509. EnumDesShapeValue sss = new EnumDesShapeValue();
  2510. string des = string.Empty;
  2511. switch (desResult.Descriptions[key])
  2512. {
  2513. case "Oval":
  2514. des = "椭圆形";
  2515. sss = EnumDesShapeValue.Oval;
  2516. break;
  2517. case "Round":
  2518. des = "类圆形";
  2519. sss = EnumDesShapeValue.Round;
  2520. break;
  2521. case "Irregular":
  2522. des = "不规则形";
  2523. sss = EnumDesShapeValue.Irregular;
  2524. break;
  2525. }
  2526. lesion.Shape = sss;
  2527. strDescription += "形状:" + des + Environment.NewLine;
  2528. }
  2529. if (key == "Orientation")
  2530. {
  2531. EnumDesOrientationValue sss = new EnumDesOrientationValue();
  2532. string des = string.Empty;
  2533. switch (desResult.Descriptions[key])
  2534. {
  2535. case "Parallel":
  2536. des = "平行";
  2537. sss = EnumDesOrientationValue.Parallel;
  2538. break;
  2539. case "NonParallel":
  2540. des = "非平行";
  2541. sss = EnumDesOrientationValue.NonParallel;
  2542. break;
  2543. }
  2544. lesion.Orientation = sss;
  2545. strDescription += "生长方向:" + des + Environment.NewLine;
  2546. }
  2547. if (key == "EchoPattern")
  2548. {
  2549. EnumDesEchoPatternValue sss = new EnumDesEchoPatternValue();
  2550. string des = string.Empty;
  2551. switch (desResult.Descriptions[key])
  2552. {
  2553. case "Anechoic":
  2554. des = "无回声";
  2555. sss = EnumDesEchoPatternValue.Anechoic;
  2556. break;
  2557. case "Hypoechoic":
  2558. des = "低回声";
  2559. sss = EnumDesEchoPatternValue.Hypoechoic;
  2560. break;
  2561. case "Isoechoic":
  2562. des = "等回声";
  2563. sss = EnumDesEchoPatternValue.Isoechoic;
  2564. break;
  2565. case "Hyperechoic":
  2566. des = "高回声";
  2567. sss = EnumDesEchoPatternValue.Hyperechoic;
  2568. break;
  2569. case "Complex":
  2570. des = "混合回声";
  2571. sss = EnumDesEchoPatternValue.Complex;
  2572. break;
  2573. }
  2574. lesion.EchoPattern = sss;
  2575. strDescription += "回声类型:" + des + Environment.NewLine;
  2576. }
  2577. if (key == "Boundary")
  2578. {
  2579. EnumDesLesionBoundaryValue sss = new EnumDesLesionBoundaryValue();
  2580. string des = string.Empty;
  2581. switch (desResult.Descriptions[key])
  2582. {
  2583. case "AbruptInterface":
  2584. des = "清晰";
  2585. sss = EnumDesLesionBoundaryValue.AbruptInterface;
  2586. break;
  2587. case "EchogenicHalo":
  2588. des = "模糊";
  2589. sss = EnumDesLesionBoundaryValue.EchogenicHalo;
  2590. break;
  2591. }
  2592. lesion.Boundary = sss;
  2593. strDescription += "边界:" + des + Environment.NewLine;
  2594. }
  2595. if (key == "Margin")
  2596. {
  2597. EnumDesMarginValue sss = new EnumDesMarginValue();
  2598. string des = string.Empty;
  2599. switch (desResult.Descriptions[key])
  2600. {
  2601. case "Circumscribed":
  2602. des = "光整";
  2603. sss = EnumDesMarginValue.Circumscribed;
  2604. break;
  2605. case "NonCircumscribed":
  2606. des = "不光整";
  2607. sss = EnumDesMarginValue.NonCircumscribed;
  2608. break;
  2609. }
  2610. lesion.Margin = sss;
  2611. strDescription += "边缘:" + des + Environment.NewLine;
  2612. }
  2613. }
  2614. }
  2615. var rect = moduleResult.BoundingBox.Contour.BoundingBox();
  2616. var roiBox = moduleResult.BoundingBox;
  2617. var ss = roiBox.Contour.Points;
  2618. var lesionSize = Array.Find(moduleResult.Measurements, x => x.GetType() == typeof(TransverseLongitudinalDiameterMeasurement));
  2619. var size = (TransverseLongitudinalDiameterMeasurement)lesionSize;
  2620. var pointLineH1 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineStart.X, size.TransverseDiameterMarkPosition.LineStart.Y);
  2621. var pointLineH2 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineEnd.X, size.TransverseDiameterMarkPosition.LineEnd.Y);
  2622. var pointLineV1 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineStart.X, size.LongitudinalDiameterMarkPosition.LineStart.Y);
  2623. var pointLineV2 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineEnd.X, size.LongitudinalDiameterMarkPosition.LineEnd.Y);
  2624. System.Drawing.Point[] axisH = new System.Drawing.Point[2];
  2625. System.Drawing.Point[] axisV = new System.Drawing.Point[2];
  2626. axisH[0].X = (int)pointLineH1.X;
  2627. axisH[0].Y = (int)pointLineH1.Y;
  2628. axisH[1].X = (int)pointLineH2.X;
  2629. axisH[1].Y = (int)pointLineH2.Y;
  2630. axisV[0].X = (int)pointLineV1.X;
  2631. axisV[0].Y = (int)pointLineV1.Y;
  2632. axisV[1].X = (int)pointLineV2.X;
  2633. axisV[1].Y = (int)pointLineV2.Y;
  2634. System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2);
  2635. g.DrawLines(pen_h, axisH); //横轴,浅绿色
  2636. System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1);
  2637. g.DrawLines(pen_v, axisV); //纵轴,红色
  2638. Font drawFont = new Font("黑体", 24);
  2639. SolidBrush drawBrush = new SolidBrush(System.Drawing.Color.GreenYellow);
  2640. float ptx = 10.0f;
  2641. float pty = 0.0f + 20;
  2642. string drawText = strDescriptionEcho;//
  2643. g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * 4 * num);
  2644. drawText = strDescriptionShape;
  2645. g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 1));
  2646. drawText = strDescriptionMargin;
  2647. g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 2));
  2648. drawText = strDescriptionOrientation;
  2649. g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 3));
  2650. drawText = strDescriptionBound;
  2651. g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 4));
  2652. //
  2653. drawText = num.ToString();
  2654. g.DrawString(drawText, drawFont, drawBrush, axisH[0].X, axisH[0].Y);
  2655. num++;
  2656. }
  2657. }
  2658. g.Dispose();
  2659. }
  2660. string name = newPath + "\\" + imageName + ".jpg";
  2661. dstimage.Save(name, System.Drawing.Imaging.ImageFormat.Png);
  2662. dstimage.Dispose();
  2663. }
  2664. }
  2665. }
  2666. }
  2667. public void Save(Bitmap image, int imageId, string imageName)
  2668. {
  2669. string currentPath = System.Environment.CurrentDirectory;
  2670. string newPath = System.IO.Path.Combine(currentPath, "result");
  2671. System.IO.Directory.CreateDirectory(newPath);
  2672. int imgNum = _allImages.Count;
  2673. if (image == null || _allImages.Count <= 0)
  2674. {
  2675. return;
  2676. }
  2677. if (_allImages[imageId].Lesions.Count <= 0)
  2678. {
  2679. string name = newPath + "\\" + imageName + ".png";
  2680. //image.Save(name, System.Drawing.Imaging.ImageFormat.Png);
  2681. }
  2682. else
  2683. {
  2684. int numLesions = _allImages[imageId].Lesions.Count;
  2685. Bitmap origImg = image;
  2686. for (int jj = 0; jj < numLesions; jj++)
  2687. {
  2688. EnumDesEchoPatternValue echoGT = _allImages[imageId].Lesions[jj].EchoPattern;
  2689. EnumDesShapeValue shapeGT = _allImages[imageId].Lesions[jj].Shape;
  2690. EnumDesMarginValue marginGT = _allImages[imageId].Lesions[jj].Margin;
  2691. EnumDesOrientationValue orientationGT = _allImages[imageId].Lesions[jj].Orientation;
  2692. EnumDesLesionBoundaryValue boundGT = _allImages[imageId].Lesions[jj].Boundary;
  2693. string echo = null, shape = null, margin = null, orientation = null, bound = null;
  2694. switch (echoGT)
  2695. {
  2696. case EnumDesEchoPatternValue.Anechoic:
  2697. echo = "无回声";
  2698. break;
  2699. case EnumDesEchoPatternValue.Hypoechoic:
  2700. echo = "低回声";
  2701. break;
  2702. case EnumDesEchoPatternValue.Hyperechoic:
  2703. echo = "高回声";
  2704. break;
  2705. case EnumDesEchoPatternValue.Strongechoic:
  2706. echo = "强回声";
  2707. break;
  2708. case EnumDesEchoPatternValue.Complex:
  2709. echo = "混合回声";
  2710. break;
  2711. case EnumDesEchoPatternValue.Isoechoic:
  2712. echo = "等回声";
  2713. break;
  2714. }
  2715. switch (shapeGT)
  2716. {
  2717. case EnumDesShapeValue.Oval:
  2718. shape = "椭圆形";
  2719. break;
  2720. case EnumDesShapeValue.Round:
  2721. shape = "圆形";
  2722. break;
  2723. case EnumDesShapeValue.Irregular:
  2724. shape = "不规则";
  2725. break;
  2726. }
  2727. switch (marginGT)
  2728. {
  2729. case EnumDesMarginValue.Circumscribed:
  2730. margin = "光整";
  2731. break;
  2732. case EnumDesMarginValue.NonCircumscribed:
  2733. margin = "不光整";
  2734. break;
  2735. }
  2736. switch (orientationGT)
  2737. {
  2738. case EnumDesOrientationValue.Parallel:
  2739. orientation = "平行";
  2740. break;
  2741. case EnumDesOrientationValue.NonParallel:
  2742. orientation = "非平行";
  2743. break;
  2744. }
  2745. switch (boundGT)
  2746. {
  2747. case EnumDesLesionBoundaryValue.AbruptInterface:
  2748. bound = "清晰";
  2749. break;
  2750. case EnumDesLesionBoundaryValue.EchogenicHalo:
  2751. bound = "模糊";
  2752. break;
  2753. }
  2754. // 显示新的病灶
  2755. LesionInfo lesion = _allImages[imageId].Lesions[jj];
  2756. int num2 = lesion.Contour.Count;
  2757. using (var g = Graphics.FromImage(origImg))
  2758. {
  2759. System.Drawing.Pen pen3 = new System.Drawing.Pen(System.Drawing.Brushes.Navy, 2);
  2760. System.Drawing.PointF[] lesionContour = new PointF[num2];
  2761. for (int i = 0; i < num2; i++)
  2762. {
  2763. lesionContour[i].X = _allImages[imageId].Lesions[jj].Contour[i].X;
  2764. lesionContour[i].Y = _allImages[imageId].Lesions[jj].Contour[i].Y;
  2765. }
  2766. if (num2 > 0)
  2767. {
  2768. System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Orange, 2);
  2769. g.DrawLines(pen, lesionContour); //画病灶轮廓
  2770. pen.Dispose();
  2771. }
  2772. System.Drawing.PointF[] axisH = new PointF[2];
  2773. System.Drawing.PointF[] axisV = new PointF[2];
  2774. axisH[0].X = lesion.HorizontalPoint1.X;
  2775. axisH[0].Y = lesion.HorizontalPoint1.Y;
  2776. axisH[1].X = lesion.HorizontalPoint2.X;
  2777. axisH[1].Y = lesion.HorizontalPoint2.Y;
  2778. axisV[0].X = lesion.VerticalPoint1.X;
  2779. axisV[0].Y = lesion.VerticalPoint1.Y;
  2780. axisV[1].X = lesion.VerticalPoint2.X;
  2781. axisV[1].Y = lesion.VerticalPoint2.Y;
  2782. //画轮廓的长短轴
  2783. System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2);
  2784. g.DrawLines(pen_h, axisH); //横轴,浅绿色
  2785. System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1);
  2786. g.DrawLines(pen_v, axisV); //纵轴,红色
  2787. //写汉字
  2788. Font drawFont = new Font("黑体", 24);
  2789. SolidBrush drawBrush = new SolidBrush(System.Drawing.Color.GreenYellow);
  2790. float x = 10.0f;
  2791. float y = 0.0f + 20;
  2792. string drawText = echo;//
  2793. g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * 4 * jj);
  2794. drawText = shape;
  2795. g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 1));
  2796. drawText = margin;
  2797. g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 2));
  2798. drawText = orientation;
  2799. g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 3));
  2800. drawText = bound;
  2801. g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 4));
  2802. //
  2803. drawText = jj.ToString();
  2804. g.DrawString(drawText, drawFont, drawBrush, axisH[0].X, axisH[0].Y);
  2805. g.Dispose();
  2806. }
  2807. }
  2808. string name = newPath + "\\" + imageName + ".png";
  2809. origImg.Save(name, System.Drawing.Imaging.ImageFormat.Png);
  2810. origImg.Dispose();
  2811. }
  2812. }
  2813. private void OnBtnGoBackClicked(object sender, RoutedEventArgs e)
  2814. {
  2815. int num = _drawingPoints.Count;
  2816. if (num > 0)
  2817. {
  2818. _drawingPoints.RemoveAt(num - 1);
  2819. DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawingPt");
  2820. }
  2821. else
  2822. {
  2823. System.Windows.MessageBox.Show("轮廓点不存在");
  2824. }
  2825. //UpdateLesionsInCanvas();
  2826. ////_drawingPoints.Add(_drawingPoints[0]);
  2827. //List<Point2D> contourInOrigImg = new List<Point2D>();
  2828. //foreach (var point in _drawingPoints)
  2829. //{
  2830. // contourInOrigImg.Add(GetPosInOrigImage(point));
  2831. //}
  2832. //_drawingPoints = new List<System.Windows.Point>();
  2833. //_mouseOper = EnumMouseOperType.None;
  2834. //RemoveContourInCanvas("drawing");
  2835. //UserControlLesionSelected.SetContour(contourInOrigImg);
  2836. }
  2837. }
  2838. }