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