我有位图。我想将中值滤波器应用于我的位图。但是我不能使用GetPixel()和SetPixel(),因为速度对我来说是非常重要的因素。我需要非常快速的方法来做到这一点。可以使用Graphics.DrawImage(Image, Point[], Rectangle, GraphicsUnit, ImageAttributes)
来完成。
中值滤波后我想应用二值化滤波器(对于每个像素计算亮度:B = 0.299 * R + 0.5876 * G + 0.114B,如果亮度小于thresholdValue(thresholdValue是参数,我的任务在[0 ... 255])然后结果图像中我的像素值为1,否则 - 0)二进制化滤波器中的速度对我来说也很重要
答案 0 :(得分:7)
刚刚找到此链接:A fast way to grayscale an image in .NET (C#)
/// <summary>
/// Grayscales a given image.
/// </summary>
/// <param name="image">
/// The image that is transformed to a grayscale image.
/// </param>
public static void GrayScaleImage(Bitmap image)
{
if (image == null)
throw new ArgumentNullException("image");
// lock the bitmap.
var data = image.LockBits(
new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, image.PixelFormat);
try
{
unsafe
{
// get a pointer to the data.
byte* ptr = (byte*)data.Scan0;
// loop over all the data.
for (int i = 0; i < data.Height; i++)
{
for (int j = 0; j < data.Width; j++)
{
// calculate the gray value.
byte y = (byte)(
(0.299 * ptr[2]) +
(0.587 * ptr[1]) +
(0.114 * ptr[0]));
// set the gray value.
ptr[0] = ptr[1] = ptr[2] = y;
// increment the pointer.
ptr += 3;
}
// move on to the next line.
ptr += data.Stride - data.Width * 3;
}
}
}
finally
{
// unlock the bits when done or when
// an exception has been thrown.
image.UnlockBits(data);
}
}
编辑:查看更多信息:
答案 1 :(得分:0)
使用CopyPixels
将数据复制到数组,然后对阵列进行操作。这是一个代码片段,我采用的是平均颜色:
int stride = (bmp.PixelWidth * bmp.Format.BitsPerPixel + 7) / 8;
byte[] pixels = new byte[bmp.PixelHeight * stride];
bmp.CopyPixels(pixels, stride, 0);
double[] averageComponents = new double[bmp.Format.BitsPerPixel / 8];
for (int pixel = 0; pixel < pixels.Length; pixel += averageComponents.Length)
{
for (int component = 0; component < averageComponents.Length; component++)
{
averageComponents[component] += pixels[pixel + component];
}
}
您正在使用的过滤器应该运行得足够快,无需进一步优化(只是不要做一些算法慢的事情)。
答案 2 :(得分:0)
如果复制速度太慢,请使用LockBits和不安全的块直接修改生成的BitmapData结构。