COTSField.cs 38 KB

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