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);
}
}