如何定义像素颜色的清晰范围

2022-09-03 15:13:23

我试图做的是测试一个像素是否是蓝色的。

例如:蓝色以 RGB 形式定义为 rgb(0,0,255)。典型的颜色深度为8位(256种颜色),16位(约6.5万),24位(约1600万)和32位(超过40亿种不同的颜色)。所以显然有超过1种蓝色阴影。

如何定义蓝色的范围并测试每个像素是否为蓝色?关于不同的深度,我需要记住什么?

到目前为止,我的代码是:

BufferedImage image = ImageIO.read(file);

// Getting pixel color by position x and y
for (int i = 0; i < image.getWidth(); i++) {
    for (int j = 0; j < image.getHeight(); j++) {
        int clr = image.getRGB(i, j);

注1

http://www.workwithcolor.com/cyan-blue-color-hue-range-01.htm

这里的问题是,颜色步骤之间有什么?

举个例子就好了。

注2

我刚刚找到了一个关于我感兴趣的主题的演示文稿:

http://cstwiki.wtb.tue.nl/images/06-opencv.pdf

在第13页上,我们可以看到红色的定义。但是如何定义其他颜色呢?


答案 1

在我看来,最简单的方法是将颜色格式转换为HSV / HSB,然后为Hue选择蓝色范围。确切的范围可能是一个问题,但我主要使用从165(下面是绿色)到240(上面是紫色/紫色)。“饱和度”和“值/亮度”仅控制阴影,但请注意,接近 0 的饱和度将相当灰色,带有一些蓝色阴影,而值接近 0 将几乎是黑色。因此,您还可以将饱和度检查为>10和值>15,但当然您可以选择自己的值来满足您的需求。

示例代码(未测试):

boolean isBlue(int rgb){
    Color color = new Color(rgb);
    float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
    // now [0] is hue, [1] saturation and [2] value/brightness
    // all values are between 0 and 1 so you must divide hue by 360 and others by 100
    if(hsb[0] > 165/360 && hsb[0] < 240/360 && hsb[1] > 0.1 && hsb[2] > 0.15)
        return true;
    return false;
}

关于 HSV 的维基

RGBtoHSB javadoc

颜色选择器,用于检查不同系统中的颜色


答案 2

在RGB色彩空间中,这并不容易做到。首先,颜色的显示方式取决于设备,也就是说,您选择显示的任何RGB值在不同的屏幕上可能看起来完全不同。但是,即使可以以某种方式控制这一点,在英语中被分配了特定名称的颜色也不一定在RGB颜色立方体中占据相同的体积,无论是在大小还是形状方面。正因为如此,有一些颜色模型试图近似人类对颜色的感知

一个竞争者是CIELab色彩空间。“Lab”是指在此模型中如何表示颜色:通过颜色的亮度,颜色在红色/洋红色和绿色轴上的位置(),以及它在黄色和蓝色轴上的位置()。不幸的是,没有简单的公式可以在RGB或CMYK值和Lab *之间进行转换,因为RGB和CMYK颜色模型是依赖于设备的。首先必须将 RGB 或 CMYK 值转换为特定的绝对色彩空间,如 sRGB 或 Adobe RGB。此调整将取决于设备,但转换产生的数据将独立于设备。Lab