繁体   English   中英

如何测试图像为灰度?

[英]How can I test an image to be grayscale?

Aforge .net / Accord .net库中, 执行以下测试以确定图像是否为灰度:

public static bool IsGrayscale (Bitmap image)
{
    bool ret = false;

    // check pixel format
    if (image.PixelFormat == PixelFormat.Format8bppIndexed)
    {
        ret = true;
        // check palette
        ColorPalette cp = image.Palette;
        Color c;
        // init palette
        for ( int i = 0; i < 256; i++ )
        {
            c = cp.Entries[i];
            if ((c.R != i) || (c.G != i) || (c.B != i))
            {
                ret = false;
                break;
            }
        }
    }
    return ret;
}

这不是谬误吗?

定义而言,灰度图像可以是除1位pp之外的任何颜色深度。例如,以下是32位灰度图像:

在此输入图像描述
在此输入图像描述

所以,我的问题是,测试灰度图像的正确方法是什么?

看起来我在这个链接中得到了答案。

如果图像是灰度图像那么

 if(R=G=B) //Grayscale 

要获得更准确的结果,您可以引入一些阈值。

 if((abs(RG)< Threshold))// Threshold-> can be greater than zero. eg 0.006 //Grayscale 

通过这种方式,您可以获得相当不错的结果。

但是,我怀疑, 这个程序会像地狱一样慢。

因此,欢迎任何有更好主意的人回答。

该代码检查标准的8位灰度,其中像素值对应于它们的亮度。 这或多或少是灰度的标准,但它确实不匹配优化的调色板或类似的东西。

我不知道为什么你会排除1bpp。 它是一种与任何其他格式一样的索引格式,实际上有一个像8bpp一样的调色板,这意味着它甚至不仅限于纯黑色和白色。 这是该鹦鹉的1bpp灰​​度版本,其调色板中有两个灰度值:

1bpp灰​​鹦鹉

检查索引图像的最简单方法确实是通过调色板并进行R = G = B测试,但从技术上讲,即使这样,你也可以认为只要调色板上的任何非灰色颜色都是灰度图像没有实际使用的图像。

一种可靠的方法可能只是让LockBits将图像转换为32bppARGB,然后检查R,G和B. 但即使在那里你也必须做出选择...... 100%透明像素与R = G = B不匹配使图像“不灰度”

无论如何,这将是我使用的方法:

public static Boolean IsGrayscale(Bitmap cur)
{
    // Indexed format, and no non-gray colours in the images palette: immediate pass.
    if ((cur.PixelFormat & PixelFormat.Indexed) == PixelFormat.Indexed
        && cur.Palette.Entries.All(c => c.R == c.G && c.R == c.B))
        return true;
    // Quick indexed check failed; actually check image data.
    // Get bytes out of the image, converted to 32bpp ARGB 
    BitmapData curBitmapData = cur.LockBits(new Rectangle(0, 0, cur.Width, cur.Height),
        ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    Int32 stride = curBitmapData.Stride;
    Byte[] data = new Byte[stride * cur.Height];
    Marshal.Copy(curBitmapData.Scan0, data, 0, data.Length);
    cur.UnlockBits(curBitmapData);
    // Go over all bytes per block of four.
    Int32 curRowOffs = 0;
    for (Int32 y = 0; y < cur.Height; y++)
    {
        // Set offset to start of current row
        Int32 curOffs = curRowOffs;
        for (Int32 x = 0; x < cur.Width; x++)
        {
            Byte b = data[curOffs];
            Byte g = data[curOffs + 1];
            Byte r = data[curOffs + 2];
            Byte a = data[curOffs + 3];
            // Increase offset to next colour
            curOffs += 4;
            if (a == 0)
                continue;
            if (r != g || r != b)
                return false;
        }
        // Increase row offset
        curRowOffs += stride;
    }
    return true;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM