//
BitmapData bmData = m_Bitmap.LockBits(new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
float valve = 50;
for (int i = 0; i < 256; i++)
gray[i] = 0;
unsafe
{
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
byte* p = (byte*)(void*)Scan0;
byte* pp;
int tt;
int nOffset = stride - m_Bitmap.Width * 3;
int nWidth = m_Bitmap.Width;
int nHeight = m_Bitmap.Height;
int Sx = 0;
int Sy = 0;
// float max = 0;
double sumM = 0;
double sumCount = 0;
int[] marginalMx = { -1, 0, 1, -2, 0, 2, -1, 0, 1 }; //sobel模板
int[] marginalMy = { 1, 2, 1, 0, 0, 0, -1, -2, -1 };
int[,] dlta = new int[nHeight, nWidth];
for (int y = 0; y < nHeight; ++y) //sobel算子
{
for (int x = 0; x < nWidth; ++x)
{
if (!(x <= 0 || x >= nWidth - 1 || y <= 0 || y >= nHeight - 1))//该过
{
pp = p;
Sx = 0;
Sy = 0;
for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
{
pp += (j * 3 + stride * i);
Sx += pp[0] * marginalMx[(i + 1) * 3 + j + 1];
Sy += pp[0] * marginalMy[(i + 1) * 3 + j + 1];
pp = p;
}
m[y, x] = (int)(Math.Sqrt(Sx * Sx + Sy * Sy));
if (m[y, x] > valve / 2) //增强白点
{
if (p[0] > 240)
{
m[y, x] += valve;
}
else if (p[0] > 220)
{
m[y, x] += (float)(valve * 0.8);
}
else if (p[0] > 200)
{
m[y, x] += (float)(valve * 0.6);
}
else if (p[0] > 180)
{
m[y, x] += (float)(valve * 0.4);
}
else if (p[0] > 160)
{
m[y, x] += (float)(valve * 0.2);
}
}
float tan;
if (Sx != 0)
{
tan = Sy / Sx;
}
else tan = 10000;
if (-0.41421356 <= tan && tan < 0.41421356)//角度为-22.5度到22.5度之间
{
dlta[y, x] = 0; // m[y,x]+=valve;
}
else if (0.41421356 <= tan && tan < 2.41421356)//角度为22.5度到67.5度之间
{
dlta[y, x] = 1; //m[y,x] = 0;
}
else if (tan >= 2.41421356 || tan < -2.41421356)//角度为67.5度到90度之间或-90度到-67.5度
{
dlta[y, x] = 2; // m[y,x]+=valve;
}
else
{
dlta[y, x] = 3;//m[y,x] = 0;
}
}
else
m[y, x] = 0;
p += 3;
if (m[y, x] > 0)
{
sumCount++;
sumM += m[y, x];
}
}
p += nOffset;
}
unsafe
{
p = (byte*)(void*)Scan0; //非极大值抑制和阀值
for (int y = 0; y < nHeight; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
if (m[y, x] > sumM / sumCount * 1.2)
{
p[0] = p[1] = p[2] = (byte)(m[y, x]); //m[y,x]=1;
}
else
{
m[y, x] = 0;
p[0] = p[1] = p[2] = 0;
}
if (x >= 1 && x <= nWidth - 1 && y >= 1 && y <= nHeight - 1 && m[y, x] > valve)
{
switch (dlta[y, x])
{
case 0:
if (m[y, x] >= m[y, x - 1] && m[y, x] >= m[y, x + 1])//水平边缘
{
p[0] = p[1] = p[2] = 255;
}
break;
case 1:
if (m[y, x] >= m[y + 1, x - 1] && m[y, x] >= m[y - 1, x + 1])//正斜45度边缘
{
p[0] = p[1] = p[2] = 255;
}
break;
case 2:
if (m[y, x] >= m[y - 1, x] && m[y, x] >= m[y + 1, x])//垂直边缘
{
p[0] = p[1] = p[2] = 255;
}
break;
case 3:
if (m[y, x] >= m[y + 1, x + 1] && m[y, x] >= m[y - 1, x - 1])//反斜45度边缘
{
p[0] = p[1] = p[2] = 255;
}
break;
}
}
if (p[0] == 255)
{
m[y, x] = 1;
}
else
{
m[y, x] = 0;
p[0] = p[1] = p[2] = 0;
}
tt = p[0];
gray[tt]++;
p += 3;
}
// p += nOffset;
}
m_Bitmap.UnlockBits(bmData);
}
}
pictureBox1.Image = m_Bitmap;
来源GitHub