123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- using OpenCvSharp;
- using PaintDotNet.Adjust;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace Metis.AutoAnalysis
- {
- /// <summary>
- /// 寻找最差视场
- /// </summary>
- class WorstfieldFinder
- {
- public static Mat Find(Mat src, OpenCvSharp.Size size)
- {
- Mat gray = new Mat();
- Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
- Mat mask = convert2Mask(gray);
- //去掉边缘
- Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(11, 11));
- Cv2.Erode(mask, mask, element);
- //取边缘
- Mat srcTemp = src.Clone();
- Mat edge = ImageSobel(srcTemp);
- if(edge == null)
- {
- Mat result1 = new Mat(src, new OpenCvSharp.Rect(new OpenCvSharp.Point(0, 0), size));
- return result1;
- }
- //把因为拼图造成的边缘去掉
- Cv2.BitwiseAnd(edge, mask, edge);
- Mat thr = new Mat();
- Cv2.Threshold(edge, thr, 50, 255, ThresholdTypes.Binary);
- OpenCvSharp.Point[][] contours = null;
- HierarchyIndex[] hierarchy = null;
- Cv2.FindContours(thr, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
- var obj = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0));
- Cv2.DrawContours(obj, contours, -1, Scalar.All(255), -1);
- //遍历整个图形
- int step = 500;
- int maxNZ = -100;//非0点个数
- var tempLoc = new OpenCvSharp.Point();
- for (int y = 0; y < src.Height - size.Height; y += step)
- {
- for (int x = 0; x < src.Width - size.Width; x += step)
- {
- LogHelper.log.Debug(" Find x =" + x.ToString() + " y = " + y.ToString());
- Rect rc = new Rect(x, y, size.Width, size.Height);
- Mat roi = new Mat(obj, rc);
- var countNZ = Cv2.CountNonZero(roi);
- if(maxNZ < countNZ)
- {
- maxNZ = countNZ;
- tempLoc = new Point(x, y);
- }
- }
- }
- Mat result = new Mat(src, new Rect(tempLoc, size));
- return result;
- }
- /// <summary>
- /// 生成拼图后的掩码
- /// </summary>
- /// <param name="mat"></param>
- /// <returns></returns>
- private static Mat convert2Mask(Mat gray)
- {
- LogHelper.log.Debug(" convert2Mask 111");
- Mat thr = new Mat();
- Cv2.Threshold(gray, thr, 1, 255, ThresholdTypes.Binary);
- LogHelper.log.Debug(" convert2Mask 222");
- OpenCvSharp.Point[][] contours = null;
- HierarchyIndex[] hierarchy = null;
- Cv2.FindContours(thr, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone);
- LogHelper.log.Debug(" convert2Mask 333");
- //生成拼图后实际图像的掩码
- var mask = new Mat(gray.Size(), MatType.CV_8UC1, Scalar.All(0));
- Cv2.DrawContours(mask, contours, -1, Scalar.All(255), -1);
- LogHelper.log.Debug(" convert2Mask 444");
- return mask;
- }
- public static Mat ImageSobel(Mat src)
- {
- Mat gray = null, xgrad = null, ygrad = null, output = null;
- try
- {
- //转为灰度
- gray = new Mat();
- Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
- MatType m = src.Type();
- //求 X 和 Y 方向的梯度 Sobel and scharr
- xgrad = new Mat();
- ygrad = new Mat();
- Cv2.Sobel(gray, xgrad, MatType.CV_16S, 1, 0, 3);
- Cv2.Sobel(gray, ygrad, MatType.CV_16S, 0, 1, 3);
- Cv2.ConvertScaleAbs(xgrad, xgrad);//缩放、计算绝对值并将结果转换为8位。不做转换的化显示不了,显示图相只能是8U类型
- Cv2.ConvertScaleAbs(ygrad, ygrad);
- //加强边缘检测
- //Cv2.Scharr(gray, xgrad, -1, 1, 0, 3);
- //Cv2.Scharr(gray, ygrad, -1, 0, 1, 3);
- output = new Mat(gray.Size(), gray.Type());
- //图像混合相加(基于权重 0.5)不精确
- Cv2.AddWeighted(xgrad, 0.5, ygrad, 0.5, 0, output);
- return output;
- }
- catch (Exception ex)
- {
-
- }
- finally
- {
- if (gray != null) gray.Dispose();
- if (xgrad != null) gray.Dispose();
- if (ygrad != null) gray.Dispose();
- if (output != null) gray.Dispose();
- GC.Collect();
- }
- return null;
- }
- }
- }
|