Каковы параметры фильтра оттенков серого Aforge?

Я использую Aforge.Net для обработки изображений, и у меня возникают проблемы с пониманием фильтр оттенков серого. В частности, три обязательных параметра конструктора коэффициентов красного/зеленого/синего цветов.

Насколько я понимаю (из исследования сегментации изображений восемь лет назад), градация серого — это операция, которая не должна принимать никаких параметров. Вы берете изображение и извлекаете канал люминесценции, вот и все.

Так что же это за параметры и как просто извлечь люминесценцию?

Обновление: я должен уточнить, что я пытаюсь сделать. Я пытаюсь автоматизировать процесс, который я могу сделать вручную в GIMP. В GIMP я могу применить порог к любому изображению, и он работает с гистограммой люминесценции для создания бинарного изображения, однако в Aforge фильтр порога работает только с изображениями в градациях серого. Итак, как мне воспроизвести мой ручной процесс?


person George Mauer    schedule 09.12.2013    source источник


Ответы (2)


Диалоговое окно обесцвечивания GIMP

Когда вы конвертируете в оттенки серого, как это (см. снимок экрана) в 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
comment
Большое спасибо, эти цифры по-прежнему не дают мне точных результатов, которые я вижу в GIMP, но я подозреваю, что теперь проблема заключается в том, что я неправильно понимаю, как пороговый фильтр GIMP работает при применении к цветным изображениям. Я создам другую тему для этого, если я не могу понять это. - person George Mauer; 11.12.2013
comment
У меня тоже были другие результаты. Обновлен ответ, чтобы отразить, что пороговый инструмент на самом деле не рассчитывает яркость, а просто макс. R/G/B. - person Matt J.; 11.12.2013
comment
вау, интересно (а также на самом деле объясняет результаты, которые я вижу) какие-нибудь советы о том, как реализовать это с помощью Aforge (в результате получается изображение в оттенках серого)? Я полагаю, что могу отследить исходный код фильтра оттенков серого... но мне интересно, есть ли лучший подход. - person George Mauer; 11.12.2013
comment
Photoshop, Imagemagick и т. д., похоже, реализуют более сложное преобразование. Gimp кажется странным, поэтому приходится реализовывать вручную. (обновлено) - person Matt J.; 11.12.2013

Преобразование RGB в оттенки серого требует взвешенной суммы по каналам RGB. А мера цветового свечения включает нелинейное преобразование, называемое гамма-коррекция. Это тоже взвешенная сумма, но по R^gamma, G^gamma и B^gamma соответственно. Дополнительные формулы описаны здесь.

person lennon310    schedule 09.12.2013
comment
Вроде выше моей головы там. Итак, на что влияют эти значения и на что мне их установить, чтобы мое изображение в градациях серого было эквивалентно простому извлечению люминесценции? - person George Mauer; 10.12.2013
comment
Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma для стандартной яркости или 0,2989*R+ 0,5870 * G + 0,1140 * B для воспринимаемого варианта. - person lennon310; 10.12.2013
comment
Все еще не совсем уверен, что представляет собой эта формула, так ли рассчитывается свечение пикселя? Вы говорите, что что-то вроде фильтра оттенков серого Photoshop или GIMP просто имеет некоторые жестко закодированные значения? - person George Mauer; 10.12.2013
comment
Да, именно так рассчитывается свечение пикселя разными методами. R, G, B представляют значения интенсивности в исходном изображении RGB на 3 каналах, разделенные на 255, поэтому все они попадают в диапазон (0,1) - person lennon310; 10.12.2013