📄 edgedetect.cs
字号:
m.TopLeft = m.MidLeft = m.BottomLeft = 5;
Bitmap b7 = m.Convolute((Bitmap)b.Clone());
// 5 5 -3
// 5 0 -3
// -3 -3 -3
m.Init(-3);
m.Center = 0;
m.TopLeft = m.MidLeft = m.TopMid = 5;
Bitmap b8 = m.Convolute((Bitmap)b.Clone());
// 梯度运算
Bitmap b9 = Gradient(Gradient(b1, b2), Gradient(b3, b4));
Bitmap b10 = Gradient(Gradient(b5, b6), Gradient(b7, b8));
b = Gradient(b9, b10);
b1.Dispose(); b2.Dispose(); b3.Dispose(); b4.Dispose();
b5.Dispose(); b6.Dispose(); b7.Dispose(); b8.Dispose();
b9.Dispose(); b10.Dispose();
return b;
} // end of Kirsch
/// <summary>
/// 按 GaussLaplacian 算子进行边缘检测
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public Bitmap GaussLaplacian(Bitmap b)
{
int[,] kernel = {
{-2, -4, -4, -4, -2},
{-4, 0, 8, 0, -4},
{-4, 8, 24, 8, -4},
{-4, 0, 8, 0, -4},
{-2, -4, -4, -4, -2}
};
MatrixNxN m = new MatrixNxN();
m.Kernel = kernel;
return m.Convolute(b);
} // end of GaussLaplacian
/// <summary>
/// 按水平边缘检测算子进行边缘检测
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public Bitmap EdgeDetectHorizontal(Bitmap b)
{
int[,] kernel = {
{ 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0},
{-1, -1, -1, -1, -1, -1, -1},
{ 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1},
{ 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0},
};
MatrixNxN m = new MatrixNxN();
m.Kernel = kernel;
return m.Convolute(b);
} // end of EdgeDetectHorizontal
/// <summary>
/// 按垂直边缘检测算子进行边缘检测
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public Bitmap EdgeDetectVertical(Bitmap b)
{
int[,] kernel = {
{ 0, 0, -1, 0, 1, 0, 0},
{ 0, 0, -1, 0, 1, 0, 0},
{ 0, 0, -1, 0, 1, 0, 0},
{ 0, 0, -1, 0, 1, 0, 0},
{ 0, 0, -1, 0, 1, 0, 0},
{ 0, 0, -1, 0, 1, 0, 0},
{ 0, 0, -1, 0, 1, 0, 0},
};
MatrixNxN m = new MatrixNxN();
m.Kernel = kernel;
return m.Convolute(b);
} // end of EdgeDetectVertical
/// <summary>
/// 边缘增强
/// </summary>
/// <param name="b">位图流</param>
/// <param name="threshold">阈值</param>
/// <returns></returns>
public Bitmap EdgeEnhance(Bitmap b, int threshold)
{
int width = b.Width;
int height = b.Height;
Bitmap dstImage = (Bitmap)b.Clone();
BitmapData srcData = b.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData dstData = dstImage.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
// 图像实际处理区域
// 不考虑最左 1 列和最右 1 列
// 不考虑最上 1 行和最下 1 行
int rectTop = 1;
int rectBottom = height - 1;
int rectLeft = 1;
int rectRight = width - 1;
unsafe
{
byte* src = (byte*)srcData.Scan0;
byte* dst = (byte*)dstData.Scan0;
int stride = srcData.Stride;
int offset = stride - width * BPP;
int pixel = 0;
int maxPixel = 0;
// 指向第 1 行
src += stride;
dst += stride;
for (int y = rectTop; y < rectBottom; y++)
{
// 指向每行第 1 列像素
src += BPP;
dst += BPP;
for (int x = rectLeft; x < rectRight; x++)
{
// Alpha
dst[3] = src[3];
// 处理 B, G, R 三分量
for (int i = 0; i < 3; i++)
{
// 右上-左下
maxPixel = src[i - stride + BPP] - src[i + stride - BPP];
if (maxPixel < 0) maxPixel = -maxPixel;
// 左上-右下
pixel = src[i - stride - BPP] - src[i + stride + BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 上-下
pixel = src[i - stride] - src[i + stride];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 左-右
pixel = src[i - BPP] - src[i + BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 进行阈值判断
if (maxPixel < threshold) maxPixel = 0;
dst[i] = (byte)maxPixel;
}
// 向后移一像素
src += BPP;
dst += BPP;
} // x
// 移向下一行
// 这里得注意要多移 1 列,因最右边还有 1 列不必处理
src += offset + BPP;
dst += offset + BPP;
} // y
}
b.UnlockBits(srcData);
dstImage.UnlockBits(dstData);
b.Dispose();
return dstImage;
} // end of EdgeEnhance
/// <summary>
/// 边缘均衡化
/// </summary>
/// <param name="b">位图流</param>
/// <param name="threshold">阈值</param>
/// <returns></returns>
public Bitmap EdgeHomogenize(Bitmap b, int threshold)
{
int width = b.Width;
int height = b.Height;
Bitmap dstImage = (Bitmap)b.Clone();
BitmapData srcData = b.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BitmapData dstData = dstImage.LockBits(new Rectangle(0, 0, width, height),
ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
// 图像实际处理区域
// 不考虑最左 1 列和最右 1 列
// 不考虑最上 1 行和最下 1 行
int rectTop = 1;
int rectBottom = height - 1;
int rectLeft = 1;
int rectRight = width - 1;
unsafe
{
byte* src = (byte*)srcData.Scan0;
byte* dst = (byte*)dstData.Scan0;
int stride = srcData.Stride;
int offset = stride - width * BPP;
int pixel = 0;
int maxPixel = 0;
// 指向第 1 行
src += stride;
dst += stride;
for (int y = rectTop; y < rectBottom; y++)
{
// 指向每行第 1 列像素
src += BPP;
dst += BPP;
for (int x = rectLeft; x < rectRight; x++)
{
// Alpha
dst[3] = src[3];
// 处理 B, G, R 三分量
for (int i = 0; i < 3; i++)
{
// 上
maxPixel = src[i] - src[i - stride];
if (maxPixel < 0) maxPixel = -maxPixel;
// 右上
pixel = src[i] - src[i - stride + BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 右
pixel = src[i] - src[i + BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 右下
pixel = src[i] - src[i + stride + BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 下
pixel = src[i] - src[i + stride];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 左下
pixel = src[i] - src[i + stride - BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 左
pixel = src[i] - src[i - BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 左上
pixel = src[i] - src[i - stride - BPP];
if (pixel < 0) pixel = -pixel;
if (pixel > maxPixel) maxPixel = pixel;
// 进行阈值判断
if (maxPixel < threshold) maxPixel = 0;
dst[i] = (byte)maxPixel;
}
// 向后移一像素
src += BPP;
dst += BPP;
} // x
// 移向下一行
// 这里得注意要多移 1 列,因最右边还有 1 列不必处理
src += offset + BPP;
dst += offset + BPP;
} // y
}
b.UnlockBits(srcData);
dstImage.UnlockBits(dstData);
b.Dispose();
return dstImage;
} // end of EdgeHomogenize
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -