COTSField.cs 37 KB

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