SmplMeasureInclution.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. using OTSCLRINTERFACE;
  2. using OTSCommon.DBOperate.Model;
  3. using OTSDataType;
  4. using OTSMeasureApp._0_OTSModel.OTSDataType;
  5. using OTSModelSharp.ServiceCenter;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Drawing;
  9. using System.Linq;
  10. using static OTSDataType.otsdataconst;
  11. namespace OTSModelSharp
  12. {
  13. class CSmplMeasureIncA : CSmplMeasure
  14. {
  15. public CSmplMeasureIncA(string a_strWorkingFolder, COTSSample a_pSample) : base(a_strWorkingFolder, a_pSample)
  16. {
  17. SetWorkingFolder(a_strWorkingFolder);
  18. SetSample(a_pSample);
  19. m_classifyEngine = new CClassifyEngine();
  20. }
  21. public override void ClassifyFieldParticles(COTSField curFldData)
  22. {
  23. try
  24. {
  25. var anylysisparts = curFldData.GetListAnalysisParticles();
  26. int nSize = anylysisparts.Count();
  27. // go through all analysis particles
  28. for (int i = 0; i < nSize; ++i)
  29. {
  30. string libname = m_Sample.GetMsrParams().GetSTDName();
  31. if (!IsLowCounts(anylysisparts[i]))
  32. {
  33. ClassifyIncAParticle(anylysisparts[i], libname);
  34. }
  35. }
  36. }
  37. catch (Exception e)
  38. {
  39. log.Info(" classify failed. " + e.Message);
  40. }
  41. }
  42. public bool ClassifyIncAParticle(COTSParticleClr particle, string libname)// classify particles
  43. {
  44. int steelTech = (int)m_Sample.GetMsrParams().GetSteelTechnology();
  45. particle.SetType((int)OTS_PARTICLE_TYPE.NOT_IDENTIFIED);
  46. if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.InclutionPlusExpressionParse)
  47. {
  48. if (libname != "NoSTDDB")
  49. {
  50. //var m_classifyEngine = new CClassifyEngine();
  51. IClassifyEngine engine = m_classifyEngine.GetExpressionClassifyEngine(libname);
  52. engine.ClassifyByExpression(particle);
  53. }
  54. if (particle.GetType() == (int)OTS_PARTICLE_TYPE.NOT_IDENTIFIED || particle.GetType() == (int)OTS_PARTICLE_TYPE.UNCLASSIFY)
  55. {
  56. IClassifyEngine engine;
  57. engine = m_classifyEngine.GetIncClassifyEngine();
  58. engine.ClassifyIncA(particle, steelTech);
  59. }
  60. }
  61. else if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.ExpressionParse)
  62. {
  63. if (libname != "NoSTDDB")
  64. {
  65. //var m_classifyEngine = new CClassifyEngine();
  66. IClassifyEngine engine = m_classifyEngine.GetExpressionClassifyEngine(libname);
  67. engine.ClassifyByExpression(particle);
  68. }
  69. }
  70. else if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.SpectrumMatch)
  71. {
  72. if (libname != "NoSTDDB")
  73. {
  74. //var m_classifyEngine = new CClassifyEngine();
  75. IClassifyEngine engine = m_classifyEngine.GetSpectrumCompareEngine(libname);
  76. engine.ClassifyBySpectrum(particle);
  77. }
  78. }
  79. else if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.InclustionEngine)
  80. {
  81. IClassifyEngine engine;
  82. engine = m_classifyEngine.GetIncClassifyEngine();
  83. engine.ClassifyIncA(particle, steelTech);
  84. }
  85. return true;
  86. }
  87. public override void CollectParticlesXrayData(COTSField curFldData)
  88. {
  89. LinkParticlesByGB30834Standard(curFldData);
  90. //collect the particles xray data
  91. base.CollectParticlesXrayData(curFldData);
  92. var parts = curFldData.GetListAnalysisParticles();
  93. string libname = m_Sample.GetMsrParams().GetSTDName();
  94. //process the maxeds rules
  95. if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.InclutionPlusExpressionParse ||
  96. m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.ExpressionParse)
  97. {
  98. if (libname != "NoSTDDB")
  99. {
  100. IClassifyEngine engine = m_classifyEngine.GetExpressionClassifyEngine(libname);
  101. double maxedstime = 0;
  102. List<COTSParticleClr> maxedsparts = new List<COTSParticleClr>();
  103. foreach (var p in parts)
  104. {
  105. if (engine.IfNeedMaxEDS(p, ref maxedstime))
  106. {
  107. maxedsparts.Add(p);
  108. }
  109. }
  110. if (maxedsparts.Count > 0)
  111. {
  112. log.Warn("Begin to collect MaxEDS particles:" + maxedsparts.Count + "(" + maxedstime.ToString() + ") on Point mode");
  113. m_EDSController.GetXRayByParts(maxedsparts, (uint)maxedstime, true);
  114. }
  115. }
  116. }
  117. }
  118. class COTSLinkedParticle
  119. {
  120. public COTSLinkedParticle(COTSParticleClr mypart)
  121. {
  122. _myPart = mypart;
  123. }
  124. private bool _merged=false;
  125. private COTSParticleClr _myPart;
  126. private List<COTSLinkedParticle> _linkedParts = new List<COTSLinkedParticle>();
  127. public void AddLinkedParticle(COTSLinkedParticle part)
  128. {
  129. if (!_linkedParts.Contains(part))
  130. {
  131. _linkedParts.Add(part);
  132. }
  133. }
  134. public List<COTSLinkedParticle> GetLinkedParticles() { return _linkedParts; }
  135. public COTSParticleClr MyPart { get => _myPart; set => _myPart = value; }
  136. public bool IsMerged { get => _merged; set => _merged = value; }
  137. internal void MergeLinkedParticles()
  138. {
  139. List<COTSSegmentClr > segs= new List<COTSSegmentClr>();
  140. int l=0, t=0, r=0, b = 0;
  141. foreach (var seg in _myPart.GetFeature().GetSegmentsList())
  142. {
  143. segs.Add(seg);
  144. }
  145. _myPart.GetOTSRect(ref l, ref t, ref r, ref b);
  146. Rectangle rec =(Rectangle)_myPart.GetParticleRect();
  147. int l1 = 0, t1 = 0, r1 = 0, b1 = 0;
  148. COTSParticleClr biggestPart = _myPart;
  149. foreach (var p in _linkedParts)
  150. {
  151. p.MyPart.GetOTSRect(ref l1,ref t1, ref r1, ref b1);
  152. if (l1 < l) l = l1;
  153. if(t1 > t) t = t1;
  154. if(r1 > r) r = r1;
  155. if (b1 < b) b = b1;
  156. if(p.MyPart.GetActualArea() > biggestPart.GetActualArea())
  157. {
  158. biggestPart = p.MyPart;
  159. }
  160. foreach (var seg in p.MyPart.GetFeature().GetSegmentsList())
  161. {
  162. if (!segs.Contains(seg))
  163. {
  164. segs.Add(seg);
  165. }
  166. }
  167. }
  168. _myPart.SetOTSRect(l, t, r, b);
  169. _myPart.GetFeature().SetSegmentsList(segs,true);
  170. _myPart.CalCoverRectFromSegment();
  171. _myPart.SetXRayPos(biggestPart.GetXRayPos());
  172. }
  173. }
  174. private void LinkParticlesByGB30834Standard(COTSField curFldData)
  175. {
  176. var parts = curFldData.GetAllParticles();
  177. if (parts.Count == 0)
  178. {
  179. return;
  180. }
  181. List<COTSLinkedParticle> linkedParticles = new List<COTSLinkedParticle>();
  182. foreach (var part in parts)
  183. {
  184. COTSLinkedParticle linkedParticle = new COTSLinkedParticle(part);
  185. linkedParticles.Add(linkedParticle);
  186. }
  187. for (int i = 0; i < linkedParticles.Count; i++)
  188. {
  189. var part = linkedParticles[i];
  190. int l = 0, r = 0, t = 0, b = 0;
  191. part.MyPart.GetOTSRect(ref l, ref t, ref r, ref b);
  192. COTSRect partrect = new COTSRect(l, t, r, b);
  193. //PointF centerPoint = partrect.GetCenterPoint();
  194. Point centerPoint =(Point) part.MyPart.GetXRayPos();
  195. for (int j = i + 1; j < linkedParticles.Count; j++)
  196. {
  197. var part1 = linkedParticles[j];
  198. part1.MyPart.GetOTSRect(ref l, ref t, ref r, ref b);
  199. COTSRect partrect1 = new COTSRect(l, t, r, b);
  200. //PointF centerPoint1 = partrect1.GetCenterPoint();
  201. Point centerPoint1 = (Point)part1.MyPart.GetXRayPos();
  202. double d = Math.Sqrt(Math.Pow(centerPoint.X - centerPoint1.X, 2) + Math.Pow(centerPoint.Y - centerPoint1.Y, 2));
  203. if (Math.Abs(part.MyPart.GetAveGray() - part1.MyPart.GetAveGray()) > 10 )
  204. {
  205. // If the average gray values are not similar, do not link them
  206. continue;
  207. }
  208. if (d - part.MyPart.GetDMAX() / 2 - part1.MyPart.GetDMAX() / 2 < 40 && d > part.MyPart.GetDMAX() / 2+part1.MyPart.GetDMAX()/2)
  209. {
  210. double aspect1 = part.MyPart.GetDMAX() / part.MyPart.GetDMIN();
  211. double aspect2 = part1.MyPart.GetDMAX() / part.MyPart.GetDMIN();
  212. var angle1 = part.MyPart.GetORIENTATION();
  213. var angle2= part1.MyPart.GetORIENTATION();
  214. if (aspect1 > 2 && aspect2 > 2)
  215. {
  216. // If the aspect ratio of both particles is greater than 2 and their orientations are similar, link them
  217. var angle = calculateTwoPointAngle(centerPoint, centerPoint1);
  218. if (Math.Abs(angle - angle1) < 5 && Math.Abs(angle - angle2) < 5)
  219. {
  220. part.AddLinkedParticle(part1);
  221. part1.AddLinkedParticle(part);
  222. continue;
  223. }
  224. else
  225. {
  226. continue;
  227. }
  228. }
  229. else if (aspect1 > 2 && aspect2 < 2)
  230. {
  231. var angle = calculateTwoPointAngle(centerPoint, centerPoint1);
  232. if (Math.Abs(angle - angle1) < 5)
  233. {
  234. part.AddLinkedParticle(part1);
  235. part1.AddLinkedParticle(part);
  236. continue;
  237. }
  238. else
  239. {
  240. continue;
  241. }
  242. }
  243. else if (aspect1 < 2 && aspect2 > 2)
  244. {
  245. var angle = calculateTwoPointAngle(centerPoint, centerPoint1);
  246. if (Math.Abs(angle - angle2) < 5)
  247. {
  248. part.AddLinkedParticle(part1);
  249. part1.AddLinkedParticle(part);
  250. continue;
  251. }
  252. else
  253. {
  254. continue;
  255. }
  256. }
  257. else if (aspect1 <= 2 && aspect2 <=2)
  258. {
  259. if (Math.Abs(part.MyPart.GetActualArea() - part1.MyPart.GetActualArea()) < 10)
  260. {
  261. // Link the particles
  262. part.AddLinkedParticle(part1);
  263. part1.AddLinkedParticle(part);
  264. continue;
  265. }
  266. else
  267. {
  268. // If the areas are not similar, do not link them
  269. continue;
  270. }
  271. }
  272. }
  273. }
  274. }
  275. //DFS all the linked particles
  276. Stack<COTSLinkedParticle> partStack=new Stack<COTSLinkedParticle>();
  277. List<COTSParticleClr> mergedParts = new List<COTSParticleClr>();
  278. List<COTSParticleClr> finalOTSParts = new List<COTSParticleClr>();
  279. foreach (var pParticle in linkedParticles)
  280. {
  281. if (!pParticle.IsMerged)
  282. {
  283. COTSLinkedParticle finalpart = new COTSLinkedParticle(pParticle.MyPart);
  284. foreach (var connP in pParticle.GetLinkedParticles())
  285. {
  286. if (!connP.IsMerged)
  287. {
  288. partStack.Push(connP);
  289. }
  290. }
  291. while (partStack.Count > 0)
  292. {
  293. COTSLinkedParticle currpart = partStack.Pop();
  294. currpart.IsMerged = true;
  295. finalpart.AddLinkedParticle(currpart);
  296. if (currpart.GetLinkedParticles().Count>0)
  297. {
  298. foreach (var connP in currpart.GetLinkedParticles())
  299. {
  300. if (!connP.IsMerged)
  301. {
  302. partStack.Push(connP);
  303. }
  304. }
  305. }
  306. }
  307. if (finalpart.GetLinkedParticles().Count > 1)
  308. {
  309. //merge the particles
  310. finalpart.MergeLinkedParticles();
  311. mergedParts.Add(finalpart.MyPart);
  312. }
  313. else
  314. {
  315. finalOTSParts.Add(finalpart.MyPart); // If no linked particles, just add the original particle
  316. }
  317. }
  318. }
  319. curFldData.CalParticleImageProp(mergedParts);
  320. finalOTSParts.AddRange(mergedParts);
  321. curFldData.SetListAnalysisParticles(finalOTSParts);
  322. }
  323. public double calculateTwoPointAngle(PointF p1, PointF p2)
  324. {
  325. if (p1.Y > p2.Y)
  326. {
  327. PointF temp = p1;
  328. p1 = p2;
  329. p2 = temp;
  330. }
  331. double angle = Math.Atan2(p2.Y - p1.Y, p2.X - p1.X) * 180 / Math.PI;
  332. if (angle < 0)
  333. {
  334. angle += 360;
  335. }
  336. return angle;
  337. }
  338. }
  339. }