using OpenCvSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PaintDotNet.Adjust { public class EdgeDetectionIntent { /// /// Log /// /// /// public static Mat ImageLog(Mat src) { Mat gray = null; Mat gray1 = null; Mat dstImage = null; try { gray = new Mat(); //将原图像转换为灰度图像 Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY); gray1 = new Mat(); //先做高斯模糊 Cv2.GaussianBlur(gray, gray1, new OpenCvSharp.Size(3, 3), 0); dstImage = new Mat(); //拉普拉斯变换 Cv2.Laplacian(gray1, dstImage, MatType.CV_16S, 3); Cv2.ConvertScaleAbs(dstImage, dstImage); dstImage.CopyTo(src); return src; } catch (Exception ex) { throw ex; } finally { if (gray != null) gray.Dispose(); if (gray1 != null) gray1.Dispose(); if (dstImage != null) dstImage.Dispose(); GC.Collect(); } } /// /// Canny /// /// /// public static Mat ImageCanny(Mat src, List lists) { Mat src_gray = null; try { //过滤尺寸(最大/最小),需要填写数值 int size1 = 20; int size2 = 100; //西格玛值 double SigmaValue = 1.5; foreach (Base.Args args in lists) { switch (args.key) { case "KernelSize1": size1 = int.Parse(args.Value.ToString()); break; case "KernelSize2": size2 = int.Parse(args.Value.ToString()); break; case "Sigma": SigmaValue = double.Parse(args.Value.ToString()); break; } } src_gray = new Mat(); //该算法对噪声敏感,必须降噪 Cv2.GaussianBlur(src, src_gray, new OpenCvSharp.Size(3, 3), SigmaValue); //将原图像转换为灰度图像 Cv2.CvtColor(src_gray, src_gray, ColorConversionCodes.BGR2GRAY); Cv2.Canny(src_gray, src_gray, size1, size2); src_gray.CopyTo(src); return src; } catch (Exception ex) { throw ex; } finally { if(src_gray!=null) src_gray.Dispose(); GC.Collect(); } } /// /// Sobel /// /// /// 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(xgrad.Size(), xgrad.Type()); //图像混合相加(基于权重 0.5)不精确 //Cv2.AddWeighted(xgrad, 0.5, ygrad, 0.5, 0, output); //基于 算法 G=|Gx|+|Gy| int width = xgrad.Cols; int hight = xgrad.Rows; //基于 G= (Gx*Gx +Gy*Gy)的开方根 for (int x = 0; x < hight; x++) { for (int y = 0; y < width; y++) { int xg = xgrad.At(x, y); int yg = ygrad.At(x, y); double v1 = Math.Pow(xg, 2); double v2 = Math.Pow(yg, 2); int val = (int)Math.Sqrt(v1 + v2); if (val > 255) //确保像素值在 0 -- 255 之间 { val = 255; } if (val < 0) { val = 0; } byte xy = (byte)val; output.Set(x, y, xy); } } output.CopyTo(src); return src; } catch (Exception ex) { throw ex; } finally { if (gray != null) gray.Dispose(); if (xgrad != null) gray.Dispose(); if (ygrad != null) gray.Dispose(); if (output != null) gray.Dispose(); GC.Collect(); } } /// /// Kirsch /// /// /// public static Mat ImageKirsch(Mat src) { Mat src_gray = null; Mat dst = null; try { dst = new Mat(); src_gray = new Mat(); Cv2.CvtColor(src, src_gray, ColorConversionCodes.BGR2GRAY); List dstImages = new List(); for (int i = 0; i < 8; i++) { dstImages.Add(new Mat()); } InputArray kernel1 = InputArray.Create(new int[3, 3] { { 5, 5, 5 }, { -3, 0, -3 }, { -3, -3, -3 } }); InputArray kernel2 = InputArray.Create(new int[3, 3] { { -3, 5, 5 }, { -3, 0, 5 }, { -3, -3, -3 } }); InputArray kernel3 = InputArray.Create(new int[3, 3] { { -3, -3, 5 }, { -3, 0, 5 }, { -3, -3, 5 } }); InputArray kernel4 = InputArray.Create(new int[3, 3] { { -3, -3, -3 }, { -3, 0, 5 }, { -3, 5, 5 } }); InputArray kernel5 = InputArray.Create(new int[3, 3] { { -3, -3, -3 }, { -3, 0, -3 }, { 5, 5, 5 } }); InputArray kernel6 = InputArray.Create(new int[3, 3] { { -3, -3, -3 }, { 5, 0, -3 }, { 5, 5, -3 } }); InputArray kernel7 = InputArray.Create(new int[3, 3] { { 5, -3, -3 }, { 5, 0, -3 }, { 5, -3, -3 } }); InputArray kernel8 = InputArray.Create(new int[3, 3] { { 5, 5, -3 }, { 5, 0, -3 }, { -3, -3, -3 } }); Cv2.Filter2D(src_gray, dstImages[0], MatType.CV_8U, kernel1); Cv2.Filter2D(src_gray, dstImages[1], MatType.CV_8U, kernel2); Cv2.Filter2D(src_gray, dstImages[2], MatType.CV_8U, kernel3); Cv2.Filter2D(src_gray, dstImages[3], MatType.CV_8U, kernel4); Cv2.Filter2D(src_gray, dstImages[4], MatType.CV_8U, kernel5); Cv2.Filter2D(src_gray, dstImages[5], MatType.CV_8U, kernel6); Cv2.Filter2D(src_gray, dstImages[6], MatType.CV_8U, kernel7); Cv2.Filter2D(src_gray, dstImages[7], MatType.CV_8U, kernel8); for (int i = 0; i < dstImages.Count(); i++) { dstImages[i] = Cv2.Abs(dstImages[i]); } dst = dstImages[0]; for (int i = 1; i < dstImages.Count(); i++) { Cv2.Max(dst, dstImages[i], dst); } dst.CopyTo(src); return src; } catch(Exception e) { throw e; } finally { if (src_gray != null) src_gray.Dispose(); if (dst != null) dst.Dispose(); GC.Collect(); } } /// /// Prewitt /// /// /// public static Mat ImagePrewitt(Mat src) { Mat grad_x = null, grad_y = null, gray = null, grad = null, abs_grad_x =null, abs_grad_y=null; try { grad_x = new Mat(); grad_y = new Mat(); abs_grad_x = new Mat(); abs_grad_y = new Mat(); gray = new Mat(); //将原图像转换为灰度图像 Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY); //定义卷积核 InputArray kernelx = InputArray.Create(new double[3, 3] { { 1, 0, -1 }, { 1, 0, -1 }, { 1, 0, -1 } }); InputArray kernely = InputArray.Create(new double[3, 3] { { -1, -1, -1 }, { 0, 0, 0 }, { 1, 1, 1 } }); //卷积运算 Cv2.Filter2D(gray, grad_x, MatType.CV_16S, kernelx); Cv2.Filter2D(gray, grad_y, MatType.CV_16S, kernely); //转为8位 Cv2.ConvertScaleAbs(grad_x, abs_grad_x); Cv2.ConvertScaleAbs(grad_y, abs_grad_y); grad = new Mat(abs_grad_x.Size(), abs_grad_x.Type()); //图像混合相加(基于权重 0.5)不精确 //Cv2.AddWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad); //基于 算法 G=|Gx|+|Gy| int width = abs_grad_x.Cols; int height = abs_grad_x.Rows; //基于 G= (Gx*Gx +Gy*Gy)的开方根 for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { int xg = abs_grad_x.At(x, y); int yg = abs_grad_y.At(x, y); //int val = (int)Math.Sqrt(xg * xg + yg * yg); grad.Set(x, y, Math.Max(xg, yg)); } } grad.CopyTo(src); return src; } catch(Exception e) { throw e; } finally { if (grad_x != null) grad_x.Dispose(); if (grad_y != null) grad_y.Dispose(); if (gray != null) gray.Dispose(); if (grad != null) grad.Dispose(); if (abs_grad_x != null) abs_grad_x.Dispose(); if (abs_grad_y != null) abs_grad_y.Dispose(); GC.Collect(); } } /// /// Roberts /// /// 源 /// 目标 public static Mat ImageRoberts(Mat src) { Mat output = null; Mat src_gray = null; Mat dstImageX = null; Mat dstImageY = null; try { src_gray = new Mat(); Cv2.CvtColor(src, src_gray, ColorConversionCodes.BGR2GRAY); dstImageX = src_gray.Clone(); dstImageY = src_gray.Clone(); //Robert算子 X向量 InputArray kernelRX = InputArray.Create(new int[2, 2] { { -1, 0 }, { 0, 1 } }); Cv2.Filter2D(src_gray, dstImageX, MatType.CV_16S, kernelRX, new OpenCvSharp.Point(-1, -1), 0); ////Robert算子 Y向量 InputArray kernelRY = InputArray.Create(new int[2, 2] { { 0, -1 }, { 1, 0 } }); Cv2.Filter2D(src_gray, dstImageY, MatType.CV_16S, kernelRY, new OpenCvSharp.Point(-1, -1), 0); Cv2.ConvertScaleAbs(dstImageX, dstImageX); Cv2.ConvertScaleAbs(dstImageY, dstImageY); output = new Mat(dstImageX.Size(), dstImageY.Type()); //图像混合相加(基于权重 0.5)不精确 //Cv2.AddWeighted(dstImageX, 0.5, dstImageY, 0.5, 0, output); //基于 算法 G=|Gx|+|Gy| int width = dstImageX.Cols; int height = dstImageY.Rows; //基于 G= (Gx*Gx +Gy*Gy)的开方根 for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { int xg = dstImageX.At(x, y); int yg = dstImageY.At(x, y); double v1 = Math.Pow(xg, 2); double v2 = Math.Pow(yg, 2); int val = (int)Math.Sqrt(v1 + v2); if (val > 255) //确保像素值在 0 -- 255 之间 { val = 255; } if (val < 0) { val = 0; } byte xy = (byte)val; output.Set(x, y, xy); } } output.CopyTo(src); return src; } catch (Exception ex) { throw ex; } finally { if (src_gray != null) src_gray.Dispose(); if (dstImageX != null) dstImageX.Dispose(); if (dstImageY != null) dstImageY.Dispose(); if (output != null) output.Dispose(); GC.Collect(); } } /// /// Laplacian /// /// /// public static Mat ImageLaplace(Mat src) { Mat gray = null, dstImage = null; try { gray = new Mat(); dstImage = new Mat(); Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY); Cv2.Laplacian(gray, dstImage, MatType.CV_16S, 1); Cv2.ConvertScaleAbs(dstImage, dstImage); dstImage.CopyTo(src); return src; } catch (Exception ex) { throw ex; } finally { if (gray != null) gray.Dispose(); if (dstImage != null) dstImage.Dispose(); GC.Collect(); } } } }