1

あなたが私を助けてくれることを願っています。

私はAndroidで写真を撮り、サムネイルを生成し、このサムネイルを使用してピクセルを分析し、最も使用されているトーンを取得しています。

RGBを使うとグループ化が難しいと思ったので、すべてのピクセルカラーをHSVカラーに変えました。ご覧のとおり、私はFloat3を使用しているので、これは、、 is 、equalsと同じhsv.xです。hsv.hhsv.yhsv.shsv.zhsv.v

scoresint[]配列であり、各トーンのピクセル数をそこに格納します。このアルゴリズムは、ブルートーン(アクアマリン、ライトブルー、ダークブルー)を見つけるときに非常にうまく機能しますが、モノクロ(黄色のスコアに移動)と暖かい色(オレンジと黄色を「混同」)を認識するのは困難です。また、最後の質問として、茶色(私が見逃したと思う最後の「大きな色」)を認識する方法がわかりません。アルゴリズムは次のとおりです。

for (Float3 hsv: hsvs) {
    if(hsv.y < 0.15)
    {
        if(hsv.z < 0.2)
            scores[BLACK]++;
        else if(hsv.z < 0.6)
            scores[GREY]++;
        else
            scores[WHITE]++;
    }
    else if (hsv.x < 15f || hsv.x > 345f)
        scores[RED]++;
    else if (hsv.x < 40)
        scores[ORANGE]++;
    else if (hsv.x < 70)
        scores[YELLOW]++;
    else if (hsv.x < 120)
        scores[GREEN]++;
    else if (hsv.x < 160)
        scores[AQUAMARINE]++;
    else if (hsv.x < 200)
        scores[LIGHT_BLUE]++;
    else if (hsv.x < 240)
        scores[DARK_BLUE]++;
    else if (hsv.x < 300)
        scores[PURPLE]++;
    else
        scores[PINK]++;
}

いくつかの数値を変更することでアルゴリズムを改善できると思いますか、それとも別のアプローチから始める必要がありますか?

編集:

私はあなたを文脈に入れさせてください。私のアプリは写真を撮り、(実用的な理由で)正方形のサムネイルを取得し、結果の写真を分析します。親指であるため、細部と寸法が失われます(たとえば、200x200pxの親指を作成します)。したがって、私の特定のケースでは、常に40000ピクセルになります。この画像で私がしていることは、最も使用されているトーンをチェックすることです。

最もよく使われるのは、3000ピクセル(画像の約7.5%)以上に現れるトーンとして定義することです。私はそれらをランク付けしません。任意の量の色にちなんで名付けられたいくつかのチェックボックスをチェックするだけです(おそらくあなたに表示される色と茶色になります)。次に、ユーザーは自分が適切と考える色をチェックまたはチェック解除します。実際、Geobitsが指摘しているように、これは人間の問題であり、最もよく使用される色は、最も関連性の高い色を意味するわけではありません。そのため、このツールは完璧である必要はありません。パックにまったく適合しない色の選択に失敗しないようにするためです。

4

2 に答える 2

3

私がそれをしている場合、各ピクセルをいくつかのバケットの1つに分類する代わりに、各色相が各色からどれだけ離れているかを確認します。たとえば、各「ターゲット色相」からの差を取り、すべての差を合計することができます。すべてのピクセルをループした後、合計が最も少ない方が「最も使用されている」はずです。もちろん、それは完璧ではありませんが、色の命名はコンピューターにとって簡単な作業ではありません。

たとえば、「緑」(私の任意の世界では色相120)の合計を取得するには、次のようにします。

float runningTotalForGreen = 0;
for(Float3 hsv: hsvs) 
{
    float diff = (hsv.x - 120) % 180; // mod 180 to normalize cw/ccw on the wheel
    runningTotalForGreen += diff; // lower = closer to green
}

ループを簡単にするために、ターゲットの色と合計を配列に格納することをお勧めしますが、それが一般的な考え方です。

編集:

これが「バケット」よりもうまくいくと思う理由は次のとおりです。画像の約35%が赤である画像を考えてみましょう。他の65%は、ライト/ダークブルーの境界のどこかにあります。つまり、34%が水色の中へ、31%が水色の中へと分類されます。35%が両方よりも大きいので、あなたの方法はそれが赤であると言います。色相の違いを使用すると、ほとんどの場合、ブルーの1つが返されます。

もちろん、ほとんどのメソッドには、失敗するイメージがあります。重要なのは、エラーが最も少ないものを見つけることです。それは、それがどのタイプの画像であるかに大きく依存します。特定の色(黒/白/茶色など)には特別な取り扱いが必要になることに同意します。


ここでの主な問題は、それが人間の問題であるということです。上記の私の例の画像では、水色と言う人もいます。ダークブルーと言う人もいます。特に青が背景に赤が前面にある場合は、それがどれほど鮮やかで対照的であるかに応じて、赤と言う人さえいるかもしれません。「この写真はx色です」と言うことは、基本的にモノクロでない限り、一貫性がありません。

于 2013-03-17T19:31:50.093 に答える
1

これが良いアプローチかどうかは言えません。色の名前のこのページをチェックしてください。ホイールの色をクリックすると、色の名前を定義するために使用する色相の範囲が表示されます。

于 2013-03-17T19:24:02.960 に答える