![Диалоговое окно обесцвечивания GIMP](https://i.stack.imgur.com/k3gCC.png)
Когда вы конвертируете в оттенки серого, как это (см. снимок экрана) в 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, должно быть выполнено вручную. Я адаптировал часть быстрого (хотя и небезопасного) кода, найденного здесь, чтобы создать это:
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, и, наконец, они оказались идентичными.
person
Matt J.
schedule
10.12.2013