1

私は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

ビットマップのピクセルを読み取ると、色相の値を取得できます。

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色のみ)を知りたいですか?

私はHSVを使用して色の範囲を確認します。このリストにない色がある場合、リストに同じ色の名前を付けたいのですが、どうすればよいですか?

ありがとうございます

4

2 に答える 2

3

あなたのコメントに基づいて、あなたは基本的にビットマップのフルカラーパレットをあなたが指定した12だけに減らそうとしているようです。明らかに、ビットマップ内のすべてのピクセルについて、それらの12から「ベストマッチ」を選択する必要があります。

HSV値が必要な理由はまだわかりません。これは、RGBコンポーネントの単なる異なる表現であり、実際には問題やその解決策を変更するものではないためです。

RGBカラーに最適なものを見つけるための簡単なアプローチは、次のようになります。

まず、照合する色を含むある種のリストを作成します。RGB値だけでなく、色の名前も知りたいとおっしゃっていたので、マップを使用しました。

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

次に、最適な方法を教えてくれるメソッドを作成します。これを2番目のforループ内から呼び出して、現在のピクセルカラーを渡すことができます。さまざまな手順を説明するためにいくつかのインラインコメントを追加しましたが、それは本当に些細なことです。

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;
}

事前定義された色定数のいくつかを使用したクイックテストの結果:

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値であり、2番目の数値は、その直前に名前が付いた、見つかった最適な一致のint値です。

の結果はColor.MAGENTA、色のint値を直接比較するだけではいけない理由も示しています。実際のint値は、 (-65536)-65281の値に非常に近い値です。Color.REDただし、さまざまなコンポーネントに基づく最適な一致は、-16181の値を持つ「ピンク」です。明らかに、これは、色が4バイトとして定義されていることを知っていると完全に理にかなっています。

色は、アルファ、赤、緑、青の4バイトで構成されるパックされたintとして表されます。(...)コンポーネントは次のように保存されます(alpha << 24)| (赤<< 16)| (緑<< 8)| 青。

ソース:android.graphics.Colorリファレンス。

//編集:HSV値を使用すると、正常に機能するようです。「マゼンタ」の結果は、ピンクではなくバイオレットに最も近いものとして、異なる結果が得られました。値を再確認し、いくつかのものにブレークポイントを設定することをお勧めします。たとえば、「H」の部分を正規化する方が良いかもしれないと想像できます。それはあなた次第です...

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;
}
于 2011-12-24T23:42:44.767 に答える
1

すでにintにピクセルカラー値があるので。次の方法を使用してRGB値を抽出できます

int green = Color.green(pix[i]);
int red   = Color.red(pix[i]);
int blue  = Color.blue(pix[i]);

そして、あなたが持っているRGB値と比較します

于 2011-12-24T02:00:46.887 に答える