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();
}
}
}
}