COTSField.cs 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  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 CalculateParticleAbsolutPos(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. }
  690. }
  691. public void InitParticles(COTSImageProcParam a_pImageProcessParam)
  692. {
  693. // get area range
  694. CDoubleRange oAreaRange = a_pImageProcessParam.GetIncAreaRange();
  695. double rMin = oAreaRange.GetStart() / 2.0;
  696. double rMax = oAreaRange.GetEnd() / 2.0;
  697. int nTagId = 0;
  698. foreach (COTSParticleClr pParticle in m_listInitialParticles)//m_listAllParticles memorize all the particles .
  699. {
  700. pParticle.SetParticleId(nTagId);//give all the conforming particles a unified sequence no.
  701. pParticle.SetFieldId(GetId());
  702. pParticle.SetType((int)otsdataconst.OTS_PARTICLE_TYPE.NO_ANALYSIS_X_RAY);
  703. pParticle.SetTypeName("Not Identified");
  704. pParticle.SetAnalysisId(nTagId); // the same as the tagId no use now.
  705. nTagId++;
  706. }
  707. log.Info("Total analysis Particles: (>" + rMin.ToString("f2") + "): " + "<" + rMax.ToString("f2") + "): " + m_listAnalysisParticles.Count);
  708. }
  709. public bool CreateXrayList(List<COTSParticleClr> a_listParticles)
  710. {
  711. foreach (COTSParticleClr pPart in a_listParticles)
  712. {
  713. System.Drawing.Point poi = (System.Drawing.Point)pPart.GetXRayPos();
  714. CPosXrayClr pPosXray = new CPosXrayClr();
  715. pPosXray.SetPosition(poi);
  716. pPosXray.SetPartTagId(pPart.GetParticleId());
  717. pPosXray.SetIndex(pPart.GetAnalysisId());
  718. pPosXray.SetScanFieldId(pPart.GetFieldId());
  719. pPart.SetXray(pPosXray);
  720. }
  721. return true;
  722. }
  723. public void ClearAllMeausredData()
  724. {
  725. m_listInitialParticles.Clear();
  726. m_listAnalysisParticles.Clear();
  727. m_pBSEImg = null;
  728. }
  729. public bool PositionEquals(COTSField a_oSource)
  730. {
  731. if (a_oSource.m_otsPos == this.m_otsPos)
  732. {
  733. return true;
  734. }
  735. else
  736. {
  737. return false;
  738. }
  739. }
  740. // ID
  741. public int GetId()
  742. {
  743. return m_nID;
  744. }
  745. public void SetId(int a_nID)
  746. {
  747. m_nID = a_nID;
  748. }
  749. // position (from field center manager)
  750. public System.Drawing.PointF GetOTSPosition()
  751. {
  752. return m_otsPos;
  753. }
  754. public void SetOTSPosition(System.Drawing.PointF a_poiPos)
  755. {
  756. m_otsPos = a_poiPos;
  757. }
  758. public List<COTSParticleClr> GetTopBorderedParticles()
  759. {
  760. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  761. foreach (var p in m_listAnalysisParticles)
  762. {
  763. var segs = p.GetFeature().GetSegmentsList();//COTSSegment
  764. foreach (var seg in segs)
  765. {
  766. if (seg.GetHeight() == 0)
  767. {
  768. parts.Add(p);
  769. break;
  770. }
  771. }
  772. }
  773. return parts;
  774. }
  775. public List<COTSParticleClr> GetBottomBorderedParticles()
  776. {
  777. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  778. foreach (var p in m_listAnalysisParticles)
  779. {
  780. var segs = p.GetFeature().GetSegmentsList();
  781. foreach (var seg in segs)
  782. {
  783. if (seg.GetHeight() == this.ImgHeight - 1)//the lowest height is 767(height-1),cause starting from 0.
  784. {
  785. parts.Add(p);
  786. break;
  787. }
  788. }
  789. }
  790. return parts;
  791. }
  792. public List<COTSParticleClr> GetBorderedParticles()
  793. {
  794. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  795. var leftparts = this.GetLeftBorderedParticles();
  796. var rightp = this.GetRightBorderedParticles();
  797. var topp = this.GetTopBorderedParticles();
  798. var bottomp = this.GetBottomBorderedParticles();
  799. foreach (var p in leftparts)
  800. {
  801. if (!parts.Contains(p))
  802. {
  803. parts.Add(p);
  804. }
  805. }
  806. foreach (var p in rightp)//
  807. {
  808. if (!parts.Contains(p))
  809. {
  810. parts.Add(p);
  811. }
  812. }
  813. foreach (var p in topp)
  814. {
  815. if (!parts.Contains(p))//there may be some particles connect to both the left and top.
  816. {
  817. parts.Add(p);
  818. }
  819. }
  820. foreach (var p in bottomp)
  821. {
  822. if (!parts.Contains(p))
  823. {
  824. parts.Add(p);
  825. }
  826. }
  827. return parts;
  828. }
  829. public List<COTSParticleClr> GetLeftBorderedParticles()
  830. {
  831. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  832. foreach (var p in m_listAnalysisParticles)
  833. {
  834. var segs = p.GetFeature().GetSegmentsList();
  835. foreach (var seg in segs)
  836. {
  837. if (seg.GetStart() == 0)
  838. {
  839. parts.Add(p);
  840. break;
  841. }
  842. }
  843. }
  844. return parts;
  845. }
  846. public List<COTSParticleClr> GetRightBorderedParticles()
  847. {
  848. List<COTSParticleClr> parts = new List<COTSParticleClr>();
  849. foreach (var p in m_listAnalysisParticles)
  850. {
  851. var segs = p.GetFeature().GetSegmentsList();
  852. foreach (var seg in segs)
  853. {
  854. if (seg.GetStart() + seg.GetLength() == this.ImgWidth)
  855. {
  856. parts.Add(p);
  857. break;
  858. }
  859. }
  860. }
  861. return parts;
  862. }
  863. // is empty
  864. public bool IsEmpty()
  865. {
  866. return m_listInitialParticles.Count == 0;
  867. }
  868. void Duplicate(COTSField a_oSource)
  869. {
  870. m_nID = a_oSource.m_nID;
  871. m_otsPos = a_oSource.m_otsPos;
  872. // copy data over
  873. foreach (var pParticle in a_oSource.m_listInitialParticles)
  874. {
  875. m_listInitialParticles.Add(pParticle);
  876. }
  877. }
  878. public override void Serialize(bool isStoring, XmlDocument classDoc, XmlNode rootNode)
  879. {
  880. xPoint xPos = new xPoint();
  881. xBool xenable = new xBool();
  882. Slo slo = new Slo();
  883. slo.Register("OTSPosition", xPos);
  884. slo.Register("Enable", xenable);
  885. if (isStoring)
  886. {
  887. xPos.AssignValue(new System.Drawing.Point((int)m_otsPos.X, (int)m_otsPos.Y));
  888. xenable.AssignValue(this.Enable);
  889. slo.Serialize(true, classDoc, rootNode);
  890. }
  891. else
  892. {
  893. slo.Serialize(false, classDoc, rootNode);
  894. m_otsPos = xPos.value();
  895. this.Enable=xenable.value();
  896. }
  897. }
  898. }
  899. }