验证Android位图是否为灰度图像

3

我有一个疑问。在Android中从Bitmap获取像素时,我得到了一张图像,这是一张灰度图像。如果我使用getPixels()并检查值,我可以看到R != G != B的值。

我认为,如果三个滑块(R、G和B)的值相同,则可以检查它是否为灰度图像,但这似乎不可能。有没有一种方法来验证它?

非常感谢!

3个回答

2

首先,有几种方法可以实现这个目标。

我建议使用以下方式获取图像的大小(类似于)

int myHeight = myImage.getHeight();
int myWidth  = myImage.getWidth();

在这种情况下,我会建议您验证位图的配置,因为它可能是三种不同的格式之一。

ALPHA_8, ARGB_8888, or RGB_565

您可以使用以下方法获取配置:

myImage.getConfig()

例行程序。稍后我们将介绍如何使用它。

现在您已经知道图像的大小,应该运行以下双重循环结构:

boolean isGrayscaleImage = true;  // assume it is grayscale until proven otherwise

for(int i = 0; i < myWidth; i++){
    for(int j = 0; j < myHeight; j++){
        int currPixel = myImage.getPixel(i, j);

        if( false == isGrayScalePixel(currPixel) ){
            isGrayscaleImage = false;
            break;
        }
    }
}

回到如何测试像素是否为灰度图像: 如果图像存储为ALPHA_8,则实际上它并不是灰度图像,但是可以通过将图像转换为ARGB_8888图像,并将Alpha值设置为0xFF以及每个R、G和B分量设置为原始8位ALPHA_8基于图像中提供的Alpha值来转换为灰度图像。
如果图像格式为RGB_565,则有些棘手,因为您必须使用移位和掩码运算符自己拆分R、G和B值为它们自己的字节。一旦完成此操作,就类似于处理下面讨论的ARGB_8888图像。
对于ARGB_8888图像: Alpha通道应始终为0xFF。
正如您在问题中所述,如果R == G == B,则像素被认为是灰度。 因此(示例代码可能如下所示)
boolean isGrayScalePixel(int pixel){
    int alpha = (pixel && 0xFF000000) >> 24;
    int red   = (pixel && 0x00FF0000) >> 16;
    int green = (pixel && 0x0000FF00) >> 8;
    int blue  = (pixel && 0x000000FF);

    if( 0 == alpha && red == green && green == blue ) return true;
    else return false;

}

有一些优化可以进行,但我正在尝试为您记录主要算法。

希望这能帮助您 :-)


这就是我所做的,但灰度图像中的像素值不同,我认为它们应该是相同的,就像你一样。这就是我的问题。 - SamuSan
好的……这就是您要验证的方式。您是否有实际图像?您是否在图像处理应用程序中打开它并放大以查看是否确实存在非灰度色彩? - trumpetlicks
我将验证应用为图像的预处理步骤,即在加载图像后立即进行,而不进行缩放或其他不同的操作。如果使用Matlab打开此图像,则会发现它是一张仅有一个图层的灰度图像(而非索引颜色图像),其像素级别从0到255。 - SamuSan
你是否已经检查过它是ARGB_8888还是ARGB_565?当你说R!= G!= B时,这些值有多远? - trumpetlicks
找到了问题。所有的图像都被加载为ARGB_565格式,而且R或B的值比G的值的比例不同。解决方案是强制使用decodeFile()函数,并将options.preferredConfig参数设置为ARGB_8888。这样每个人都可以获得相同比例的正确值。 - SamuSan
很高兴听到这个消息,至少我能帮助你走上正确的道路 :-) - trumpetlicks

1
请注意,当屏蔽掩码时应使用&&(布尔与),而位屏蔽应该使用单个&(位与),如下所示:
int alpha = (pixel & 0xFF000000) >> 24;
int red   = (pixel & 0x00FF0000) >> 16;
int green = (pixel & 0x0000FF00) >> 8;
int blue  = (pixel & 0x000000FF);

1
如果您只需要检查R、G和B值是否相同,则可以使用Colors.red()Colors.green()Colors.blue()进行检查。

以下是实际代码的一小部分。

for(int x=0;x< bmp.getWidth();x++) {
    for(int y=0;y< bmp.getHeight();y++) {    

        int pixel=bmp.getPixel(x,y);
        int alpha=Color.alpha(pixel);            
        int gray_color=Color.red(pixel);         
        int gray_color1=Color.green(pixel);

        //int gray_color=pixel&0x000000ff;
        //int gray_color1=(pixel&0x0000ff00)>>8;
        //int gray_color2=(pixel&0x00ff0000)>>16;
        //int gray_color3=Math.abs((pixel&0xff000000))>>24;

        int pixels= (int)Math.pow(gray_color,gamma);
        k.add(""+alpha+" "+gray_color+" "+gray_color1);
        bmp.setPixel(x,y,Color.argb(alpha,pixels,pixels,pixels));
    }
}

你可以看到,我已经对移位和掩码部分进行了注释。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接