COTSField.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. using OTSCLRINTERFACE;
  2. using OTSCommon.DBOperate.Model;
  3. using OTSMeasureApp._0_OTSModel.OTSDataType;
  4. using OTSModelSharp;
  5. using OTSModelSharp.ServiceCenter;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Drawing;
  9. using System.Drawing.Imaging;
  10. using System.Linq;
  11. using System.Xml;
  12. namespace OTSDataType
  13. {
  14. public class COTSField : ISlo
  15. {
  16. public COTSField leftField = null;
  17. public COTSField upField = null;
  18. public COTSField downField = null;
  19. public COTSField rightField = null;
  20. public List<CBSEImgClr> particleImages = new List<CBSEImgClr>();
  21. protected NLog.Logger log;
  22. // ID
  23. int m_nID;
  24. int measureSequence;
  25. private bool m_enable=true;
  26. // position (from field center manager)
  27. protected System.Drawing.PointF m_otsPos;
  28. protected CBSEImgClr m_pBSEImg;
  29. protected double m_pixelSize;
  30. protected CImageHandler m_ImagePro;
  31. protected List<COTSParticleClr> m_listInitialParticles = new List<COTSParticleClr>();//hold up all the particles abstracted from bse image;
  32. protected List<COTSParticleClr> m_listAnalysisParticles = new List<COTSParticleClr>();// hold up all the final particles that need to be saved to db ;
  33. private int imgheight;
  34. private int imgwidth;
  35. private COTSRect m_otsRect;
  36. private COTSSample m_sample;
  37. public COTSField()
  38. {
  39. log = NLog.LogManager.GetCurrentClassLogger();
  40. Init();
  41. }//only using in xmlserialization
  42. public int ImgHeight { get => imgheight; set => imgheight = value; }
  43. public int ImgWidth { get => imgwidth; set => imgwidth = value; }
  44. public COTSSample Sample { get => m_sample; set => m_sample = value; }
  45. public bool Enable { get => m_enable; set => m_enable = value; }
  46. internal COTSRect GetOTSRect()
  47. {
  48. return m_otsRect;
  49. }
  50. internal void SetOTSRect(COTSRect value)
  51. {
  52. m_otsRect = value;
  53. }
  54. public int GetMeasureSequence()
  55. {
  56. return measureSequence;
  57. }
  58. public void SetMeasureSequence(int value)
  59. {
  60. measureSequence = value;
  61. }
  62. public List<string> strKeyName;
  63. public bool GetIsMeasureComplete()
  64. {
  65. return isMeasureComplete;
  66. }
  67. public void SetIsMeasureComplete(bool value)
  68. {
  69. isMeasureComplete = value;
  70. }
  71. private bool isMeasureComplete;
  72. public PointF GetSemPos()
  73. {
  74. return m_semPos;
  75. }
  76. public void SetSemPos(PointF value)
  77. {
  78. m_semPos = value;
  79. }
  80. private PointF m_semPos;
  81. public List<COTSParticleClr> GetInitialParticles()
  82. {
  83. return m_listInitialParticles;
  84. }
  85. public List<COTSParticleClr> GetListAnalysisParticles()
  86. {
  87. return m_listAnalysisParticles;
  88. }
  89. public List<COTSParticleClr> GetListXrayParticles()
  90. {
  91. List<COTSParticleClr> m_listXrayParticles = new List<COTSParticleClr>();//hold up all the particles that needing the xray data.
  92. m_listXrayParticles.Clear();
  93. foreach (var p in m_listAnalysisParticles)
  94. {
  95. if (p.IsXrayParticle())
  96. {
  97. m_listXrayParticles.Add(p);
  98. }
  99. }
  100. return m_listXrayParticles;
  101. }
  102. public void SetListAnalysisParticles(List<COTSParticleClr> value)
  103. {
  104. m_listAnalysisParticles = value;
  105. }
  106. public void SetInitialParticles(List<COTSParticleClr> value)
  107. {
  108. m_listInitialParticles = value;
  109. }
  110. public COTSField(PointF centerPoint, double a_dPixelSize)
  111. {
  112. log = NLog.LogManager.GetCurrentClassLogger();
  113. Init();
  114. m_otsPos = centerPoint;
  115. m_pixelSize = a_dPixelSize;
  116. }
  117. public double GetPixelSize()
  118. {
  119. return m_pixelSize;
  120. }
  121. public void SetPixelSize(double size)
  122. {
  123. m_pixelSize = size;
  124. }
  125. // initialization
  126. void Init()
  127. {
  128. // initialization
  129. m_nID = -1;
  130. m_otsPos = new System.Drawing.Point(0, 0);
  131. m_listInitialParticles.Clear();
  132. m_enable = true;
  133. }
  134. public COTSField(COTSField a_poSource)
  135. {
  136. // can't copy itself
  137. if (a_poSource == this)
  138. {
  139. return;
  140. }
  141. Duplicate(a_poSource);
  142. }
  143. public CBSEImgClr GetBSEImage()
  144. {
  145. return m_pBSEImg;
  146. }
  147. public Bitmap GetAnalysisParticleBlackColoredImage()
  148. {
  149. CImageHandler imghandler = new CImageHandler();
  150. List<COTSParticleClr> Parts = GetInitialParticles();
  151. Bitmap img = new Bitmap(this.ImgWidth, this.ImgHeight);
  152. var imgparam = m_sample.GetMsrParams().GetImageProcessParam();
  153. var pixelsize = m_sample.CalculatePixelSize();
  154. imghandler.GetImageWithBlackColoredParts(Parts,imgparam,pixelsize, ref img);
  155. return img;
  156. }
  157. public Bitmap GetAnalysisParticleSTDColoredImage()
  158. {
  159. CImageHandler imghandler = new CImageHandler();
  160. List<COTSParticleClr> Parts = GetListAnalysisParticles();
  161. Bitmap img = new Bitmap(this.ImgWidth, this.ImgHeight, PixelFormat.Format24bppRgb);
  162. var imgparam = m_sample.GetMsrParams().GetImageProcessParam();
  163. var pixelsize = m_sample.CalculatePixelSize();
  164. imghandler.GetImageWithSTDColoredParts(Parts, imgparam, pixelsize, ref img);
  165. return img;
  166. }
  167. public void SetBSEImage(CBSEImgClr a_pBSEImg)
  168. {
  169. if (a_pBSEImg == null)
  170. {
  171. // invalid BSE image.
  172. log.Error("SetBSEImage: invalid BSE image.");
  173. return;
  174. }
  175. m_pBSEImg = a_pBSEImg;
  176. imgwidth = a_pBSEImg.GetWidth();
  177. imgheight = a_pBSEImg.GetHeight();
  178. }
  179. public void GetOriginalParticles(CSampleParam pMsrParam, double pixelsize)
  180. {
  181. COTSImageProcParam pImgProcessParam = pMsrParam.GetImageProcessParam();
  182. // remove BES image background
  183. if (m_pBSEImg == null)
  184. return;
  185. CImageHandler imghandler = new CImageHandler();
  186. List<COTSParticleClr> allParts = new List<COTSParticleClr>();
  187. imghandler.RemoveBGAndGetParts(this, pImgProcessParam, ref allParts);
  188. var specialPartsparam = pMsrParam.GetImageProcessParam().GetSpecialGreyRangeParam();
  189. if (specialPartsparam != null && specialPartsparam.GetIsToRun())
  190. {
  191. List<CSpecialGrayRange> ranges = specialPartsparam.GetSpecialGreyRanges();
  192. List<COTSParticleClr> allgreyRngParts = new List<COTSParticleClr>();
  193. foreach (var grayRange in ranges)
  194. {
  195. CIntRangeClr range = new CIntRangeClr(grayRange.range.GetStart(), grayRange.range.GetEnd());
  196. CDoubleRangeClr diaRange = new CDoubleRangeClr(grayRange.diameterRange.GetStart(), grayRange.diameterRange.GetEnd());
  197. var pixelSize = this.GetPixelSize();
  198. List<COTSParticleClr> specialParts = new List<COTSParticleClr>();
  199. imghandler.GetParticlesBySpecialGray(m_pBSEImg, range, diaRange, pixelSize, ref specialParts);
  200. foreach (var p in specialParts)
  201. {
  202. p.SetIsXrayParticle(grayRange.ifCollectXray);
  203. allgreyRngParts.Add(p);
  204. }
  205. }
  206. allParts.AddRange(allgreyRngParts);
  207. }
  208. List<COTSParticleClr> m_listInnerParticles= new List<COTSParticleClr>();
  209. for(var i = 0; i < allParts.Count; i++)
  210. {
  211. var part = allParts[i];
  212. int l = 0, r = 0, t = 0, b = 0;
  213. part.GetOTSRect(ref l, ref t, ref r, ref b);
  214. COTSRect otsrec = new COTSRect(l, t, r, b);
  215. PointF p1 = otsrec.GetCenterPoint();
  216. if (m_sample.IsThisPointInMeasureArea(new Point((int)p1.X, (int)p1.Y)))
  217. {
  218. m_listInnerParticles.Add(allParts[i]);
  219. }
  220. }
  221. m_listInitialParticles=m_listInnerParticles;
  222. log.Info("Find all particle num:" + GetInitialParticles().Count);
  223. return;
  224. }
  225. class particleCompOnArea : IComparer<COTSParticleClr>
  226. {
  227. public int Compare(COTSParticleClr x, COTSParticleClr y)
  228. {
  229. return y.GetActualArea().CompareTo(x.GetActualArea());//descending sort
  230. }
  231. }
  232. public void FilterParticles(COTSXRayParam pXRayParam)
  233. {
  234. log.Info("filter particle according to xraylimit and outermost border");
  235. m_listInitialParticles.Sort(new particleCompOnArea());
  236. var listXray1 = new List<COTSParticleClr>();
  237. if (m_listInitialParticles.Count > pXRayParam.GetXrayLimit())
  238. {
  239. for (var i = 0; i < pXRayParam.GetXrayLimit(); i++)
  240. {
  241. listXray1.Add(m_listInitialParticles[i]);
  242. }
  243. }
  244. else
  245. {
  246. foreach (var p in m_listInitialParticles)
  247. {
  248. listXray1.Add(p);
  249. }
  250. }
  251. SetListAnalysisParticles(listXray1);
  252. log.Info("Xray Analysis particles:" + listXray1.Count);
  253. }
  254. public void SelectParticlesAccordingImgProp(COTSImageProcParam a_pImageProcessParam)
  255. {
  256. var selconditiondic = a_pImageProcessParam.GetParticleSelConditionDic();
  257. var listselparts = new List<COTSParticleClr>();
  258. var excludeparts = new List<COTSParticleClr>();
  259. if (selconditiondic.ContainsKey("dmax"))
  260. {
  261. log.Info("Select particles according to dmax");
  262. var rng = selconditiondic["dmax"];
  263. foreach (var p in GetListAnalysisParticles())
  264. {
  265. if (p.GetDMAX() < rng.GetStart() || p.GetDMAX() >= rng.GetEnd())
  266. {
  267. excludeparts.Add(p);
  268. }
  269. else
  270. {
  271. //log.Info("dmax=" + p.GetDMAX().ToString("F2"));
  272. }
  273. }
  274. }
  275. if (selconditiondic.ContainsKey("dmin"))
  276. {
  277. log.Info("Select particles according to dmin");
  278. var rng = selconditiondic["dmin"];
  279. foreach (var p in GetListAnalysisParticles())
  280. {
  281. if (p.GetDMIN() < rng.GetStart() || p.GetDMIN() >= rng.GetEnd())
  282. {
  283. if (!excludeparts.Contains(p))
  284. {
  285. excludeparts.Add(p);
  286. }
  287. else
  288. {
  289. //log.Info("dmin=" + p.GetDMIN().ToString("F2"));
  290. }
  291. }
  292. }
  293. }
  294. if (selconditiondic.ContainsKey("orientation"))
  295. {
  296. log.Info("Select particles according to orientation");
  297. var rng = selconditiondic["orientation"];
  298. foreach (var p in GetListAnalysisParticles())
  299. {
  300. if (p.GetORIENTATION() < rng.GetStart() || p.GetORIENTATION() >= rng.GetEnd())
  301. {
  302. if (!excludeparts.Contains(p))
  303. {
  304. excludeparts.Add(p);
  305. }
  306. else
  307. {
  308. //log.Info("orientation=" + p.GetORIENTATION().ToString("F2"));
  309. }
  310. }
  311. }
  312. }
  313. if (selconditiondic.ContainsKey("aspect"))
  314. {
  315. log.Info("Select particles according to aspect");
  316. var rng = selconditiondic["aspect"];
  317. foreach (var p in GetListAnalysisParticles())
  318. {
  319. double aspect = p.GetDMAX() / p.GetDMIN();
  320. if (aspect < rng.GetStart() || aspect >= rng.GetEnd())
  321. {
  322. if (!excludeparts.Contains(p))
  323. {
  324. excludeparts.Add(p);
  325. }
  326. else
  327. {
  328. //log.Info("aspect=" + aspect.ToString("F2"));
  329. }
  330. }
  331. }
  332. }
  333. if (selconditiondic.ContainsKey("ferret"))
  334. {
  335. log.Info("Select particles according to ferret");
  336. var rng = selconditiondic["ferret"];
  337. foreach (var p in GetListAnalysisParticles())
  338. {
  339. double dferet = p.GetFeretDiameter();
  340. if (dferet < rng.GetStart() || dferet >= rng.GetEnd())
  341. {
  342. if (!excludeparts.Contains(p))
  343. {
  344. excludeparts.Add(p);
  345. }
  346. else
  347. {
  348. //log.Info("ferret=" + dferet.ToString("F2"));
  349. }
  350. }
  351. }
  352. }
  353. foreach (var p in GetListAnalysisParticles())
  354. {
  355. if (!excludeparts.Contains(p))
  356. {
  357. listselparts.Add(p);
  358. }
  359. }
  360. SetListAnalysisParticles(listselparts);
  361. log.Info("Analysis particles:" + listselparts.Count);
  362. }
  363. public void RemoveDuplicateOverlapParticles(int overlap)
  364. {
  365. List<COTSParticleClr> finalparts = new List<COTSParticleClr>();
  366. List<COTSParticleClr> duplicateparts = new List<COTSParticleClr>();
  367. //find left side duplicate particles
  368. var leftparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  369. if (leftField != null && leftField.measureSequence < this.measureSequence)
  370. {
  371. var rightsideparts = leftField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  372. if (leftField.upField != null && leftField.upField.measureSequence < this.measureSequence)//include the left up corner parts
  373. {
  374. var leftupParts = leftField.upField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  375. rightsideparts.AddRange(leftupParts);
  376. }
  377. if (leftField.downField != null && leftField.downField.measureSequence < this.measureSequence)//include the left down corner parts
  378. {
  379. var leftdownParts = leftField.downField.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  380. rightsideparts.AddRange(leftdownParts);
  381. }
  382. log.Info("left side particles num:" + leftparts.Count.ToString());
  383. foreach (var p in leftparts)
  384. {
  385. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  386. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  387. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  388. PointF pcenter = prec.GetCenterPoint();
  389. foreach (var p1 in rightsideparts)
  390. {
  391. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  392. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  393. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  394. PointF p1Center = p1rec.GetCenterPoint();
  395. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  396. {
  397. var sim = p.CalculateSimilarity(p1);
  398. if (sim > 0.95)
  399. {
  400. log.Warn("remove left side duplicate particle,similarity:" + sim.ToString("F3"));
  401. log.Warn("P1:" + p.GetImgPortraitString());
  402. log.Warn("P2:" + p1.GetImgPortraitString());
  403. duplicateparts.Add(p);
  404. break;
  405. }
  406. }
  407. }
  408. }
  409. }
  410. //find up side duplicate particles
  411. var upparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
  412. if (upField != null && upField.measureSequence < this.measureSequence)
  413. {
  414. var othersideparts = upField.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
  415. log.Info("up side particles num:" + upparts.Count.ToString());
  416. foreach (var p in upparts)
  417. {
  418. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  419. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  420. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  421. PointF pcenter = prec.GetCenterPoint();
  422. foreach (var p1 in othersideparts)
  423. {
  424. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  425. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  426. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  427. PointF p1Center = p1rec.GetCenterPoint();
  428. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  429. {
  430. var sim = p.CalculateSimilarity(p1);
  431. if (sim > 0.95)
  432. {
  433. log.Warn("remove upside duplicate particle,similarity:" + sim.ToString("F3"));
  434. log.Warn("P1:" + p.GetImgPortraitString());
  435. log.Warn("P2:" + p1.GetImgPortraitString());
  436. duplicateparts.Add(p);
  437. break;
  438. }
  439. }
  440. }
  441. }
  442. }
  443. //find right side duplicate particles
  444. var rightparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.RIGHT, overlap);
  445. if (rightField != null && rightField.measureSequence < this.measureSequence)
  446. {
  447. log.Info("right side particles num:" + rightparts.Count.ToString());
  448. var othersideparts = rightField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  449. if (rightField.upField != null && rightField.upField.measureSequence < this.measureSequence)// right up corner parts
  450. {
  451. var rightupParts = rightField.upField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  452. othersideparts.AddRange(rightupParts);
  453. }
  454. if (rightField.downField != null && leftField.downField.measureSequence < this.measureSequence)// rightdown corner parts
  455. {
  456. var rightdownParts = leftField.downField.GetSideParticlesByOverlap(SORTING_DIRECTION.LEFT, overlap);
  457. othersideparts.AddRange(rightdownParts);
  458. }
  459. foreach (var p in rightparts)
  460. {
  461. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  462. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  463. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  464. PointF pcenter = prec.GetCenterPoint();
  465. foreach (var p1 in othersideparts)
  466. {
  467. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  468. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  469. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  470. PointF p1Center = p1rec.GetCenterPoint();
  471. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  472. {
  473. var sim = p.CalculateSimilarity(p1);
  474. if (sim > 0.95)
  475. {
  476. log.Warn("remove right side duplicate particle,similarity:" + sim.ToString("F3"));
  477. log.Warn("P1:" + p.GetImgPortraitString());
  478. log.Warn("P2:" + p1.GetImgPortraitString());
  479. duplicateparts.Add(p);
  480. break;
  481. }
  482. }
  483. }
  484. }
  485. }
  486. //find down side duplicate particles
  487. var downparts = this.GetSideParticlesByOverlap(SORTING_DIRECTION.DOWN, overlap);
  488. if (downField != null && downField.measureSequence < this.measureSequence)
  489. {
  490. log.Info("down side particles num:" + downparts.Count.ToString());
  491. var othersideparts = downField.GetSideParticlesByOverlap(SORTING_DIRECTION.UP, overlap);
  492. foreach (var p in downparts)
  493. {
  494. int pleft = 0, pright = 0, ptop = 0, pbottom = 0;
  495. p.GetOTSRect(ref pleft, ref ptop, ref pright, ref pbottom);
  496. COTSRect prec = new COTSRect(pleft, ptop, pright, pbottom);
  497. PointF pcenter = prec.GetCenterPoint();
  498. foreach (var p1 in othersideparts)
  499. {
  500. int p1left = 0, p1right = 0, p1top = 0, p1bottom = 0;
  501. p1.GetOTSRect(ref p1left, ref p1top, ref p1right, ref p1bottom);
  502. COTSRect p1rec = new COTSRect(p1left, p1top, p1right, p1bottom);
  503. PointF p1Center = p1rec.GetCenterPoint();
  504. if (Math.Abs(pcenter.X - p1Center.X) < 2 * overlap && Math.Abs(pcenter.Y - p1Center.Y) < 2 * overlap)
  505. {
  506. var sim = p.CalculateSimilarity(p1);
  507. if (sim > 0.95)
  508. {
  509. log.Warn("remove down side duplicate particle,similarity:" + sim.ToString("F3"));
  510. log.Warn("P1:" + p.GetImgPortraitString());
  511. log.Warn("P2:" + p1.GetImgPortraitString());
  512. duplicateparts.Add(p);
  513. break;
  514. }
  515. }
  516. }
  517. }
  518. }
  519. foreach (var p in leftparts)
  520. {
  521. if (duplicateparts.Contains(p))
  522. {
  523. continue;
  524. }
  525. if (!finalparts.Contains(p))
  526. {
  527. finalparts.Add(p);
  528. }
  529. }
  530. foreach (var p in upparts)
  531. {
  532. if (duplicateparts.Contains(p))
  533. {
  534. continue;
  535. }
  536. if (!finalparts.Contains(p))
  537. {
  538. finalparts.Add(p);
  539. }
  540. }
  541. foreach (var p in rightparts)
  542. {
  543. if (duplicateparts.Contains(p))
  544. {
  545. continue;
  546. }
  547. if (!finalparts.Contains(p))
  548. {
  549. finalparts.Add(p);
  550. }
  551. }
  552. foreach (var p in downparts)
  553. {
  554. if (duplicateparts.Contains(p))
  555. {
  556. continue;
  557. }
  558. if (!finalparts.Contains(p))
  559. {
  560. finalparts.Add(p);
  561. }
  562. }
  563. foreach (var p in this.GetSideParticlesByOverlap(SORTING_DIRECTION.CENTER, overlap))
  564. {
  565. if (!finalparts.Contains(p))
  566. {
  567. finalparts.Add(p);
  568. }
  569. }
  570. this.SetListAnalysisParticles(finalparts);
  571. log.Info("removing duplicate particles result:" + finalparts.Count);
  572. }
  573. private List<COTSParticleClr> GetSideParticlesByOverlap(SORTING_DIRECTION direction, int overlap)
  574. {
  575. List<COTSParticleClr> sideparts = new List<COTSParticleClr>();
  576. var borderedparts = this.GetBorderedParticles();
  577. if (direction == SORTING_DIRECTION.LEFT)
  578. {
  579. foreach (var p in this.GetListAnalysisParticles())
  580. {
  581. int left = 0, top = 0, right = 0, bottom = 0;
  582. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  583. if (Math.Abs(right - this.GetOTSRect().GetTopLeft().X) < 2 * overlap)
  584. {
  585. if (!borderedparts.Contains(p) || Math.Abs(left - right) > 2 * overlap)//not on the border or it's a big particle
  586. {
  587. sideparts.Add(p);
  588. }
  589. }
  590. }
  591. }
  592. if (direction == SORTING_DIRECTION.RIGHT)
  593. {
  594. foreach (var p in this.GetListAnalysisParticles())
  595. {
  596. int left = 0, top = 0, right = 0, bottom = 0;
  597. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  598. if (Math.Abs(this.GetOTSRect().GetBottomRight().X - left) < 2 * overlap)
  599. {
  600. if (!borderedparts.Contains(p) || Math.Abs(left - right) > 2 * overlap)//not on the border or is a big part
  601. {
  602. sideparts.Add(p);
  603. }
  604. }
  605. }
  606. }
  607. if (direction == SORTING_DIRECTION.UP)
  608. {
  609. foreach (var p in this.GetListAnalysisParticles())
  610. {
  611. int left = 0, top = 0, right = 0, bottom = 0;
  612. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  613. if (Math.Abs(this.GetOTSRect().GetTopLeft().Y - bottom) < 2 * overlap)
  614. {
  615. if (!borderedparts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
  616. {
  617. sideparts.Add(p);
  618. }
  619. }
  620. }
  621. }
  622. if (direction == SORTING_DIRECTION.DOWN)
  623. {
  624. foreach (var p in this.GetListAnalysisParticles())
  625. {
  626. int left = 0, top = 0, right = 0, bottom = 0;
  627. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  628. if (Math.Abs(top - this.GetOTSRect().GetBottomRight().Y) < 2 * overlap)
  629. {
  630. if (!borderedparts.Contains(p) || Math.Abs(top - bottom) > 2 * overlap)//not on the border
  631. {
  632. sideparts.Add(p);
  633. }
  634. }
  635. }
  636. }
  637. if (direction == SORTING_DIRECTION.CENTER)
  638. {
  639. foreach (var p in this.GetListAnalysisParticles())
  640. {
  641. int left = 0, top = 0, right = 0, bottom = 0;
  642. p.GetOTSRect(ref left, ref top, ref right, ref bottom);
  643. var fldrec = this.GetOTSRect();
  644. int fldleft = (int)fldrec.GetTopLeft().X;
  645. int fldright = (int)fldrec.GetBottomRight().X;
  646. int fldtop = (int)fldrec.GetTopLeft().Y;
  647. int fldbottom = (int)fldrec.GetBottomRight().Y;
  648. if ((Math.Abs(top - fldtop) > 2 * overlap) && (Math.Abs(fldbottom - bottom) > 2 * overlap) && (Math.Abs(left - fldleft) > 2 * overlap) && (Math.Abs(fldright - right) > 2 * overlap))
  649. {
  650. sideparts.Add(p);
  651. }
  652. }
  653. }
  654. return sideparts;
  655. }
  656. public void GetPartsBySpecialGray(CIntRangeClr grayRange, CDoubleRangeClr diameterRange, double pixelSize, bool ifXray)
  657. {
  658. if (m_pBSEImg == null)
  659. return;
  660. CImageHandler imghandler = new CImageHandler();
  661. List<COTSParticleClr> specialParts = new List<COTSParticleClr>();
  662. imghandler.GetParticlesBySpecialGray(m_pBSEImg, grayRange, diameterRange, pixelSize, ref specialParts);
  663. foreach (var p in specialParts)
  664. {
  665. p.SetIsXrayParticle(ifXray);
  666. m_listInitialParticles.Add(p);
  667. }
  668. return;
  669. }
  670. public bool CalParticleImageProp(List<COTSParticleClr> particles)
  671. {
  672. m_ImagePro = new CImageHandler();
  673. foreach (COTSParticleClr part in particles)
  674. {
  675. m_ImagePro.CalParticleImageProp(part, m_pixelSize);
  676. }
  677. return true;
  678. }
  679. public void CalculateParticleFieldSEMPosAndOTSPos(CSEMStageData pCSEMStageData)
  680. {
  681. foreach (var p in GetListAnalysisParticles())
  682. {
  683. PointF semP = new PointF(); ;
  684. Point semPos = new Point();
  685. pCSEMStageData.ConvertOTSToSEMCoord(GetOTSPosition(), ref semP);
  686. semPos.X = (int)semP.X;
  687. semPos.Y = (int)semP.Y;
  688. p.SetSEMPos(semPos);
  689. var otspos = GetOTSPosition();
  690. p.SetFieldOTSPos(new Point((int)otspos.X,(int)otspos.Y));
  691. }
  692. }
  693. public void InitParticles(COTSImageProcParam a_pImageProcessParam)
  694. {
  695. // get area range
  696. CDoubleRange oAreaRange = a_pImageProcessParam.GetIncAreaRange();
  697. double rMin = oAreaRange.GetStart() / 2.0;
  698. double rMax = oAreaRange.GetEnd() / 2.0;
  699. int nTagId = 0;
  700. foreach (COTSParticleClr pParticle in m_listInitialParticles)//m_listAllParticles memorize all the particles .
  701. {
  702. pParticle.SetParticleId(nTagId);//give all the conforming particles a unified sequence no.
  703. pParticle.SetFieldId(GetId());
  704. pParticle.SetBasicClassifyId((int)otsdataconst.OTS_PARTICLE_TYPE.NO_ANALYSIS_X_RAY);
  705. pParticle.SetTypeName("Not Identified");
  706. pParticle.SetAnalysisId(nTagId); // the same as the tagId no use now.
  707. nTagId++;
  708. }
  709. log.Info("Total analysis Particles: (>" + rMin.ToString("f2") + "): " + "<" + rMax.ToString("f2") + "): " + m_listAnalysisParticles.Count);
  710. }
  711. public bool CreateXrayList(List<COTSParticleClr> a_listParticles)
  712. {
  713. foreach (COTSParticleClr pPart in a_listParticles)
  714. {
  715. System.Drawing.Point poi = (System.Drawing.Point)pPart.GetXRayPos();
  716. CPosXrayClr pPosXray = new CPosXrayClr();
  717. pPosXray.SetPosition(poi);
  718. pPosXray.SetPartTagId(pPart.GetParticleId());
  719. pPosXray.SetIndex(pPart.GetAnalysisId());
  720. pPosXray.SetScanFieldId(pPart.GetFieldId());
  721. pPart.SetXray(pPosXray);
  722. }
  723. return true;
  724. }
  725. public void ClearAllMeausredData()
  726. {
  727. m_listInitialParticles.Clear();
  728. m_listAnalysisParticles.Clear();
  729. m_pBSEImg = null;
  730. }
  731. public bool PositionEquals(COTSField a_oSource)
  732. {
  733. if (a_oSource.m_otsPos == this.m_otsPos)
  734. {
  735. return true;
  736. }
  737. else
  738. {
  739. return false;
  740. }
  741. }
  742. // ID
  743. public int GetId()
  744. {
  745. return m_nID;
  746. }
  747. public void SetId(int a_nID)
  748. {
  749. m_nID = a_nID;
  750. }
  751. // position (from field center manager)
  752. public System.Drawing.PointF GetOTSPosition()
  753. {
  754. return m_otsPos;
  755. }
  756. public void SetOTSPosition(System.Drawing.PointF a_poiPos)
  757. {
  758. m_otsPos = a_poiPos;
  759. }
  760. public List<COTSParticleClr> GetTopBorderedParticles()
  761. {
  762. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  763. foreach (var p in m_listAnalysisParticles)
  764. {
  765. var segs = p.GetFeature().GetSegmentsList();//COTSSegment
  766. foreach (var seg in segs)
  767. {
  768. if (seg.GetHeight() == 0)
  769. {
  770. parts.Add(p);
  771. break;
  772. }
  773. }
  774. }
  775. return parts;
  776. }
  777. public List<COTSParticleClr> GetBottomBorderedParticles()
  778. {
  779. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  780. foreach (var p in m_listAnalysisParticles)
  781. {
  782. var segs = p.GetFeature().GetSegmentsList();
  783. foreach (var seg in segs)
  784. {
  785. if (seg.GetHeight() == this.ImgHeight - 1)//the lowest height is 767(height-1),cause starting from 0.
  786. {
  787. parts.Add(p);
  788. break;
  789. }
  790. }
  791. }
  792. return parts;
  793. }
  794. public List<COTSParticleClr> GetBorderedParticles()
  795. {
  796. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  797. var leftparts = this.GetLeftBorderedParticles();
  798. var rightp = this.GetRightBorderedParticles();
  799. var topp = this.GetTopBorderedParticles();
  800. var bottomp = this.GetBottomBorderedParticles();
  801. foreach (var p in leftparts)
  802. {
  803. if (!parts.Contains(p))
  804. {
  805. parts.Add(p);
  806. }
  807. }
  808. foreach (var p in rightp)//
  809. {
  810. if (!parts.Contains(p))
  811. {
  812. parts.Add(p);
  813. }
  814. }
  815. foreach (var p in topp)
  816. {
  817. if (!parts.Contains(p))//there may be some particles connect to both the left and top.
  818. {
  819. parts.Add(p);
  820. }
  821. }
  822. foreach (var p in bottomp)
  823. {
  824. if (!parts.Contains(p))
  825. {
  826. parts.Add(p);
  827. }
  828. }
  829. return parts;
  830. }
  831. public List<COTSParticleClr> GetLeftBorderedParticles()
  832. {
  833. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  834. foreach (var p in m_listAnalysisParticles)
  835. {
  836. var segs = p.GetFeature().GetSegmentsList();
  837. foreach (var seg in segs)
  838. {
  839. if (seg.GetStart() == 0)
  840. {
  841. parts.Add(p);
  842. break;
  843. }
  844. }
  845. }
  846. return parts;
  847. }
  848. public List<COTSParticleClr> GetRightBorderedParticles()
  849. {
  850. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  851. foreach (var p in m_listAnalysisParticles)
  852. {
  853. var segs = p.GetFeature().GetSegmentsList();
  854. foreach (var seg in segs)
  855. {
  856. if (seg.GetStart() + seg.GetLength() == this.ImgWidth)
  857. {
  858. parts.Add(p);
  859. break;
  860. }
  861. }
  862. }
  863. return parts;
  864. }
  865. // is empty
  866. public bool IsEmpty()
  867. {
  868. return m_listInitialParticles.Count == 0;
  869. }
  870. void Duplicate(COTSField a_oSource)
  871. {
  872. m_nID = a_oSource.m_nID;
  873. m_otsPos = a_oSource.m_otsPos;
  874. // copy data over
  875. foreach (var pParticle in a_oSource.m_listInitialParticles)
  876. {
  877. m_listInitialParticles.Add(pParticle);
  878. }
  879. }
  880. public override void Serialize(bool isStoring, XmlDocument classDoc, XmlNode rootNode)
  881. {
  882. xPoint xPos = new xPoint();
  883. xBool xenable = new xBool();
  884. Slo slo = new Slo();
  885. slo.Register("OTSPosition", xPos);
  886. slo.Register("Enable", xenable);
  887. if (isStoring)
  888. {
  889. xPos.AssignValue(new System.Drawing.Point((int)m_otsPos.X, (int)m_otsPos.Y));
  890. xenable.AssignValue(this.Enable);
  891. slo.Serialize(true, classDoc, rootNode);
  892. }
  893. else
  894. {
  895. slo.Serialize(false, classDoc, rootNode);
  896. m_otsPos = xPos.value();
  897. this.Enable=xenable.value();
  898. }
  899. }
  900. }
  901. }