using OpenCvSharp; using PaintDotNet.Base.DedicatedAnalysis.Inclusions.Model; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using static PaintDotNet.Base.DedicatedAnalysis.Inclusions.InclusionsGlobalSettings; namespace PaintDotNet.Base.DedicatedAnalysis.Inclusions { /// /// 评定方法 /// public abstract class MethodOfAssessment { public static MethodOfAssessment activeMethod; /// /// 所属的标准 /// public InclusionsStandard inclusionsStandard; /// /// 测量区域 /// public Mat field; public string resourcesName; public int is_full; // 标准的结果模型 // 试样总检验面积 // 视场面积 // 放大倍数 /// /// 产生报告 /// public AnalysisResult generateReport(Mat originalImage, Mat binary, List rectangles,int is_k, int viewNum, int kNum,int is_full, RollingDirection rollingDirection) { Mat binaryBGR2GRAY = binary.CvtColor(ColorConversionCodes.BGR2GRAY); Cv2.Threshold(binaryBGR2GRAY, binaryBGR2GRAY, 249, 255, ThresholdTypes.Binary); List particles = new List(); List MedthodKRectangles = new List(); this.inclusionsStandard.globalSettings.rollingDirection = rollingDirection; int offX = 0; int offY = 0; int segmentationView = 1; if (is_k != 1) { particles = this.inclusionsStandard.identifyParticles(binaryBGR2GRAY, is_k); } else { if (rectangles.Count == 0) { rectangles.Add(new RectangleF(0,0, originalImage.Width, originalImage.Height)); } var grap = rectangles[0]; if (grap.Width > originalImage.Width) { grap.Width = originalImage.Width; } if (grap.Height > originalImage.Height) { grap.Height = originalImage.Height; } var biaochi = this.inclusionsStandard.globalSettings.pxPerUnit; int hnum = (int)Math.Truncate(grap.Width * biaochi / viewNum); //水平网格数 int vnum = (int)Math.Truncate(grap.Height * biaochi / viewNum); //垂直网格数 if (hnum == 0) { particles = this.inclusionsStandard.identifyParticles(binaryBGR2GRAY,is_k); MedthodKRectangles.Add(grap); } else { int OffsetX = (int)((grap.Width - (viewNum / biaochi) * hnum) / 2); int OffsetY = (int)((grap.Height - (viewNum / biaochi) * vnum) / 2); int startX = ((int)grap.X + OffsetX) < 0 ? OffsetX : ((int)grap.X + OffsetX); int startY = ((int)grap.Y + OffsetY) < 0 ? OffsetY : ((int)grap.Y + OffsetY); for (int i = 0; i < hnum; i++) { for (int j = 0; j < vnum; j++) { Mat mat = new Mat(binaryBGR2GRAY, new Rect((int)(startX + ((viewNum / biaochi)) * i), (int)(startY + ((viewNum / biaochi)) * j), (int)((viewNum / biaochi)), (int)((viewNum / biaochi)))); var newParticles = this.inclusionsStandard.identifyParticles(mat, is_k); foreach (var s in newParticles) { s.rectKMethodProfile.X += (int)(startX + ((viewNum / biaochi)) * i); s.rectKMethodProfile.Y += (int)(startY + ((viewNum / biaochi)) * j); var points = new List(); foreach (var k in s.points2) { var point = new System.Drawing.Point((int)(k.X + (startX + ((viewNum / biaochi)) * i)), (int)(k.Y + (startY + ((viewNum / biaochi)) * j))); points.Add(point); } s.points2 = points.ToArray(); s.offsetX = (int)(i * (viewNum / biaochi)); s.offsetY = (int)(j * (viewNum / biaochi)); } particles.AddRange(newParticles); MedthodKRectangles.Add(new Rectangle((int)(startX + (viewNum / biaochi) * i), (int)(startY + (viewNum / biaochi) * j), (int)(viewNum / biaochi), (int)(viewNum / biaochi))); } } segmentationView = 2; offX = startX; offY = startY; } } particles = this.inclusionsStandard.filterParticles(particles); List inclusions = this.inclusionsStandard.divideInclusion(particles); // 三通道 验证颜色 if (originalImage.Channels() >= 3) { Dictionary colorCount = new Dictionary(); foreach (var inclusion in inclusions) { // 清理记录列表 colorCount.Clear(); foreach (var item in this.inclusionsStandard.globalSettings.colorOfInclusions) { colorCount.Add(item.Value, 0); } // 循环微粒 // 遍历所有点颜色,判断夹杂物颜色 foreach (var particle in inclusion.particles) { var groups = particle.points2.GroupBy(r => r.Y); foreach (var group in groups) { // 确定一行的两个端点 int y = group.Key; int? minx = null,maxx = null; foreach (var item in group) { if (minx == null) { minx = item.X; } if (maxx == null) { maxx = item.X; } if (item.X < minx) { minx = item.X; } if (item.X > maxx) { maxx = item.X; } } for (int x = minx.Value; x <= maxx.Value; x++) { Vec3b color = originalImage.At(y, x); List keys = new List(); keys.AddRange(colorCount.Keys); // 判断是否符合颜色区间 foreach (var colorOfInclusion in keys) { //r if (!(colorOfInclusion.rd <= color[2] && colorOfInclusion.ru >= color[2])) { continue; } //g if (!(colorOfInclusion.gd <= color[1] && colorOfInclusion.gu >= color[1])) { continue; } //b if (!(colorOfInclusion.bd <= color[0] && colorOfInclusion.bu >= color[0])) { continue; } colorCount[colorOfInclusion]++; } } } } inclusion.color = colorCount.First(r => r.Value == colorCount.Max(t => t.Value)).Key; } } this.is_full = is_full; AnalysisResult analysisResult = GetAnalysisResult(); analysisResult.inclusionsStandard = this.inclusionsStandard; analysisResult.mat = originalImage; analysisResult.kNum = kNum; analysisResult.segmentationView = segmentationView; analysisResult.inclusions = inclusions; analysisResult.rectangles = rectangles; analysisResult.offsetX = offX; analysisResult.offsetY = offY; analysisResult.viewNum = viewNum; analysisResult.MedthodKRectangles = MedthodKRectangles; analysisResult.buildResultBody(); binary.Dispose(); return analysisResult; } public abstract AnalysisResult GetAnalysisResult(); public abstract List getResultConclusionHead(); public abstract List buildResultConclusion(List analysisResults); /// /// 分析结果 /// public abstract class AnalysisResult { /// /// 所属标准 /// public InclusionsStandard inclusionsStandard; /// /// 所属图片 /// public Mat mat; /// /// 夹杂物列表 /// public List inclusions; public List rectangles; public List MedthodKRectangles = new List(); public int segmentationView = 1; public int kNum; public int offsetX = 0; public int offsetY = 0; public int viewNum; public List publicResultHead = new List {"图片","视场"}; public Dictionary> resultBody = new Dictionary>(); /// /// 是否是K法 /// public int is_k; /// /// 视场模型 /// public class FieldOfView { public string name; public RectangleF rectangle; public List inclusions; /// /// 过滤有效的夹杂物 /// /// public List effectiveFilteringInclusion(List inclusions) { List inclusions1 = new List(); foreach (var item in inclusions) { if (this.rectangle.Contains(item.rectProfile) || this.rectangle.IntersectsWith(item.rectProfile)) { inclusions1.Add(item); } } return inclusions1; } /// /// 过滤有效的夹杂物(50602K) /// /// public List effectiveFilteringMethodKInclusion(RectangleF rectangleF, List inclusions) { List inclusions1 = new List(); foreach (var item in inclusions) { if (rectangleF.Contains(item.rectKMethodProfile) || rectangleF.IntersectsWith(item.rectKMethodProfile)) { inclusions1.Add(item); } } return inclusions1; } } public List getResultHead() { List resultHead = new List(); resultHead.AddRange(publicResultHead); resultHead.AddRange(getDedicatedResultHead()); return resultHead; } public abstract List getDedicatedResultHead(); public abstract void buildResultBody(); /// /// 夹杂物评级 /// /// 评级图暂已硬编码形式实现 public abstract double ratingInclusion(string type, double value); } } }