using OTSCLRINTERFACE; using OTSCommon.DBOperate.Model; using OTSDataType; using OTSMeasureApp._0_OTSModel.OTSDataType; using OTSModelSharp.ServiceCenter; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using static OTSDataType.otsdataconst; namespace OTSModelSharp { class CSmplMeasureIncA : CSmplMeasure { public CSmplMeasureIncA(string a_strWorkingFolder, COTSSample a_pSample) : base(a_strWorkingFolder, a_pSample) { SetWorkingFolder(a_strWorkingFolder); SetSample(a_pSample); m_classifyEngine = new CClassifyEngine(); } public override void ClassifyFieldParticles(COTSField curFldData) { try { var anylysisparts = curFldData.GetListAnalysisParticles(); int nSize = anylysisparts.Count(); // go through all analysis particles for (int i = 0; i < nSize; ++i) { string libname = m_Sample.GetMsrParams().GetSTDName(); if (!IsLowCounts(anylysisparts[i])) { ClassifyIncAParticle(anylysisparts[i], libname); } } } catch (Exception e) { log.Info(" classify failed. " + e.Message); } } public bool ClassifyIncAParticle(COTSParticleClr particle, string libname)// classify particles { int steelTech = (int)m_Sample.GetMsrParams().GetSteelTechnology(); particle.SetType((int)OTS_PARTICLE_TYPE.NOT_IDENTIFIED); if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.InclutionPlusExpressionParse) { if (libname != "NoSTDDB") { //var m_classifyEngine = new CClassifyEngine(); IClassifyEngine engine = m_classifyEngine.GetExpressionClassifyEngine(libname); engine.ClassifyByExpression(particle); } if (particle.GetType() == (int)OTS_PARTICLE_TYPE.NOT_IDENTIFIED || particle.GetType() == (int)OTS_PARTICLE_TYPE.UNCLASSIFY) { IClassifyEngine engine; engine = m_classifyEngine.GetIncClassifyEngine(); engine.ClassifyIncA(particle, steelTech); } } else if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.ExpressionParse) { if (libname != "NoSTDDB") { //var m_classifyEngine = new CClassifyEngine(); IClassifyEngine engine = m_classifyEngine.GetExpressionClassifyEngine(libname); engine.ClassifyByExpression(particle); } } else if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.SpectrumMatch) { if (libname != "NoSTDDB") { //var m_classifyEngine = new CClassifyEngine(); IClassifyEngine engine = m_classifyEngine.GetSpectrumCompareEngine(libname); engine.ClassifyBySpectrum(particle); } } else if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.InclustionEngine) { IClassifyEngine engine; engine = m_classifyEngine.GetIncClassifyEngine(); engine.ClassifyIncA(particle, steelTech); } return true; } public override void CollectParticlesXrayData(COTSField curFldData) { LinkParticlesByGB30834Standard(curFldData); //collect the particles xray data base.CollectParticlesXrayData(curFldData); var parts = curFldData.GetListAnalysisParticles(); string libname = m_Sample.GetMsrParams().GetSTDName(); //process the maxeds rules if (m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.InclutionPlusExpressionParse || m_Sample.GetMsrParams().GetEngineType() == OTS_CLASSIFY_ENGINE_TYPE.ExpressionParse) { if (libname != "NoSTDDB") { IClassifyEngine engine = m_classifyEngine.GetExpressionClassifyEngine(libname); double maxedstime = 0; List maxedsparts = new List(); foreach (var p in parts) { if (engine.IfNeedMaxEDS(p, ref maxedstime)) { maxedsparts.Add(p); } } if (maxedsparts.Count > 0) { log.Warn("Begin to collect MaxEDS particles:" + maxedsparts.Count + "(" + maxedstime.ToString() + ") on Point mode"); m_EDSController.GetXRayByParts(maxedsparts, (uint)maxedstime, true); } } } } class COTSLinkedParticle { public COTSLinkedParticle(COTSParticleClr mypart) { _myPart = mypart; } private bool _merged=false; private COTSParticleClr _myPart; private List _linkedParts = new List(); public void AddLinkedParticle(COTSLinkedParticle part) { if (!_linkedParts.Contains(part)) { _linkedParts.Add(part); } } public List GetLinkedParticles() { return _linkedParts; } public COTSParticleClr MyPart { get => _myPart; set => _myPart = value; } public bool IsMerged { get => _merged; set => _merged = value; } internal void MergeLinkedParticles() { List segs= new List(); int l=0, t=0, r=0, b = 0; foreach (var seg in _myPart.GetFeature().GetSegmentsList()) { segs.Add(seg); } _myPart.GetOTSRect(ref l, ref t, ref r, ref b); Rectangle rec =(Rectangle)_myPart.GetParticleRect(); int l1 = 0, t1 = 0, r1 = 0, b1 = 0; COTSParticleClr biggestPart = _myPart; foreach (var p in _linkedParts) { p.MyPart.GetOTSRect(ref l1,ref t1, ref r1, ref b1); if (l1 < l) l = l1; if(t1 > t) t = t1; if(r1 > r) r = r1; if (b1 < b) b = b1; if(p.MyPart.GetActualArea() > biggestPart.GetActualArea()) { biggestPart = p.MyPart; } foreach (var seg in p.MyPart.GetFeature().GetSegmentsList()) { if (!segs.Contains(seg)) { segs.Add(seg); } } } _myPart.SetOTSRect(l, t, r, b); _myPart.GetFeature().SetSegmentsList(segs,true); _myPart.CalCoverRectFromSegment(); _myPart.SetXRayPos(biggestPart.GetXRayPos()); } } private void LinkParticlesByGB30834Standard(COTSField curFldData) { var parts = curFldData.GetAllParticles(); if (parts.Count == 0) { return; } List linkedParticles = new List(); foreach (var part in parts) { COTSLinkedParticle linkedParticle = new COTSLinkedParticle(part); linkedParticles.Add(linkedParticle); } for (int i = 0; i < linkedParticles.Count; i++) { var part = linkedParticles[i]; int l = 0, r = 0, t = 0, b = 0; part.MyPart.GetOTSRect(ref l, ref t, ref r, ref b); COTSRect partrect = new COTSRect(l, t, r, b); //PointF centerPoint = partrect.GetCenterPoint(); Point centerPoint =(Point) part.MyPart.GetXRayPos(); for (int j = i + 1; j < linkedParticles.Count; j++) { var part1 = linkedParticles[j]; part1.MyPart.GetOTSRect(ref l, ref t, ref r, ref b); COTSRect partrect1 = new COTSRect(l, t, r, b); //PointF centerPoint1 = partrect1.GetCenterPoint(); Point centerPoint1 = (Point)part1.MyPart.GetXRayPos(); double d = Math.Sqrt(Math.Pow(centerPoint.X - centerPoint1.X, 2) + Math.Pow(centerPoint.Y - centerPoint1.Y, 2)); if (Math.Abs(part.MyPart.GetAveGray() - part1.MyPart.GetAveGray()) > 10 ) { // If the average gray values are not similar, do not link them continue; } if (d - part.MyPart.GetDMAX() / 2 - part1.MyPart.GetDMAX() / 2 < 40 && d > part.MyPart.GetDMAX() / 2+part1.MyPart.GetDMAX()/2) { double aspect1 = part.MyPart.GetDMAX() / part.MyPart.GetDMIN(); double aspect2 = part1.MyPart.GetDMAX() / part.MyPart.GetDMIN(); var angle1 = part.MyPart.GetORIENTATION(); var angle2= part1.MyPart.GetORIENTATION(); if (aspect1 > 2 && aspect2 > 2) { // If the aspect ratio of both particles is greater than 2 and their orientations are similar, link them var angle = calculateTwoPointAngle(centerPoint, centerPoint1); if (Math.Abs(angle - angle1) < 5 && Math.Abs(angle - angle2) < 5) { part.AddLinkedParticle(part1); part1.AddLinkedParticle(part); continue; } else { continue; } } else if (aspect1 > 2 && aspect2 < 2) { var angle = calculateTwoPointAngle(centerPoint, centerPoint1); if (Math.Abs(angle - angle1) < 5) { part.AddLinkedParticle(part1); part1.AddLinkedParticle(part); continue; } else { continue; } } else if (aspect1 < 2 && aspect2 > 2) { var angle = calculateTwoPointAngle(centerPoint, centerPoint1); if (Math.Abs(angle - angle2) < 5) { part.AddLinkedParticle(part1); part1.AddLinkedParticle(part); continue; } else { continue; } } else if (aspect1 <= 2 && aspect2 <=2) { if (Math.Abs(part.MyPart.GetActualArea() - part1.MyPart.GetActualArea()) < 10) { // Link the particles part.AddLinkedParticle(part1); part1.AddLinkedParticle(part); continue; } else { // If the areas are not similar, do not link them continue; } } } } } //DFS all the linked particles Stack partStack=new Stack(); List mergedParts = new List(); List finalOTSParts = new List(); foreach (var pParticle in linkedParticles) { if (!pParticle.IsMerged) { COTSLinkedParticle finalpart = new COTSLinkedParticle(pParticle.MyPart); foreach (var connP in pParticle.GetLinkedParticles()) { if (!connP.IsMerged) { partStack.Push(connP); } } while (partStack.Count > 0) { COTSLinkedParticle currpart = partStack.Pop(); currpart.IsMerged = true; finalpart.AddLinkedParticle(currpart); if (currpart.GetLinkedParticles().Count>0) { foreach (var connP in currpart.GetLinkedParticles()) { if (!connP.IsMerged) { partStack.Push(connP); } } } } if (finalpart.GetLinkedParticles().Count > 1) { //merge the particles finalpart.MergeLinkedParticles(); mergedParts.Add(finalpart.MyPart); } else { finalOTSParts.Add(finalpart.MyPart); // If no linked particles, just add the original particle } } } curFldData.CalParticleImageProp(mergedParts); finalOTSParts.AddRange(mergedParts); curFldData.SetListAnalysisParticles(finalOTSParts); } public double calculateTwoPointAngle(PointF p1, PointF p2) { if (p1.Y > p2.Y) { PointF temp = p1; p1 = p2; p2 = temp; } double angle = Math.Atan2(p2.Y - p1.Y, p2.X - p1.X) * 180 / Math.PI; if (angle < 0) { angle += 360; } return angle; } } }