n = 100 とします。視覚的に異なる 100 色を生成するにはどうすればよいですか? これは数学的に可能ですか?
6 に答える
うん。明確に定義することは、色空間に従うことの産物であり、最大に異なる色を言うとき、私たちが言いたいのは、他のすべての色から可能な限り離れた色です. しかし、色空間は変わらないので、答えは変わりません。また、人間の目によりよく適合するものや、CIE-lab de2000 色距離のような人間の目による色の認識方法を実装すると、すべての計算をやり直すのが難しくなりますが、静的なリストは簡単になります。128件のエントリーがあります。
private static final String[] indexcolors = new String[]{
"#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
"#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
"#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
"#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
"#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
"#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
"#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
"#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
"#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
"#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
"#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
"#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
"#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C",
"#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800",
"#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51",
"#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58"
};
画像として最初の 256 を次に示します。
(左から右) (上から下)。色空間内で各色ができるだけ等距離であることを確認すると、さらにいくつかの異なる色を取得できる場合があります。そのルックアップ テーブルは、最初に N を指定してから色空間をマッピングするのではなく、以前のすべての色から最大限に区別できるように追加の各色を選択します。ええ、ブルート フォースと高レベルの色距離アルゴリズムを使用すると、同じ色のセットを自分で作成できます。1日かそこらの間。
リストを設定してそれらを等距離にすると、たとえば、異なる色の間で明確な数を得ることができます 。min_delta_max 53.2 で min_delta_max 61.5 であった 5 色のデフォルト リストを上回ります。
またはリスト内の色 , #156FC3 #165859 #24C4FF #30A581 #957D5C #213E02 #DE9AF5 #68D840 #6E0062 #C25B77 これは、事前計算されたリストの最初の 10 要素を超えています。
代わりにこれを試してみたい場合: https://gist.github.com/tatarize/a483db49993e6e0e994ad82ba3e2a22e
を取るように編集できnum_of_colors
、長時間実行して、全体的な min_delta_max (リスト内の任意の 2 つの色間の最大最大最小距離) が低い色のセットを取得できます。コンパイル済みのリストが必要です。
編集:
私はこの分野の専門知識がなく、私の数学のスキルはかなり平均的です。しかし、最近似たようなことをしようとして解決策が見つからなかったため、この問題の解決策はここでの多くの回答が示唆するよりも複雑で興味深いものであるという意見があります。
色の違い
もちろん、色の知覚は主観的なものですが、人間の間にはかなりの一致があります。たとえば、赤、緑、青が非常に異なる色であることは誰もが認めることができ、色盲の人でさえ黒と白が非常に異なることに同意します.
RGB
コンピュータ システムにおける色の最も一般的な表現はベクトル(r, g, b)であり、次のような単純な距離関数を示唆しています。
r、g、bの範囲を[0, 1]に設定して、これがどのように機能するかを見てみましょう。
- 赤(1, 0, 0)と赤(1, 0, 0)の距離は0です。これは明らかなはずです
- 赤(1, 0, 0)と黄(1, 1, 0)の距離は1で、
- 赤(1, 0, 0)と青(0, 0, 1)はsqrt(2)であり、もっともらしい
ここまでは順調ですね。ただし、問題は、青と赤が黒(0, 0, 0)から同じ距離1を持っていることですが、画像を見ると、これは当てはまらないようです:
また、黄色(1, 1, 0)とマゼンタ(1, 0, 1)は両方とも白(1, 1, 1)から同じ距離1を持っていますが、これも意味がないようです:
HSLとHSV
HSL と HSV のカラー スキームのアナログ メトリックには同じ問題があると想定しても問題ないと思います。これらの配色は、色を比較するためのものではありません。
CIEDE2000
幸いなことに、色を比較する良い方法を見つけようとしている科学者がすでにいます。彼らはいくつかの精巧な方法を考え出しました。最新のものはCIEDE2000 です。
(記事で説明されている完全な式は巨大です)
この指標は、青の色合いをうまく識別できないように見えるという事実など、人間の知覚を考慮に入れています。したがって、これを色差関数として使用すると思います。
カラーピッキングアルゴリズム
素朴な解決策
いくつかの回答は、次のアルゴリズムを提案しました
colors = []
for n in range(n):
success=False
while not success:
new_color = random_color()
for color in colors:
if distance(color, new_color)>far_enough:
colors.append(new_color)
success = True
break
このアルゴリズムにはいくつかの問題があります。
色の間隔が最適ではありません。色が線上の数字のようなものだと想像すると、3 つの数字は次のように最適な間隔で配置されます。
|a-----b-----c|
a、b、および c を移動せずに追加の 1 つの数値をそこに詰め込むことは、すべての色を再配置するよりも明らかに悪いことです。
アルゴリズムが終了することは保証されていません。リスト内の既存の色から十分離れた色がない場合はどうなりますか? ループは永遠に続く
適切な解決策
ええと.. 私は持っていません。
100 は多くの色ですが、HSB または HSL 空間でできるだけまばらに分散させることで実現できる場合があります。RGBでそれを行うのはおそらく難しいでしょう。
たとえば、10 種類の色相、4 種類の彩度レベル、3 種類の明るさの設定を使用すると、最大 120 色になります。彩度と明るさの値は慎重に選択する必要があります。人間の目は複雑でわかりにくいセンサーです。色空間を円錐として扱う場合、明度/彩度レベルごとに異なる数の色相が必要になる可能性があります。
これは、HSBのウィキペディア エントリへのリンクです。
HSL に変換してから、他の 2 つの値を一定に保ちながら色相 (H) の値を繰り返します。
N が非常に大きく、したがって色が視覚的に区別できない場合は、その時点で同じ色相をすべて繰り返し、他のコンポーネントを変更して彩度または明度を変えることができます。したがって、基本的に使用する色相値の最大数を設定でき、それがヒットすると、別の彩度または明度でやり直すことができます。
あなたの質問に対する答えではありませんが、nに最大値があり、アプリケーションで許可されている場合は、次のような事前定義された色のリストを使用できます。
http://en.wikipedia.org/wiki/List_of_colors
利点の 1 つは、色覚異常を持つユーザー向けのツールチップに人間が判読できる色の名前を表示できることです。
まず、RGB 空間を使用しないでください。この問題に適した色空間を見つけるのは困難です。(色を表示用に使用しているか印刷用に使用しているかによって、黒または白に近い見分けがつかない色が大量に存在します。)
ラボ スペースを使用する場合、色の視覚的な近さを測定するための知覚カラー モデル (CIE 1996? および CIE 2000) があります (それぞれ印刷用および表示用)。
色を一度計算して結果を保存するかどうか、またはその場で再計算する必要があるかどうか (その場合、決定論的である必要があるかどうか) は言いません。明らかに、セットを生成する最善の方法に関する議論はそれに依存します。
色空間の軸を均等に分割し(たとえば8つに)、それらを初期点として使用することは、ランダムなプロセスよりもはるかに効率的であることをお勧めします。確かに、任意のポイントをその隣接ポイントと比較するだけでよく (それらが既にセット内にある場合のみ)、膨大な数の比較を節約できます。