所以我尝试使用带有不安全代码的C#进行平滑过滤
public static bool Conv5x5(Bitmap b, double[,] m, int factor, int offset)
{
if (0 == factor)
return false;
Bitmap bSrc = (Bitmap)b.Clone();
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
int stride2 = stride * 2;
int stride3 = stride * 3;
int stride4 = stride * 4;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;
unsafe
{
byte* p = (byte*)(void*)Scan0;
byte* pSrc = (byte*)(void*)SrcScan0;
int nOffset = stride - b.Width * 3;
int nWidth = b.Width - 4;
int nHeight = b.Height - 4;
int nPixel;
for (int y = 0; y < nHeight; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
nPixel = Convert.ToInt32((((pSrc[4] * m[0, 0]) + (pSrc[9] * m[0, 1]) + (pSrc[14] * m[0, 2]) + (pSrc[19] * m[0, 3]) + (pSrc[24] * m[0, 4]) +
(pSrc[4 + stride] * m[1, 0]) + (pSrc[9 + stride] * m[1, 0]) + (pSrc[14 + stride] * m[1, 0]) + (pSrc[19 + stride] * m[1, 0]) + (pSrc[24 + stride] * m[1, 0]) +
(pSrc[4 + stride2] * m[2, 0]) + (pSrc[9 + stride2] * m[2, 1]) + (pSrc[14 + stride2] * m[2, 2]) + (pSrc[19 + stride2] * m[2, 3]) + (pSrc[24 + stride2] * m[2, 4]) +
(pSrc[4 + stride3] * m[3, 0]) + (pSrc[9 + stride3] * m[3, 1]) + (pSrc[14 + stride3] * m[3, 2]) + (pSrc[19 + stride3] * m[3, 3]) + (pSrc[24 + stride3] * m[3, 4]) +
(pSrc[4 + stride4] * m[4, 0]) + (pSrc[9 + stride4] * m[4, 1]) + (pSrc[14 + stride4] * m[4, 2]) + (pSrc[19 + stride4] * m[4, 3]) + (pSrc[24 + stride4] * m[4, 4])
) / factor) + offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[9 + stride] = (byte)nPixel;
nPixel = Convert.ToInt32((((pSrc[3] * m[0, 0]) + (pSrc[8] * m[0, 1]) + (pSrc[13] * m[0, 2]) + (pSrc[18] * m[0, 3]) + (pSrc[23] * m[0, 4]) +
(pSrc[3 + stride] * m[1, 0]) + (pSrc[8 + stride] * m[1, 0]) + (pSrc[13 + stride] * m[1, 0]) + (pSrc[18 + stride] * m[1, 0]) + (pSrc[23 + stride] * m[1, 0]) +
(pSrc[3 + stride2] * m[2, 0]) + (pSrc[8 + stride2] * m[2, 1]) + (pSrc[13 + stride2] * m[2, 2]) + (pSrc[18 + stride2] * m[2, 3]) + (pSrc[23 + stride2] * m[2, 4]) +
(pSrc[3 + stride3] * m[3, 0]) + (pSrc[8 + stride3] * m[3, 1]) + (pSrc[13 + stride3] * m[3, 2]) + (pSrc[18 + stride3] * m[3, 3]) + (pSrc[23 + stride3] * m[3, 4]) +
(pSrc[3 + stride4] * m[4, 0]) + (pSrc[8 + stride4] * m[4, 1]) + (pSrc[13 + stride4] * m[4, 2]) + (pSrc[18 + stride4] * m[4, 3]) + (pSrc[23 + stride4] * m[4, 4])
) / factor) + offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[8 + stride] = (byte)nPixel;
nPixel = Convert.ToInt32((((pSrc[2] * m[0, 0]) + (pSrc[7] * m[0, 1]) + (pSrc[12] * m[0, 2]) + (pSrc[17] * m[0, 3]) + (pSrc[22] * m[0, 4]) +
(pSrc[2 + stride] * m[1, 0]) + (pSrc[7 + stride] * m[1, 0]) + (pSrc[12 + stride] * m[1, 0]) + (pSrc[17 + stride] * m[1, 0]) + (pSrc[22 + stride] * m[1, 0]) +
(pSrc[2 + stride2] * m[2, 0]) + (pSrc[7 + stride2] * m[2, 1]) + (pSrc[12 + stride2] * m[2, 2]) + (pSrc[17 + stride2] * m[2, 3]) + (pSrc[22 + stride2] * m[2, 4]) +
(pSrc[2 + stride3] * m[3, 0]) + (pSrc[7 + stride3] * m[3, 1]) + (pSrc[12 + stride3] * m[3, 2]) + (pSrc[17 + stride3] * m[3, 3]) + (pSrc[22 + stride3] * m[3, 4]) +
(pSrc[2 + stride4] * m[4, 0]) + (pSrc[7 + stride4] * m[4, 1]) + (pSrc[12 + stride4] * m[4, 2]) + (pSrc[17 + stride4] * m[4, 3]) + (pSrc[22 + stride4] * m[4, 4])
) / factor) + offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[7 + stride] = (byte)nPixel;
nPixel = Convert.ToInt32((((pSrc[1] * m[0, 0]) + (pSrc[6] * m[0, 1]) + (pSrc[11] * m[0, 2]) + (pSrc[16] * m[0, 3]) + (pSrc[21] * m[0, 4]) +
(pSrc[1 + stride] * m[1, 0]) + (pSrc[6 + stride] * m[1, 0]) + (pSrc[11 + stride] * m[1, 0]) + (pSrc[16 + stride] * m[1, 0]) + (pSrc[21 + stride] * m[1, 0]) +
(pSrc[1 + stride2] * m[2, 0]) + (pSrc[6 + stride2] * m[2, 1]) + (pSrc[11 + stride2] * m[2, 2]) + (pSrc[16 + stride2] * m[2, 3]) + (pSrc[21 + stride2] * m[2, 4]) +
(pSrc[1 + stride3] * m[3, 0]) + (pSrc[6 + stride3] * m[3, 1]) + (pSrc[11 + stride3] * m[3, 2]) + (pSrc[16 + stride3] * m[3, 3]) + (pSrc[21 + stride3] * m[3, 4]) +
(pSrc[1 + stride4] * m[4, 0]) + (pSrc[6 + stride4] * m[4, 1]) + (pSrc[11 + stride4] * m[4, 2]) + (pSrc[16 + stride4] * m[4, 3]) + (pSrc[21 + stride4] * m[4, 4])
) / factor) + offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[6 + stride] = (byte)nPixel;
nPixel = Convert.ToInt32((((pSrc[0] * m[0, 0]) + (pSrc[5] * m[0, 1]) + (pSrc[10] * m[0, 2]) + (pSrc[15] * m[0, 3]) + (pSrc[20] * m[0, 4]) +
(pSrc[0 + stride] * m[1, 0]) + (pSrc[5 + stride] * m[1, 0]) + (pSrc[10 + stride] * m[1, 0]) + (pSrc[15 + stride] * m[1, 0]) + (pSrc[20 + stride] * m[1, 0]) +
(pSrc[0 + stride2] * m[2, 0]) + (pSrc[5 + stride2] * m[2, 1]) + (pSrc[10 + stride2] * m[2, 2]) + (pSrc[15 + stride2] * m[2, 3]) + (pSrc[20 + stride2] * m[2, 4]) +
(pSrc[0 + stride3] * m[3, 0]) + (pSrc[5 + stride3] * m[3, 1]) + (pSrc[10 + stride3] * m[3, 2]) + (pSrc[15 + stride3] * m[3, 3]) + (pSrc[20 + stride3] * m[3, 4]) +
(pSrc[0 + stride4] * m[4, 0]) + (pSrc[5 + stride4] * m[4, 1]) + (pSrc[10 + stride4] * m[4, 2]) + (pSrc[15 + stride4] * m[4, 3]) + (pSrc[20 + stride4] * m[4, 4])
) / factor) + offset);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[5 + stride] = (byte)nPixel;
p += 5;
pSrc += 5;
}
p += nOffset;
pSrc += nOffset;
}
}
b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);
return true;
}
使用我的默认参数:
public static double[,] Smooth5x5
{
get
{
return new double[,]
{ { 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1}, };
}
}
int factor=25; int offset=0;
我有这个错误: “附加信息:尝试读取或写入受保护的内存。这通常表示其他内存已损坏。”
有人可以帮忙吗?
答案 0 :(得分:0)
所以,这是一个解决方案:此外,这里是所有卷积滤波器和所有卷积矩阵大小的通用卷积函数:
public bool universalConv(Bitmap b, double[,] m, int factor, int offset, byte fill)
{
int convMatrixWidth = m.GetLength(0);
int convMatrixHeight = m.GetLength(1);
// Avoid divide by zero errors
if (0 == factor)
return false;
Bitmap bSrc = new Bitmap(b.Width + convMatrixWidth - 1, b.Height + convMatrixHeight - 1, b.PixelFormat);
bSrc = fillBitmapWith(bSrc, fill);
Graphics g = Graphics.FromImage(bSrc);
g.DrawImage(b, 0, 0, b.Width, b.Height);
g.Dispose();
// GDI+ still lies to us - the return format is BGR, NOT RGB.
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
int stridetmp = bmSrc.Stride;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr SrcScan0 = bmSrc.Scan0;
unsafe
{
byte* p = (byte*)(void*)Scan0;
byte* pSrc = (byte*)(void*)SrcScan0;
int nOffset = stride - b.Width * 3;
int nOffsettmp = stridetmp - bSrc.Width * 3;
int nWidth = b.Width;
int nHeight = b.Height - convMatrixWidth / 2;
int nPixel, nPixel2, nPixel3;
for (int y = 0; y < nHeight; y++)
{
for (int x = 0; x < nWidth; x++)
{
nPixel = nPixel2 = nPixel3 = 0;
for (int i = 0; i < convMatrixHeight; i++)
{
for (int j = 0; j < convMatrixWidth; j++)
{
nPixel += Convert.ToInt32(pSrc[2 + (j * 3) + i * stridetmp] * m[i, j]);
nPixel2 += Convert.ToInt32(pSrc[1 + (j * 3) + i * stridetmp] * m[i, j]);
nPixel3 += Convert.ToInt32(pSrc[0 + (j * 3) + i * stridetmp] * m[i, j]);
}
}
nPixel = nPixel / factor + offset;
nPixel2 = nPixel2 / factor + offset;
nPixel3 = nPixel3 / factor + offset;
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[2 + stride * (convMatrixWidth / 2)] = (byte)nPixel;
if (nPixel2 < 0) nPixel2 = 0;
if (nPixel2 > 255) nPixel2 = 255;
p[1 + stride * (convMatrixWidth / 2)] = (byte)nPixel2;
if (nPixel3 < 0) nPixel3 = 0;
if (nPixel3 > 255) nPixel3 = 255;
p[0 + stride * (convMatrixWidth / 2)] = (byte)nPixel3;
p += 3;
pSrc += 3;
}
p += nOffset;
pSrc += (nOffsettmp + (convMatrixWidth - 1) * 3);
}
}
b.UnlockBits(bmData);
bSrc.UnlockBits(bmSrc);
return true;
}