【问题标题】:What are the parameters for Aforge's Grayscale filter?Aforge 的灰度滤镜的参数是什么?
【发布时间】:2013-12-11 06:29:22
【问题描述】:

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

据我了解(从八年前进行图像分割研究)灰度化是一种不应该采用任何参数的操作。您拍摄一张图像,然后提取 luminescence 通道,仅此而已。

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

更新: 我应该澄清我想要做什么。我正在尝试自动化一个我可以在 GIMP 中手动完成的过程。在 GIMP 中,我可以对任何图像应用阈值,它对发光直方图进行操作以生成二值图像,但在 Aforge 中,阈值过滤器仅适用于灰度图像。那么我将如何复制我的手动流程?

【问题讨论】:

    标签: .net image-processing aforge


    【解决方案1】:

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

    【讨论】:

    • 非常感谢,这些数字仍然无法让我得到我在 GIMP 中看到的确切结果,但我怀疑现在的问题在于我误解了 GIMP 阈值过滤器在应用于彩色图像时的工作原理.如果我无法弄清楚,我将为此启动另一个线程。
    • 我也得到了不同的结果。更新答案以反映阈值工具实际上并未计算“亮度”,而只是计算最大 R/G/B。
    • 哇,有趣(实际上也解释了我所看到的结果)有关如何使用 Aforge 实现此功能的任何建议(生成灰度图像)?我想我可以追踪灰度过滤器的源代码……但我想知道是否有更好的方法。
    • Photoshop、Imagemagick 等似乎都实现了更复杂的转换。 Gimp 似乎是一个奇怪的问题,因此必须手动实施。 (更新)
    【解决方案2】:

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

    【讨论】:

    • 我的头上有种。那么这些值会影响什么?我应该将它们设置为什么才能使我的灰度图像等同于简单地提取发光?
    • Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma 用于标准亮度或 0.2989*R+ 0.5870 * G + 0.1140 * B 用于感知选项最常用经常。
    • 还是不太清楚,这个公式代表什么,一个像素的发光度是这样计算的吗?你是说 Photoshop 或 GIMP 灰度滤镜之类的东西只是有一些硬编码的值吗?
    • 是的,这就是使用不同方法计算像素发光度的方式。 R,G,B表示原始RGB图像中3个通道的强度值除以255,所以都落在(0,1)的范围内
    猜你喜欢
    • 2016-10-03
    • 2013-12-31
    • 1970-01-01
    • 2018-02-18
    • 2016-01-06
    • 2014-02-11
    • 1970-01-01
    • 2018-09-19
    • 2017-05-21
    相关资源
    最近更新 更多