public unsafe Bitmap MedianFilter(Bitmap Img)
{
int Size =2;
List<byte> R = new List<byte>();
List<byte> G = new List<byte>();
List<byte> B = new List<byte>();
int ApetureMin = -(Size / 2);
int ApetureMax = (Size / 2);
BitmapData imageData = Img.LockBits(new Rectangle(0, 0, Img.Width, Img.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
byte* start = (byte*)imageData.Scan0.ToPointer ();
for (int x = 0; x < imageData.Width; x++)
{
for (int y = 0; y < imageData.Height; y++)
{
for (int x1 = ApetureMin; x1 < ApetureMax; x1++)
{
int valx = x + x1;
if (valx >= 0 && valx < imageData.Width)
{
for (int y1 = ApetureMin; y1 < ApetureMax; y1++)
{
int valy = y + y1;
if (valy >= 0 && valy < imageData.Height)
{
Color tempColor = Img.GetPixel(valx, valy);// error come from here
R.Add(tempColor.R);
G.Add(tempColor.G);
B.Add(tempColor.B);
}
}
}
}
}
}
R.Sort();
G.Sort();
B.Sort();
Img.UnlockBits(imageData);
return Img;
}
我试过这样做。但我收到一个错误消息“位图区域已被锁定”任何人都可以帮助解决这个问题。 (错误位置高亮显示)
请您参考如下方法:
GetPixel 是访问图像的 slooow 方法,如果其他人开始直接弄乱图像缓冲区,它就不再起作用(正如您所注意到的)。为什么要这样做?
检查 Using the LockBits method to access image data以获得对快速图像处理的一些深入了解。
在这种情况下,请改用这样的东西:
int pixelSize = 4 /* Check below or the site I linked to and make sure this is correct */
byte* color =(byte *)imageData .Scan0+(y*imageData .Stride) + x * pixelSize;
请注意,这为您提供了该像素的第一个字节。根据您正在查看的颜色格式(ARGB?RGB?..),您还需要访问以下字节。似乎无论如何都适合您的用例,因为您只关心字节值,而不是 Color 值。
所以,经过一些空闲时间,这就是我想出的(请花点时间理解和检查它,我只是确保它可以编译):
public void SomeStuff(Bitmap image)
{
var imageWidth = image.Width;
var imageHeight = image.Height;
var imageData = image.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
var imageByteCount = imageData.Stride*imageData.Height;
var imageBuffer = new byte[imageByteCount];
Marshal.Copy(imageData.Scan0, imageBuffer, 0, imageByteCount);
for (int x = 0; x < imageWidth; x++)
{
for (int y = 0; y < imageHeight; y++)
{
var pixelColor = GetPixel(imageBuffer, imageData.Stride, x, y);
// Do your stuff
}
}
}
private static Color GetPixel(byte[] imageBuffer, int imageStride, int x, int y)
{
int pixelBase = y*imageStride + x*3;
byte blue = imageBuffer[pixelBase];
byte green = imageBuffer[pixelBase + 1];
byte red = imageBuffer[pixelBase + 2];
return Color.FromArgb(red, green, blue);
}
这个
- 取决于您在示例中使用的
PixelFormat(关于像素大小/每像素字节数和值的顺序)。如果您更改PixelFormat,这将中断。 - 不需要不安全关键字。我怀疑这会有很大的不同,但您可以自由使用基于指针的访问,方法是相同的。
