【问题标题】:Counting "redish/blueish/greenish..." colors in an image计算图像中的“红色/蓝色/绿色......”颜色
【发布时间】:2011-10-28 05:36:46
【问题描述】:

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

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)。

所以我实际上不仅要计算纯红色像素,还要计算所有“带红色”的像素。我认为有一种更简单的方法来解决这个问题,而不是编写一个疯狂的 long if (red = 255), if (red = 254),... 结构?

【问题讨论】:

    标签: java colors count


    【解决方案1】:

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

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

    【讨论】:

    • 这确实容易多了。谢谢。
    【解决方案2】:

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

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

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

    xkcd 传达了一个非常有趣的survey on the subject of colors。我建议您查看它以了解有关颜色如何工作的更多详细信息,它可能会为您提供一些关于哪些值使颜色“偏红”、“偏绿”和“偏蓝”的信息。结果非常有趣,但显示了许多有趣的案例,其中颜色检测并非易事。受性别、色盲和许多其他因素的影响,不同的人对颜色的感知可能不同。

    此外,该调查还包括您可以使用的大量 RGB 常量的大量颜色名称。它还附带了一个颜色名称的地图!

    我真的相信颜色是一个非常有趣的话题,但是它确实很复杂,在真正决定如何编写代码之前,您应该尽可能多地了解该主题。

    【讨论】:

    • 啊,是的,xkcd 的颜色调查。这确实会派上用场,谢谢。
    【解决方案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(色调、饱和度、亮度)并根据某个阈值按顺序比较他的值。看看这个问题,有很多很好的信息。

    【讨论】:

      【解决方案4】:

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

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

      How do you get the hue of a #xxxxxx colour?Map rainbow colors to RGB 为例

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

      【讨论】:

        【解决方案5】:

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

        (您必须针对语法和计算进行调整 - 我不是 Java 编码员)

        私人静态无效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++; 否则 if (red !=0 && green == (red/2) && blue == 0) orangeCount++; else if (red !=0 && green == red && blue == 0) yellowCount++; 否则 if (red == 0 && green == !=0 && blue == 0) greenCount++; 否则 if (red == 0 && green == 0 && blue == !=0) blueCount++; 否则 if (red == (blue/3) && green == 0 && blue !=0) indigoCount++; 否则 if (red == (blue/0.66) && green == 0 && blue == !=)violetCount++; 否则其他计数++; }

        如果可行,它将检查与红色、绿色、蓝色、白色、黑色等色调相匹配的颜色。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-02-23
          • 2020-06-10
          • 1970-01-01
          • 2011-09-22
          • 2018-09-15
          • 2017-08-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多