计算图像中的“红/蓝/绿......”颜色

时间:2011-08-16 16:26:42

标签: java colors count

我正在开发能够计算图像中蓝色/红色/黄色/ ...像素数量的东西。到目前为止,我已将此代码作为测试:

public class Main {

    /*
   Black: 0,0,0
   White: 255, 255, 255
   Red: 255, 0, 0
   Orange: 255, 127, 0
   Yellow: 255, 255, 0
   Green: 0, 255, 0
   Blue: 0, 0, 255
   Indigo: 111, 0, 255
   Violet: 143, 0, 255
    */

    static int blackCount = 0;
    static int whiteCount = 0;
    static int redCount = 0;
    static int orangeCount = 0;
    static int yellowCount = 0;
    static int greenCount = 0;
    static int blueCount = 0;
    static int indigoCount = 0;
    static int violetCount = 0;
    static int otherCount = 0;

    static int totalCount = 0;

    public static void main(String[] args) {
        try {

            String path = "src/colors.jpg";
            BufferedImage image = ImageIO.read(new File(path));
            int w = image.getWidth();
            int h = image.getHeight();
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    Color c = new Color(image.getRGB(x, y));
                    int red = c.getRed();
                    int green = c.getGreen();
                    int blue = c.getBlue();
                    countColor(red, green, blue);
                    totalCount++;
                }
            }

            printColors();

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }

    private static void countColor(int red, int green, int blue) {
        if (red == 0 && green == 0 && blue == 0) blackCount++;
        else if (red == 255 && green == 255 && blue == 255) whiteCount++;
        else if (red == 255 && green == 0 && blue == 0) redCount++;
        else if (red == 255 && green == 127 && blue == 0) orangeCount++;
        else if (red == 255 && green == 255 && blue == 0) yellowCount++;
        else if (red == 0 && green == 255 && blue == 0) greenCount++;
        else if (red == 0 && green == 0 && blue == 255) blueCount++;
        else if (red == 111 && green == 0 && blue == 255) indigoCount++;
        else if (red == 143 && green == 0 && blue == 255) violetCount++;
        else otherCount++;
    }

    private static void printColors() {
        System.out.println("Black: " + blackCount);
        System.out.println("White: " + whiteCount);
        System.out.println("Red: " + redCount);
        System.out.println("Orange: " + orangeCount);
        System.out.println("Yellow: " + yellowCount);
        System.out.println("Green: " + greenCount);
        System.out.println("Blue: " + blueCount);
        System.out.println("Indigo: " + indigoCount);
        System.out.println("Violet: " + violetCount);
        System.out.println("Other: " + otherCount);
        System.out.println("Total: " + totalCount);
    }

但您可能会注意到问题...在RGB中,颜色“红色”定义为(255,0,0)。因此,包含大量红色的图像可能会返回“0”,因为图像中使用的颜色是(254,0,0)而不是(255,0,0)。

所以我实际上不仅要计算纯红色像素,还要计算所有“红色”像素。我假设有一种更容易的方法来解决这个问题,而不是写一个疯狂的长if(红色= 255),如果(红色= 254),......结构?

5 个答案:

答案 0 :(得分:4)

我会考虑尝试确定三种常数中哪一种颜色更大。如果红色的数量大于蓝色的数量和绿色的数量,您可能会认为您的颜色是“红色”。 蓝色和绿色也一样。

但是,您可能需要考虑一些极端情况:

  • 当颜色为“灰色”时,你会怎么做,即所有三个常数都相同
  • 如果考虑颜色(155,154,154)会发生什么?红色常数最大,但颜色仍然是灰色。也许你应该说颜色是某种颜色 - 当且仅当相关常数大于其他常数加上一定值时?

xkcd传达了一个非常有趣的survey on the subject of colors。我建议您查看有关颜色如何工作的更多详细信息,它可能会给您一些关于哪些值使颜色变为“红色”,“绿色”和“蓝色”的命中。结果非常有趣,但显示了很多有趣的情况,其中颜色检测非常重要。不同的人可以区分不同的颜色,受到性别,色盲和其他因素的影响。

此外,调查还包括许多可以使用的RGB常数的颜色名称。它还附带一个颜色名称地图!

我真的相信颜色是一个非常有趣的主题,但它确实非常复杂,在实际决定如何编写代码之前,你应该获得关于这个主题的更多信息。

答案 1 :(得分:4)

您可以将正在处理的像素转换为更方便的颜色模型,即HSL or HSV

然后定义属于特定组的组件值范围(红色/蓝色/等)可能更简单。

答案 2 :(得分:3)

你需要定义偏红,偏蓝和绿色。显然[254,0,0]应该通过红色。那么[254,5,5]呢?那么[200,10,10]呢?

您最好的选择是检查距离检查颜色的距离(例如,使用纯红色:(255-r)^2 + (0-b)^2 (0-g)^2)并将其与您认为“有效红色”的阈值进行比较。

然后对其他颜色做同样的事情。

这种方式还可以让您轻松扩展到其他颜色(因为您可以检查颜色与其他颜色的距离)。

编辑:找到这个问题:Is there an easy way to compare how close two colors are to each other后,我建议转换为HSL(色调,饱和度,亮度)并根据某个阈值按顺序比较他的值。看看这个问题,有很多好的信息。

答案 3 :(得分:1)

前段时间我看到一个非常相关的问题,关于从RGB值获取颜色名称。例如,当颜色可以从RGB转换为HSV时,解决方案更容易,因为hue是颜色。完成后,您可以为色调定义一些范围,并将它们用作颜色。

因此,例如,0到30度之间的色调(或任何其他度量)将是红色,从30到60将是橙色,然后是黄色....

请查看How do you get the hue of a #xxxxxx colour?Map rainbow colors to RGB,例如

要从色调中获取颜色名称,wikipedia可以帮助...

答案 4 :(得分:0)

检查范围,而不是检查红色,绿色或蓝色的特定值

(你必须为语法和计算调整它 - 我不是Java编码器)


    private static void countColor(int red, int green, int blue) {
            if (red == 0 && green == 0 && blue == 0) blackCount++;
            else if (red !=0 && green == red && blue == red) whiteCount++;
            else if (red !=0 && green == 0 && blue == 0) redCount++;
            else if (red !=0 && green == (red/2) && blue == 0) orangeCount++;
            else if (red !=0 && green == red && blue == 0) yellowCount++;
            else if (red == 0 && green == !=0 && blue == 0) greenCount++;
            else if (red == 0 && green == 0 && blue == !=0) blueCount++;
            else if (red == (blue/3) && green == 0 && blue !=0) indigoCount++;
            else if (red == (blue/0.66) && green == 0 && blue == !=) violetCount++;
            else otherCount++;
        }

如果这样做,它将检查与红色,绿色,蓝色,白色,黑色等色调相匹配的颜色。