using OpenCvSharp; using PaintDotNet.Base.DedicatedAnalysis.Inclusions.Model; using System.Collections.Generic; using System.Drawing; namespace PaintDotNet.Base.DedicatedAnalysis.Inclusions { /// /// 夹杂物标准 /// public abstract class InclusionsStandard { public static Color[] RAINBOW_COLORS = { Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Blue, Color.Cyan, Color.Purple }; /// /// 设置 /// public InclusionsGlobalSettings globalSettings = new InclusionsGlobalSettings(); #region 识别测量区域中的微粒 /// /// 识别测量区域中的微粒 /// /// 视场 /// 识别出的微粒列表 public virtual List identifyParticles(Mat field,int isK) { Cv2.Threshold(field, field, 175, 255, ThresholdTypes.BinaryInv); OpenCvSharp.Point[][] contours; HierarchyIndex[] hierarchy; Cv2.FindContours(field, out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone); List particles = new List(); for (int i = 0; i < contours.Length; i++) { if (hierarchy[i].Parent != -1) { continue; } OpenCvSharp.Point[] contour = contours[i]; var p = new Particle(contour, this); if (isK == 1) { p.areaK = (Cv2.FloodFill(field, contours[i][0], new Scalar(0, 0, 0, 0))) * globalSettings.pxPerUnit * globalSettings.pxPerUnit; } particles.Add(p); } return particles; } #endregion #region 过滤微粒 /// /// 过滤微粒 /// /// 使用minimumLength,minimumWidth最小尺寸来过滤微粒 /// 过滤前的微粒列表 /// 过滤后的微粒列表 public virtual List filterParticles(List particles) { for (int i = particles.Count - 1; i >= 0; i--) { Particle particle = particles[i]; if (particle.physicalLength < this.globalSettings.minimumLength || particle.physicalWidth < this.globalSettings.minimumWidth) { particles.Remove(particle); } } return particles; } #endregion #region 划分夹杂物 /// /// 划分夹杂物 /// /// 使用distancesBetweenParticles,distancesBetweenStringers划分夹杂物 /// 过滤后的微粒列表 /// 夹杂物列表 public virtual List divideInclusion(List particles) { return this.inclusionsDivideInclusion(this.particlesDivideInclusion(particles)); } #endregion #region 微粒划分夹杂物 /// /// 微粒划分夹杂物 /// /// 过滤后的微粒列表 /// 夹杂物列表 protected virtual List particlesDivideInclusion(List particles) { List inclusions = new List(); // 第一次划分 微粒划分夹杂物 foreach (Particle particle in particles) { if (inclusions.Count == 0) { Inclusion inclusion = new Inclusion(this); inclusion.addParticles(particle); inclusions.Add(inclusion); continue; } foreach (Inclusion inclusion in inclusions) { if (inclusion.particles[0].shape != particle.shape) { continue; } // 矩形相交 if (inclusion.rectProfile.IntersectsWith(particle.rectProfile)) { inclusion.addParticles(particle); goto particleJump; } else { int verticalDistancePx = this.globalSettings.distancesBetweenParticlesE, horizontalDistancePx = this.globalSettings.distancesBetweenParticlesT; // 先比较垂直距离 if (this.globalSettings.rollingDirection == InclusionsGlobalSettings.RollingDirection.PORTRAIT) { if (particle.rectProfile.Bottom < inclusion.rectProfile.Top) { verticalDistancePx = inclusion.rectProfile.Top - particle.rectProfile.Bottom; } if (particle.rectProfile.Top > inclusion.rectProfile.Bottom) { verticalDistancePx = particle.rectProfile.Top - inclusion.rectProfile.Bottom; } //if (particle.rectProfile.Right < inclusion.rectProfile.Left) //{ // horizontalDistancePx = inclusion.rectProfile.Left - particle.rectProfile.Right; //} //if (particle.rectProfile.Left > inclusion.rectProfile.Right) //{ // horizontalDistancePx = particle.rectProfile.Left - inclusion.rectProfile.Right; //} //if (particle.rectProfile.Right > inclusion.rectProfile.Right && particle.rectProfile.Left < inclusion.rectProfile.Left) { // horizontalDistancePx = 0; //} //if (particle.rectProfile.Right < inclusion.rectProfile.Right && particle.rectProfile.Left > inclusion.rectProfile.Left) //{ // horizontalDistancePx = 0; //} if (particle.rectProfile.Right < inclusion.rectProfile.Right) { if (particle.rectProfile.Right < inclusion.rectProfile.Left) { horizontalDistancePx = inclusion.rectProfile.Left - particle.rectProfile.Right; } else { horizontalDistancePx = inclusion.rectProfile.Left - particle.rectProfile.Left; } } if (particle.rectProfile.Left > inclusion.rectProfile.Left) { if (particle.rectProfile.Left > inclusion.rectProfile.Right) { horizontalDistancePx = particle.rectProfile.Left - inclusion.rectProfile.Right; } else { horizontalDistancePx = particle.rectProfile.Right - inclusion.rectProfile.Right; } } if (horizontalDistancePx <= 0) { horizontalDistancePx = 0; } } else { //if (particle.rectProfile.Bottom < inclusion.rectProfile.Top) //{ // horizontalDistancePx = inclusion.rectProfile.Top - particle.rectProfile.Bottom; //} //if (particle.rectProfile.Top > inclusion.rectProfile.Bottom) //{ // horizontalDistancePx = particle.rectProfile.Top - inclusion.rectProfile.Bottom; //} //if (particle.rectProfile.Top > inclusion.rectProfile.Top && particle.rectProfile.Bottom < inclusion.rectProfile.Bottom) //{ // horizontalDistancePx = 0; //} //if (particle.rectProfile.Top < inclusion.rectProfile.Top && particle.rectProfile.Bottom > inclusion.rectProfile.Bottom) //{ // horizontalDistancePx = 0; //} if (particle.rectProfile.Bottom < inclusion.rectProfile.Bottom) { if (particle.rectProfile.Bottom < inclusion.rectProfile.Top) { horizontalDistancePx = inclusion.rectProfile.Top - particle.rectProfile.Bottom; } else { horizontalDistancePx = inclusion.rectProfile.Top - particle.rectProfile.Left; } } if (particle.rectProfile.Top > inclusion.rectProfile.Top) { if (particle.rectProfile.Top > inclusion.rectProfile.Bottom) { horizontalDistancePx = particle.rectProfile.Top - inclusion.rectProfile.Bottom; } else { horizontalDistancePx = particle.rectProfile.Bottom - inclusion.rectProfile.Bottom; } } if (horizontalDistancePx <= 0) { horizontalDistancePx = 0; } if (particle.rectProfile.Right < inclusion.rectProfile.Left) { verticalDistancePx = inclusion.rectProfile.Left - particle.rectProfile.Right; } if (particle.rectProfile.Left > inclusion.rectProfile.Right) { verticalDistancePx = particle.rectProfile.Left - inclusion.rectProfile.Right; } } if (verticalDistancePx * this.globalSettings.pxPerUnit <= this.globalSettings.distancesBetweenParticlesE && horizontalDistancePx * this.globalSettings.pxPerUnit <= this.globalSettings.distancesBetweenParticlesT) { inclusion.addParticles(particle); goto particleJump; } } } Inclusion newInclusion = new Inclusion(this); newInclusion.addParticles(particle); inclusions.Add(newInclusion); particleJump:; } return inclusions; } #endregion #region 夹杂物划分夹杂物(合并) /// /// 夹杂物划分夹杂物(合并) /// /// 夹杂物列表 /// 夹杂物列表 protected virtual List inclusionsDivideInclusion(List inclusions) { // 第二次划分 夹杂物间划分 for (int i = 0; i < inclusions.Count; i++) { if (i > inclusions.Count - 1) { break; } Inclusion inclusion = inclusions[i]; for (int o = inclusions.Count - 1; o > i; o--) { if (o > inclusions.Count - 1) { break; } // 矩形相交 if (inclusion.rectProfile.IntersectsWith(inclusions[o].rectProfile)) { inclusion.addParticles(inclusions[o].particles); inclusions.RemoveAt(o); } else { if (inclusions[o].particles[0].shape != inclusion.particles[0].shape) { continue; } int verticalDistancePx = this.globalSettings.distancesBetweenParticlesE, horizontalDistancePx = this.globalSettings.distancesBetweenParticlesT; // 先比较垂直距离 if (this.globalSettings.rollingDirection == InclusionsGlobalSettings.RollingDirection.PORTRAIT) { if (inclusions[o].rectProfile.Bottom < inclusion.rectProfile.Top) { verticalDistancePx = inclusion.rectProfile.Top - inclusions[o].rectProfile.Bottom; } if (inclusions[o].rectProfile.Top > inclusion.rectProfile.Bottom) { verticalDistancePx = inclusions[o].rectProfile.Top - inclusion.rectProfile.Bottom; } //if (inclusions[o].rectProfile.Right < inclusion.rectProfile.Left) //{ // horizontalDistancePx = inclusion.rectProfile.Left - inclusions[o].rectProfile.Right; //} //if (inclusions[o].rectProfile.Left > inclusion.rectProfile.Right) //{ // horizontalDistancePx = inclusions[o].rectProfile.Left - inclusion.rectProfile.Right; //} if (inclusions[o].rectProfile.Right < inclusion.rectProfile.Right) { if (inclusions[o].rectProfile.Right < inclusion.rectProfile.Left) { horizontalDistancePx = inclusion.rectProfile.Left - inclusions[o].rectProfile.Right; } else { horizontalDistancePx = inclusion.rectProfile.Left - inclusions[o].rectProfile.Left; } } if (inclusions[o].rectProfile.Left > inclusion.rectProfile.Left) { if (inclusions[o].rectProfile.Left > inclusion.rectProfile.Right) { horizontalDistancePx = inclusions[o].rectProfile.Left - inclusion.rectProfile.Right; } else { horizontalDistancePx = inclusions[o].rectProfile.Right - inclusion.rectProfile.Right; } } if (horizontalDistancePx <= 0) { horizontalDistancePx = 0; } } else { //if (inclusions[o].rectProfile.Bottom < inclusion.rectProfile.Top) //{ // horizontalDistancePx = inclusion.rectProfile.Top - inclusions[o].rectProfile.Bottom; //} //if (inclusions[o].rectProfile.Top > inclusion.rectProfile.Bottom) //{ // horizontalDistancePx = inclusions[o].rectProfile.Top - inclusion.rectProfile.Bottom; //} if (inclusions[o].rectProfile.Bottom < inclusion.rectProfile.Bottom) { if (inclusions[o].rectProfile.Bottom < inclusion.rectProfile.Top) { horizontalDistancePx = inclusion.rectProfile.Top - inclusions[o].rectProfile.Bottom; } else { horizontalDistancePx = inclusion.rectProfile.Top - inclusions[o].rectProfile.Left; } } if (inclusions[o].rectProfile.Top > inclusion.rectProfile.Top) { if (inclusions[o].rectProfile.Top > inclusion.rectProfile.Bottom) { horizontalDistancePx = inclusions[o].rectProfile.Top - inclusion.rectProfile.Bottom; } else { horizontalDistancePx = inclusions[o].rectProfile.Bottom - inclusion.rectProfile.Bottom; } } if (horizontalDistancePx <= 0) { horizontalDistancePx = 0; } if (inclusions[o].rectProfile.Right < inclusion.rectProfile.Left) { verticalDistancePx = inclusion.rectProfile.Left - inclusions[o].rectProfile.Right; } if (inclusions[o].rectProfile.Left > inclusion.rectProfile.Right) { verticalDistancePx = inclusions[o].rectProfile.Left - inclusion.rectProfile.Right; } } if (verticalDistancePx * this.globalSettings.pxPerUnit <= this.globalSettings.distancesBetweenParticlesE && horizontalDistancePx * this.globalSettings.pxPerUnit <= this.globalSettings.distancesBetweenParticlesT) { inclusion.addParticles(inclusions[o].particles); inclusions.RemoveAt(o); } } } } List tobeCombined = new List(); foreach (var item in inclusions) { if (item.particles.Count<3) { tobeCombined.Add(item); } } inclusionsCombinationSplit(inclusions,tobeCombined); return inclusions; } #endregion #region 夹杂物组合 /// /// 夹杂物组合 /// /// 全部的夹杂物 /// 待合并的夹杂物 public virtual List inclusionsCombination(List allInclusions, List tobeCombined) { Inclusion inclusion = new Inclusion(this); foreach (Inclusion item in tobeCombined) { inclusion.addParticles(item.particles); allInclusions.Remove(item); } allInclusions.Add(inclusion); return allInclusions; } #endregion #region 夹杂物组合拆分 /// /// 夹杂物组合拆分 /// /// 全部的夹杂物 /// 待拆分的夹杂物 public virtual List inclusionsCombinationSplit(List allInclusions, List tobeCombined) { foreach (Inclusion item in tobeCombined) { foreach (Particle particle in item.particles) { Inclusion inclusion = new Inclusion(this); inclusion.addParticles(particle); allInclusions.Add(inclusion); } allInclusions.Remove(item); } return allInclusions; } #endregion /// /// 判断夹杂物类型 /// public abstract void determineType(Inclusion inclusion); /// /// 边缘误差修正 /// /// 根据视场边界修正所计算的夹杂物 /// public abstract void edgeErrorsCorrection(List inclusions); } }