查找颜色名称时,在机器人有色相 [英] Find color name when have Hue in android

查看:295
本文介绍了查找颜色名称时,在机器人有色相的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只关心12种颜色:

red: RGB: 255, 0, 0
pink: RGB: 255, 192, 203
violet: RGB: 36, 10, 64
blue: RGB: 0, 0, 255
green: RGB: 0, 255, 0
yellow: RGB: 255, 255, 0
orange: RGB: 255, 104, 31
white: RGB: 255, 255, 255
black: RGB: 0, 0, 0
gray: RGB: 128, 128, 128
tea: RGB: 193, 186, 176
cream: RGB: 255, 253, 208

当我读位图的像素,我可以得到的色调值:

When i read the pixel of bitmap, i can get the Hue value:

int picw = mBitmap.getWidth();
    int pich = mBitmap.getHeight();
    int[] pix = new int[picw * pich];
    float[] HSV = new float[3];

    // get pixel array from source
    mBitmap.getPixels(pix, 0, picw, 0, 0, picw, pich);

    int index = 0;
    // iteration through pixels
    for(int y = 0; y < pich; ++y) {
        for(int x = 0; x < picw; ++x) {
            // get current index in 2D-matrix
            index = y * picw + x;               
            // convert to HSV
            Color.colorToHSV(pix[index], HSV);
            // increase Saturation level
            //HSV[0] = Hue
            Log.i(getCallingPackage(), String.valueOf(HSV[0]));
        }
    }

现在我想知道什么颜色的这个像素的(仅在12以上的颜色)?

Now i want to know what color of this pixel (only in 12 above colors)?

我用HSV看颜色的范围。当我有没有在这个列表中的颜色,我想将其命名为同样的颜色在我的列表 我怎样才能做到这一点?

I use HSV to see the range of color. When i have a color which doesn't in this list, i want to name it as similarly color in my list How can i do it?

感谢你这么多。

推荐答案

根据您的意见,似乎你基本上是试图减少对位的全彩色调色板只有你所指定的12。显然,在位图的每一个像素从这些12最佳匹配应该选择。

Based on your comments it seems you're basically trying to reduce the bitmap's full colour palette to only the 12 you specified. Obviously for every pixel in the bitmap the 'best match' from those 12 should be picked.

我还是不明白你为什么会需要HSV值,因为它是一个RGB分量只是不同重presentation - 它实际上并没有改变这个问题,或者它的解决方案

I still don't see why you would need the HSV values, as it's just a different representation of the RGB components - it doesn't actually change the problem, or its solution.

有一个简单的方法找到任何RGB颜色看起来像如下的最佳匹配。

A straightforward approach to find the best match for any RGB colour would look something like as follows.

首先建立某种形式包含要匹配的颜色列表中。我用一个地图,因为你提到你(也)想知道的名称的颜色,而不仅仅是RGB值。

First build some sort of a list containing the colours you want to match against. I've used a Map, since you mentioned you (also) wanted to know the name of the colour, not just the RGB value.

Map<String, Integer> mColors = new HashMap<String, Integer>();
mColors.put("red", Color.rgb(255, 0, 0));
mColors.put("pink", Color.rgb(255, 192, 203));
mColors.put("voilet", Color.rgb(36, 10, 64));
mColors.put("blue", Color.rgb(0, 0, 255));
mColors.put("green", Color.rgb(0, 255, 0));
mColors.put("yellow", Color.rgb(255, 255, 0));
mColors.put("orange", Color.rgb(255, 104, 31));
mColors.put("white", Color.rgb(255, 255, 255));
mColors.put("black", Color.rgb(0, 0, 0));
mColors.put("gray", Color.rgb(128, 128, 128));
mColors.put("tea", Color.rgb(193, 186, 176));
mColors.put("cream", Color.rgb(255, 253, 208));

然后,只需做一个方法,将告诉你的最佳匹配。您可以在一秒中称这种来自for循环并通过其当前的像素颜色。我已经添加了一些内部注释来解释不同的步骤,但它真的很简单。

Then just make a method that will tell you the best match. You can call this from within your second for loop and pass it the current pixel colour. I've added some inline comments to explain the different steps, but it's really quite trivial.

