COTSField.cs 37 KB

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