当您在 GIMP 中像这样(见截图)转换为灰度时,它会在每个像素上调用它:
gint luminosity = GIMP_RGB_LUMINANCE (s[RED], s[GREEN], s[BLUE]) + 0.5;
查看 gimprgb.c 的源代码表明它确实在使用这些值:
#define GIMP_RGB_LUMINANCE_RED (0.2126)
#define GIMP_RGB_LUMINANCE_GREEN (0.7152)
#define GIMP_RGB_LUMINANCE_BLUE (0.0722)
我使用以下参数将 GIMP 的输出图像与 AForge 生成的图像进行了比较:
var filter = new AForge.Imaging.Filters.Grayscale(0.2126, 0.7152, 0.0722);
它们看起来相同。
更新:
似乎使用阈值工具,GIMP 正在走捷径,简单地取 R、G 或 B 的最大值。来自 threshold.c:
if (tr->color)
{
value = MAX (s[RED], s[GREEN]);
value = MAX (value, s[BLUE]);
value = (value >= tr->low_threshold &&
value <= tr->high_threshold ) ? 255 : 0;
}
else
{
value = (s[GRAY] >= tr->low_threshold &&
s[GRAY] <= tr->high_threshold) ? 255 : 0;
}
所以这可能就是你得到不同结果的原因。
更新 2:
.Net 和其他地方包含的各种“转换为灰度”方法似乎都取平均值或使用上述亮度或光度数的一些变化。我认为复制 GIMP Threshold 使用的最大值版本必须手动完成。我修改了here 发现的一些快速(尽管不安全)代码来生成这个:
public static Bitmap ColorToGrayscaleWithMax(Bitmap original)
{
unsafe
{
Bitmap newBitmap = new Bitmap(original.Width, original.Height, PixelFormat.Format8bppIndexed);
BitmapData originalData = original.LockBits(
new Rectangle(0, 0, original.Width, original.Height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData newData = newBitmap.LockBits(
new Rectangle(0, 0, original.Width, original.Height),
ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
//Set bytes per pixel
int colorBytesPerPixel = 3;
int grayBytesPerPixel = 1;
for (int y = 0; y < original.Height; y++)
{
//get the data from the original image
byte* oRow = (byte*)originalData.Scan0 + (y * originalData.Stride);
//get the data from the new image
byte* nRow = (byte*)newData.Scan0 + (y * newData.Stride);
for (int x = 0; x < original.Width; x++)
{
//create the grayscale pixel by finding the max color
byte grayScale = Math.Max(oRow[x * colorBytesPerPixel], oRow[x * colorBytesPerPixel + 1]);
grayScale = Math.Max(grayScale, oRow[x * colorBytesPerPixel + 2]);
//set the new image's pixel to the grayscale version
nRow[x * grayBytesPerPixel] = grayScale; //B
}
}
//unlock the bitmaps, finish
newBitmap.UnlockBits(newData);
original.UnlockBits(originalData);
return newBitmap;
}
}
然后你可以这样使用它:
var colorImage = AForge.Imaging.Image.FromFile(@"c:\temp\images\colorImage.png");
var preThresholdImage = ColorToGrayscaleWithMax(colorImage);
var filter = new AForge.Imaging.Filters.Threshold(100);
Bitmap bwImage = filter.Apply(preThresholdImage);
bwImage.Save(@"c:\temp\images\bwImage.png");
我在几张图像上运行它,并与使用 GIMP 手动生成的图像进行比较,它们最终看起来相同。