MethodOfAssessment.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. using OpenCvSharp;
  2. using PaintDotNet.Base.DedicatedAnalysis.Inclusions.Model;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.Linq;
  7. using static PaintDotNet.Base.DedicatedAnalysis.Inclusions.InclusionsGlobalSettings;
  8. namespace PaintDotNet.Base.DedicatedAnalysis.Inclusions
  9. {
  10. /// <summary>
  11. /// 评定方法
  12. /// </summary>
  13. public abstract class MethodOfAssessment
  14. {
  15. public static MethodOfAssessment activeMethod;
  16. /// <summary>
  17. /// 所属的标准
  18. /// </summary>
  19. public InclusionsStandard inclusionsStandard;
  20. /// <summary>
  21. /// 测量区域
  22. /// </summary>
  23. public Mat field;
  24. public string resourcesName;
  25. public int is_full;
  26. // 标准的结果模型
  27. // 试样总检验面积
  28. // 视场面积
  29. // 放大倍数
  30. /// <summary>
  31. /// 产生报告
  32. /// </summary>
  33. public AnalysisResult generateReport(Mat originalImage, Mat binary, List<RectangleF> rectangles,int is_k, int viewNum, int kNum,int is_full, RollingDirection rollingDirection)
  34. {
  35. Mat binaryBGR2GRAY = binary.CvtColor(ColorConversionCodes.BGR2GRAY);
  36. Cv2.Threshold(binaryBGR2GRAY, binaryBGR2GRAY, 249, 255, ThresholdTypes.Binary);
  37. List<Particle> particles = new List<Particle>();
  38. List<RectangleF> MedthodKRectangles = new List<RectangleF>();
  39. this.inclusionsStandard.globalSettings.rollingDirection = rollingDirection;
  40. int offX = 0;
  41. int offY = 0;
  42. int segmentationView = 1;
  43. if (is_k != 1)
  44. {
  45. particles = this.inclusionsStandard.identifyParticles(binaryBGR2GRAY, is_k);
  46. }
  47. else {
  48. if (rectangles.Count == 0) {
  49. rectangles.Add(new RectangleF(0,0, originalImage.Width, originalImage.Height));
  50. }
  51. var grap = rectangles[0];
  52. if (grap.Width > originalImage.Width) {
  53. grap.Width = originalImage.Width;
  54. }
  55. if (grap.Height > originalImage.Height) {
  56. grap.Height = originalImage.Height;
  57. }
  58. var biaochi = this.inclusionsStandard.globalSettings.pxPerUnit;
  59. int hnum = (int)Math.Truncate(grap.Width * biaochi / viewNum); //水平网格数
  60. int vnum = (int)Math.Truncate(grap.Height * biaochi / viewNum); //垂直网格数
  61. if (hnum == 0)
  62. {
  63. particles = this.inclusionsStandard.identifyParticles(binaryBGR2GRAY,is_k);
  64. MedthodKRectangles.Add(grap);
  65. }
  66. else
  67. {
  68. int OffsetX = (int)((grap.Width - (viewNum / biaochi) * hnum) / 2);
  69. int OffsetY = (int)((grap.Height - (viewNum / biaochi) * vnum) / 2);
  70. int startX = ((int)grap.X + OffsetX) < 0 ? OffsetX : ((int)grap.X + OffsetX);
  71. int startY = ((int)grap.Y + OffsetY) < 0 ? OffsetY : ((int)grap.Y + OffsetY);
  72. for (int i = 0; i < hnum; i++)
  73. {
  74. for (int j = 0; j < vnum; j++)
  75. {
  76. Mat mat = new Mat(binaryBGR2GRAY, new Rect((int)(startX + ((viewNum / biaochi)) * i), (int)(startY + ((viewNum / biaochi)) * j), (int)((viewNum / biaochi)), (int)((viewNum / biaochi))));
  77. var newParticles = this.inclusionsStandard.identifyParticles(mat, is_k);
  78. foreach (var s in newParticles)
  79. {
  80. s.rectKMethodProfile.X += (int)(startX + ((viewNum / biaochi)) * i);
  81. s.rectKMethodProfile.Y += (int)(startY + ((viewNum / biaochi)) * j);
  82. var points = new List<System.Drawing.Point>();
  83. foreach (var k in s.points2)
  84. {
  85. var point = new System.Drawing.Point((int)(k.X + (startX + ((viewNum / biaochi)) * i)), (int)(k.Y + (startY + ((viewNum / biaochi)) * j)));
  86. points.Add(point);
  87. }
  88. s.points2 = points.ToArray();
  89. s.offsetX = (int)(i * (viewNum / biaochi));
  90. s.offsetY = (int)(j * (viewNum / biaochi));
  91. }
  92. particles.AddRange(newParticles);
  93. MedthodKRectangles.Add(new Rectangle((int)(startX + (viewNum / biaochi) * i), (int)(startY + (viewNum / biaochi) * j), (int)(viewNum / biaochi), (int)(viewNum / biaochi)));
  94. }
  95. }
  96. segmentationView = 2;
  97. offX = startX;
  98. offY = startY;
  99. }
  100. }
  101. particles = this.inclusionsStandard.filterParticles(particles);
  102. List<Inclusion> inclusions = this.inclusionsStandard.divideInclusion(particles);
  103. // 三通道 验证颜色
  104. if (originalImage.Channels() >= 3)
  105. {
  106. Dictionary<ColorOfInclusions, int> colorCount = new Dictionary<ColorOfInclusions, int>();
  107. foreach (var inclusion in inclusions)
  108. {
  109. // 清理记录列表
  110. colorCount.Clear();
  111. foreach (var item in this.inclusionsStandard.globalSettings.colorOfInclusions)
  112. {
  113. colorCount.Add(item.Value, 0);
  114. }
  115. // 循环微粒
  116. // 遍历所有点颜色,判断夹杂物颜色
  117. foreach (var particle in inclusion.particles)
  118. {
  119. var groups = particle.points2.GroupBy(r => r.Y);
  120. foreach (var group in groups)
  121. {
  122. // 确定一行的两个端点
  123. int y = group.Key;
  124. int? minx = null,maxx = null;
  125. foreach (var item in group)
  126. {
  127. if (minx == null)
  128. {
  129. minx = item.X;
  130. }
  131. if (maxx == null)
  132. {
  133. maxx = item.X;
  134. }
  135. if (item.X < minx)
  136. {
  137. minx = item.X;
  138. }
  139. if (item.X > maxx)
  140. {
  141. maxx = item.X;
  142. }
  143. }
  144. for (int x = minx.Value; x <= maxx.Value; x++)
  145. {
  146. Vec3b color = originalImage.At<Vec3b>(y, x);
  147. List<ColorOfInclusions> keys = new List<ColorOfInclusions>();
  148. keys.AddRange(colorCount.Keys);
  149. // 判断是否符合颜色区间
  150. foreach (var colorOfInclusion in keys)
  151. {
  152. //r
  153. if (!(colorOfInclusion.rd <= color[2] && colorOfInclusion.ru >= color[2]))
  154. {
  155. continue;
  156. }
  157. //g
  158. if (!(colorOfInclusion.gd <= color[1] && colorOfInclusion.gu >= color[1]))
  159. {
  160. continue;
  161. }
  162. //b
  163. if (!(colorOfInclusion.bd <= color[0] && colorOfInclusion.bu >= color[0]))
  164. {
  165. continue;
  166. }
  167. colorCount[colorOfInclusion]++;
  168. }
  169. }
  170. }
  171. }
  172. inclusion.color = colorCount.First(r => r.Value == colorCount.Max(t => t.Value)).Key;
  173. }
  174. }
  175. this.is_full = is_full;
  176. AnalysisResult analysisResult = GetAnalysisResult();
  177. analysisResult.inclusionsStandard = this.inclusionsStandard;
  178. analysisResult.mat = originalImage;
  179. analysisResult.kNum = kNum;
  180. analysisResult.segmentationView = segmentationView;
  181. analysisResult.inclusions = inclusions;
  182. analysisResult.rectangles = rectangles;
  183. analysisResult.offsetX = offX;
  184. analysisResult.offsetY = offY;
  185. analysisResult.viewNum = viewNum;
  186. analysisResult.MedthodKRectangles = MedthodKRectangles;
  187. analysisResult.buildResultBody();
  188. binary.Dispose();
  189. return analysisResult;
  190. }
  191. public abstract AnalysisResult GetAnalysisResult();
  192. public abstract List<string> getResultConclusionHead();
  193. public abstract List<string> buildResultConclusion(List<AnalysisResult> analysisResults);
  194. /// <summary>
  195. /// 分析结果
  196. /// </summary>
  197. public abstract class AnalysisResult
  198. {
  199. /// <summary>
  200. /// 所属标准
  201. /// </summary>
  202. public InclusionsStandard inclusionsStandard;
  203. /// <summary>
  204. /// 所属图片
  205. /// </summary>
  206. public Mat mat;
  207. /// <summary>
  208. /// 夹杂物列表
  209. /// </summary>
  210. public List<Inclusion> inclusions;
  211. public List<RectangleF> rectangles;
  212. public List<RectangleF> MedthodKRectangles = new List<RectangleF>();
  213. public int segmentationView = 1;
  214. public int kNum;
  215. public int offsetX = 0;
  216. public int offsetY = 0;
  217. public int viewNum;
  218. public List<string> publicResultHead = new List<string> {"图片","视场"};
  219. public Dictionary<FieldOfView, List<string>> resultBody = new Dictionary<FieldOfView, List<string>>();
  220. /// <summary>
  221. /// 是否是K法
  222. /// </summary>
  223. public int is_k;
  224. /// <summary>
  225. /// 视场模型
  226. /// </summary>
  227. public class FieldOfView
  228. {
  229. public string name;
  230. public RectangleF rectangle;
  231. public List<Inclusion> inclusions;
  232. /// <summary>
  233. /// 过滤有效的夹杂物
  234. /// </summary>
  235. /// <returns></returns>
  236. public List<Inclusion> effectiveFilteringInclusion(List<Inclusion> inclusions)
  237. {
  238. List<Inclusion> inclusions1 = new List<Inclusion>();
  239. foreach (var item in inclusions)
  240. {
  241. if (this.rectangle.Contains(item.rectProfile) || this.rectangle.IntersectsWith(item.rectProfile))
  242. {
  243. inclusions1.Add(item);
  244. }
  245. }
  246. return inclusions1;
  247. }
  248. /// <summary>
  249. /// 过滤有效的夹杂物(50602K)
  250. /// </summary>
  251. /// <returns></returns>
  252. public List<Inclusion> effectiveFilteringMethodKInclusion(RectangleF rectangleF, List<Inclusion> inclusions)
  253. {
  254. List<Inclusion> inclusions1 = new List<Inclusion>();
  255. foreach (var item in inclusions)
  256. {
  257. if (rectangleF.Contains(item.rectKMethodProfile) || rectangleF.IntersectsWith(item.rectKMethodProfile))
  258. {
  259. inclusions1.Add(item);
  260. }
  261. }
  262. return inclusions1;
  263. }
  264. }
  265. public List<string> getResultHead()
  266. {
  267. List<string> resultHead = new List<string>();
  268. resultHead.AddRange(publicResultHead);
  269. resultHead.AddRange(getDedicatedResultHead());
  270. return resultHead;
  271. }
  272. public abstract List<string> getDedicatedResultHead();
  273. public abstract void buildResultBody();
  274. /// <summary>
  275. /// 夹杂物评级
  276. /// </summary>
  277. /// 评级图暂已硬编码形式实现
  278. public abstract double ratingInclusion(string type, double value);
  279. }
  280. }
  281. }