COTSField.cs 37 KB

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