Aforge的灰度滤镜有哪些参数?

时间:2013-12-09 22:06:35

标签: .net image-processing aforge

我正在使用Aforge.Net进行一些图像处理,而我无法理解the Grayscale filter。具体是三个强制性的红色/绿色/蓝色系数构造函数参数。

根据我的理解(从八年前进行的图像分割研究),灰度是一种不应该采用任何参数的操作。您拍摄图像,然后提取发光频道,就是这样。

那么这些参数是什么,我如何简单地提取发光?

更新 我应该澄清一下我要做的事情。我试图自动化一个我可以在GIMP中手动完成的过程。在GIMP中,我可以对任何图像应用阈值,并且它在发光直方图上操作以产生二进制图像,但是在Aforge中,阈值滤波器仅对灰度图像起作用。那么我将如何复制我的手动过程呢?

2 个答案:

答案 0 :(得分:3)

GIMP desaturate dialog box

当你在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手动生成的图像进行比较,它们最终看起来完全相同。

答案 1 :(得分:1)

RGB到灰度转换需要RGB通道上的加权和。并且颜色发光的量度包括称为gamma correction的非线性变换。它也是加权和,但分别在R^gammaG^gammaB^gamma上。描述了更多公式here