有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

图像处理与颜色检测

我想在Java中实现一个功能,它可以读取图像,并能够检测出红色、蓝色、绿色、黄色等阴影,作为卫星图像分析程序的一部分。例如,在一张标准的卫星图像中,蓝色是水,所以我想让程序读取多少像素是蓝色的,然后它可以说图像的x%是水

我知道可以通过读取每个像素的RGB值来使用全部逻辑语句,但是有更简单的方法吗?否则,将会有数百条if语句,这将需要很长时间来编写,但也需要很长时间来执行。理想情况下,我喜欢这样的东西:

if (pixelValue = red) {
   redCounter++;
}

这显然是非常简单的,但它可以避免对红色、蓝色、绿色、黄色、紫色等的每一种可能的RGB组合进行检查,这些颜色都存在于一些彩色图像中

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    无论如何,你必须读取每个像素。你可以用它来做这个

    int rgb = bufferedImage.getRGB(x,y);
    

    或者,您可以从图像中获取数据缓冲区,并直接以int[]数组的形式获取像素(如注释中所述),但请注意,这可能会对以后渲染此图像时的性能产生一些影响

    下一步是检测像素是否具有特定颜色。当谈到照片时,一个比较像

    if (rgb == Color.BLUE.getRGB()) { ... }
    

    没有意义:在大多数情况下,像素不会完全呈蓝色。相反,您可以通过将RGB值转换为HSB颜色空间来分析其色调。所以你可以做一些像

    float hsb[] = new float[3];
    int r = (rgb >> 16) & 0xFF;
    int g = (rgb >>  8) & 0xFF;
    int b = (rgb      ) & 0xFF;
    Color.RGBtoHSB(r, g, b, hsb);
    

    然后hsb数组将包含颜色的色调、饱和度和亮度。这些值将介于0和1之间。色调乘以360将得到颜色的“色调”:

    HSV

    饱和度和亮度可用于检测“接近黑色”或“接近白色”的像素。所以你的最终分析可以大致(!)像这样:

    if      (hsb[1] < 0.1 && hsb[2] > 0.9) nearlyWhite();
    else if (hsb[2] < 0.1) nearlyBlack();
    else {
        float deg = hsb[0]*360;
        if      (deg >=   0 && deg <  30) red();
        else if (deg >=  30 && deg <  90) yellow();
        else if (deg >=  90 && deg < 150) green();
        else if (deg >= 150 && deg < 210) cyan();
        else if (deg >= 210 && deg < 270) blue();
        else if (deg >= 270 && deg < 330) magenta();
        else red();
    }
    

    这些嵌套的if语句也可以通过使用NavigableMap及其floorEntryceilingEntry方法来避免,但是if语句在这里可能更容易理解