WorstfieldFinder.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using OpenCvSharp;
  2. using PaintDotNet.Adjust;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. namespace Metis.AutoAnalysis
  9. {
  10. /// <summary>
  11. /// 寻找最差视场
  12. /// </summary>
  13. class WorstfieldFinder
  14. {
  15. public static Mat Find(Mat src, OpenCvSharp.Size size)
  16. {
  17. Mat gray = new Mat();
  18. Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
  19. Mat mask = convert2Mask(gray);
  20. //去掉边缘
  21. Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(11, 11));
  22. Cv2.Erode(mask, mask, element);
  23. //取边缘
  24. Mat srcTemp = src.Clone();
  25. Mat edge = ImageSobel(srcTemp);
  26. if(edge == null)
  27. {
  28. Mat result1 = new Mat(src, new OpenCvSharp.Rect(new OpenCvSharp.Point(0, 0), size));
  29. return result1;
  30. }
  31. //把因为拼图造成的边缘去掉
  32. Cv2.BitwiseAnd(edge, mask, edge);
  33. Mat thr = new Mat();
  34. Cv2.Threshold(edge, thr, 50, 255, ThresholdTypes.Binary);
  35. OpenCvSharp.Point[][] contours = null;
  36. HierarchyIndex[] hierarchy = null;
  37. Cv2.FindContours(thr, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  38. var obj = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0));
  39. Cv2.DrawContours(obj, contours, -1, Scalar.All(255), -1);
  40. //遍历整个图形
  41. int step = 500;
  42. int maxNZ = -100;//非0点个数
  43. var tempLoc = new OpenCvSharp.Point();
  44. for (int y = 0; y < src.Height - size.Height; y += step)
  45. {
  46. for (int x = 0; x < src.Width - size.Width; x += step)
  47. {
  48. LogHelper.log.Debug(" Find x =" + x.ToString() + " y = " + y.ToString());
  49. Rect rc = new Rect(x, y, size.Width, size.Height);
  50. Mat roi = new Mat(obj, rc);
  51. var countNZ = Cv2.CountNonZero(roi);
  52. if(maxNZ < countNZ)
  53. {
  54. maxNZ = countNZ;
  55. tempLoc = new Point(x, y);
  56. }
  57. }
  58. }
  59. Mat result = new Mat(src, new Rect(tempLoc, size));
  60. return result;
  61. }
  62. /// <summary>
  63. /// 生成拼图后的掩码
  64. /// </summary>
  65. /// <param name="mat"></param>
  66. /// <returns></returns>
  67. private static Mat convert2Mask(Mat gray)
  68. {
  69. LogHelper.log.Debug(" convert2Mask 111");
  70. Mat thr = new Mat();
  71. Cv2.Threshold(gray, thr, 1, 255, ThresholdTypes.Binary);
  72. LogHelper.log.Debug(" convert2Mask 222");
  73. OpenCvSharp.Point[][] contours = null;
  74. HierarchyIndex[] hierarchy = null;
  75. Cv2.FindContours(thr, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
  76. LogHelper.log.Debug(" convert2Mask 333");
  77. //生成拼图后实际图像的掩码
  78. var mask = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0));
  79. Cv2.DrawContours(mask, contours, -1, Scalar.All(255), -1);
  80. LogHelper.log.Debug(" convert2Mask 444");
  81. return mask;
  82. }
  83. public static Mat ImageSobel(Mat src)
  84. {
  85. Mat gray = null, xgrad = null, ygrad = null, output = null;
  86. try
  87. {
  88. //转为灰度
  89. gray = new Mat();
  90. Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
  91. MatType m = src.Type();
  92. //求 X 和 Y 方向的梯度 Sobel and scharr
  93. xgrad = new Mat();
  94. ygrad = new Mat();
  95. Cv2.Sobel(gray, xgrad, MatType.CV_16S, 1, 0, 3);
  96. Cv2.Sobel(gray, ygrad, MatType.CV_16S, 0, 1, 3);
  97. Cv2.ConvertScaleAbs(xgrad, xgrad);//缩放、计算绝对值并将结果转换为8位。不做转换的化显示不了,显示图相只能是8U类型
  98. Cv2.ConvertScaleAbs(ygrad, ygrad);
  99. //加强边缘检测
  100. //Cv2.Scharr(gray, xgrad, -1, 1, 0, 3);
  101. //Cv2.Scharr(gray, ygrad, -1, 0, 1, 3);
  102. output = new Mat(gray.Size(), gray.Type());
  103. //图像混合相加(基于权重 0.5)不精确
  104. Cv2.AddWeighted(xgrad, 0.5, ygrad, 0.5, 0, output);
  105. return output;
  106. }
  107. catch (Exception ex)
  108. {
  109. }
  110. finally
  111. {
  112. if (gray != null) gray.Dispose();
  113. if (xgrad != null) gray.Dispose();
  114. if (ygrad != null) gray.Dispose();
  115. if (output != null) gray.Dispose();
  116. GC.Collect();
  117. }
  118. return null;
  119. }
  120. }
  121. }