假设n = 100; 我如何生成100个视觉上不同的颜色?这在数学上是否可能?
假设n = 100; 我如何生成100个视觉上不同的颜色?这在数学上是否可能?
是的。定义“不同”是根据颜色空间而言的,因此当我们说“最大程度的不同颜色”时,我们的意思是与所有其他颜色尽可能远的颜色。但由于颜色空间不会改变,答案也不会改变。实现一些更符合人眼和人眼看到颜色的方式的东西(比如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并映射颜色空间。所以,使用蛮力算法和高级颜色距离算法,您可以自己生成相同的颜色集合。需要一天时间或更长时间。编辑:
我在这个领域没有任何专业知识,我的数学技能也很平均。但我认为,这个问题的解决方案比许多答案所暗示的更加复杂和有趣,因为最近我试图做类似的事情,但没有找到解决方法。
颜色的感知当然是主观的,但人类之间存在相当大的一致性。例如,我们都可以同意红、绿、蓝是非常不同的颜色,即使色盲的人也会同意黑白是非常不同的。
计算机系统中最常见的颜色表示是向量 (r, g, b),它建议一个简单的距离函数,如下:
让我们将 r,g 和 b 的范围设置为 [0, 1],看看它是如何工作的:
到目前为止,一切都很好。然而问题在于,蓝色和红色距离黑色 (0, 0, 0) 的距离相同为1,但观察图像时,这似乎并不成立:
此外,黄色(1, 1, 0)和洋红色(1, 0, 1)都与白色(1, 1, 1)的距离为1,这似乎也没有什么意义:
我认为可以安全地假设HSL和HSV颜色方案的类似度量存在相同的问题。这些颜色方案不是为了比较颜色而设计的。
幸运的是,已经有科学家在尝试找到一种好的比较颜色的方法。他们提出了一些复杂的方法,其中最新的方法是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
这个算法存在一些问题:
颜色的间距不够优化。如果我们将颜色想象成一条线上的数字,三个数字的最佳间距如下所示:
|a-----b-----c|
在不移动a、b和c的情况下添加一个数字显然比重新排列所有颜色更糟糕。
该算法无法保证终止。如果列表中不存在与现有颜色足够远的颜色,循环将永远继续。
嗯... 我没有一个。
100种颜色很多,但您可以尽可能地在HSB或HSL空间中分散它们;在RGB中实现可能很困难。
例如,您可以决定使用10种不同的色调,4种不同的饱和度级别和3种不同的亮度设置,这将为您提供多达120种颜色。您需要仔细选择饱和度和亮度值;人眼是复杂和混乱的传感器。如果将颜色空间视为一个圆锥体,则可能需要在每个亮度/饱和度级别上使用不同数量的色调。
这里是维基百科关于HSB的链接:HSL和HSV条目。
虽然这不是对你问题的回答,但是如果n有一个最大值并且你的应用程序允许,你可以使用预定义的颜色列表,例如:
http://en.wikipedia.org/wiki/List_of_colors
其中一个优点是你可以在提示框中显示易读的颜色名称以供色盲人士查看。