private String getBestMatchingColorName(int pixelColor) {
    // largest difference is 255 for every colour component
    int currentDifference = 3 * 255;
    // name of the best matching colour
    String closestColorName = null;
    // get int values for all three colour components of the pixel
    int pixelColorR = Color.red(pixelColor);
    int pixelColorG = Color.green(pixelColor);
    int pixelColorB = Color.blue(pixelColor);

    Iterator<String> colorNameIterator = mColors.keySet().iterator();
    // continue iterating if the map contains a next colour and the difference is greater than zero.
    // a difference of zero means we've found an exact match, so there's no point in iterating further.
    while (colorNameIterator.hasNext() && currentDifference > 0) {
        // this colour's name
        String currentColorName = colorNameIterator.next();
        // this colour's int value
        int color = mColors.get(currentColorName);
        // get int values for all three colour components of this colour
        int colorR = Color.red(color);
        int colorG = Color.green(color);
        int colorB = Color.blue(color); 
        // calculate sum of absolute differences that indicates how good this match is 
        int difference = Math.abs(pixelColorR - colorR) + Math.abs(pixelColorG - colorG) + Math.abs(pixelColorB - colorB);
        // a smaller difference means a better match, so keep track of it
        if (currentDifference > difference) {
            currentDifference = difference;
            closestColorName = currentColorName;
        }
    }
    return closestColorName;
}

的结果快速测试使用某些$ P $的pdefined颜色常量:

The results for a quick test using some of the predefined Color constants:

Color.RED (-65536) -> red (-65536)
Color.GREEN (-16711936) -> green (-16711936)
Color.BLUE (-16776961) -> blue (-16776961)
Color.BLACK (-16777216) -> black (-16777216)
Color.WHITE (-1) -> white (-1)
Color.GRAY (-7829368) -> gray (-8355712)
Color.YELLOW (-256) -> yellow (-256)
Color.MAGENTA (-65281) -> pink (-16181)

插图中的括号中的第一个数字是颜色常数实际int值,二是最优匹配的int值发现,与就在它前面的名称。

The first number inbetween the brackets is the actual int value for the Color constant, the second is the int value for the best match found, with the name right in front of it.

的结果 Col​​or.MAGENTA 也说明了为什么你不应该只是直接比较出彩的int值。实际的int值是 -65281 ,这是相当接近的 Col​​or.RED (-65536)的值。然而,根据不同的组件的最佳匹配是'粉',其中有一个-16181值。显然,这使得完整意义上知道一个颜色定义为4个字节:

The result for Color.MAGENTA also illustrates why you should not just compare the colour's int value directly. The actual int value is -65281, which is quite close to the value for Color.RED (-65536). However, the best match based on the different components is 'pink', which has a -16181 value. Obviously this makes complete sense knowing that a colour is defined as 4 bytes:

颜色重新psented外带整数,由4个字节$ P $:alpha,红色,   绿色,蓝色。 (...)的分量存储如下(阿尔法&其中;&所述; 24)   | (红&LT;&LT; 16)| (绿色&LT;&LT; 8)|蓝色。

Colors are represented as packed ints, made up of 4 bytes: alpha, red, green, blue. (...) The components are stored as follows (alpha << 24) | (red << 16) | (green << 8) | blue.

来源:android.graphics.Color参考

//编辑:与HSV值似乎是可以的。我没有得到一个不同的结果洋红作为最接近的匹配虽然 - 紫色,粉红色的代替。您可能要仔细检查值和断点一些东西。举例来说,我能想象它可能会更好正常化H的一部分。这是给你......

// with HSV values it seems to work fine too. I did get a different result for 'magenta' as closest match though - violet, in stead of pink. You might want to double check the values and breakpoint some stuff. For instance, I can imagine it might be better to normalize the 'H' part. That's up to you...

private String getBestMatchingHsvColor(int pixelColor) {
    // largest difference is 360(H), 1(S), 1(V)
    float currentDifference = 360 + 1 + 1;
    // name of the best matching colour
    String closestColorName = null;
    // get HSV values for the pixel's colour
    float[] pixelColorHsv = new float[3];
    Color.colorToHSV(pixelColor, pixelColorHsv);

    Iterator<String> colorNameIterator = mColors.keySet().iterator();
    // continue iterating if the map contains a next colour and the difference is greater than zero.
    // a difference of zero means we've found an exact match, so there's not point in iterating further.
    while (colorNameIterator.hasNext() && currentDifference > 0) {
        // this colour's name
        String currentColorName = colorNameIterator.next();
        // this colour's int value
        int color = mColors.get(currentColorName);
        // get HSV values for this colour
        float[] colorHsv = new float[3];
        Color.colorToHSV(color, colorHsv);
        // calculate sum of absolute differences that indicates how good this match is 
        float difference = Math.abs(pixelColorHsv[0] - colorHsv[0]) + Math.abs(pixelColorHsv[1] - colorHsv[1]) + Math.abs(pixelColorHsv[2] - colorHsv[2]);
        // a smaller difference means a better match, so store it
        if (currentDifference > difference) {
            currentDifference = difference;
            closestColorName = currentColorName;
        }
    }
    return closestColorName;
}

这篇关于查找颜色名称时,在机器人有色相的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