[英]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灰度版本,其调色板中有两个灰度值:
检查索引图像的最简单方法确实是通过调色板并进行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.