如何为任何自然数n生成n种不同的颜色?

时间:2010-02-24 18:09:31

标签: algorithm colors pseudocode perception

说n = 100;如何生成100种视觉上鲜明的颜色?这在数学上是否可行?

6 个答案:

答案 0 :(得分:38)

呀。定义明显是推迟到色彩空间的产物然后当我们说最大不同的颜色时我们所说的是尽可能远离所有其他颜色的颜色。但由于色彩空间没有改变,答案不会改变。并且实现更适合人眼的东西以及人眼看到的颜色如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作为图像。

max distance

(从左到右)(从上到下)。如果确保每种颜色在颜色空间内尽可能等距,则可能会获得更多不同的颜色。该查找表将每个附加颜色选择为与所有先前颜色最大不同,而不是在开始时指定N,然后映射出颜色空间。所以是的,蛮力和高级别的颜色算法,你可以自己制作同样的颜色。在一天左右的过程中。

答案 1 :(得分:37)

编辑:

我在这方面没有任何专业知识,而且我的数学技能非常平均。但我认为这个问题的解决方案比这里提出的许多答案更复杂,更有趣,因为我最近尝试做类似的事情并没有找到解决方案。

色差

对颜色的感知当然是主观的,但人类之间存在显着的一致性。例如,我们都同意红色,绿色和蓝色是非常不同的颜色,甚至色盲人都认为黑色和白色是非常不同的。

RGB

计算机系统中最常见的颜色表示是矢量(r,g,b),它表示一个简单的距离函数,如

RGB color difference

让我们将 r g b 的范围设置为 [0,1] ,看看如何这有效:

  1. 红色(1,0,0)和红色(1,0,0)的距离 0 ,应该是明显
  2. 红色(1,0,0)和黄色(1,1,0)的距离 1 ,更小
  3. 的距离
  4. 红色(1,0,0)和蓝色(0,0,1) sqrt(2),这是可信
  5. 到目前为止,这么好。然而问题是蓝色和红色与黑色(0,0,0)具有相同的距离 1 ,但是当看到图像时,这似乎不成立真:

    blue and red on black

    黄色(1,1,0)和品红色(1,0,1)两者的距离 1 相同白色(1,1,1),这似乎没有意义:

    yellow and magenta on white

    HSL和HSV

    我认为可以安全地假设HSL and HSV color schemes的模拟指标存在同样的问题。这些配色方案不是为比较颜色而设计的。

    CIEDE2000

    幸运的是,有些科学家已经在努力找到一种比较颜色的好方法。他们提出了一些精心设计的方法,最新的方法是CIEDE2000

    CIEDE2000

    (文章中描述的完整公式是 huge

    这个指标考虑了人类的感知,就像我们似乎无法很好地辨别蓝色阴影一样。所以我要说我们用它作为我们的色差函数。

    颜色选择算法

    天真的解决方案

    一些答案​​提出了以下算法

    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
    

    此算法存在一些问题:

    1. 颜色的间距不是最佳的。如果我们将颜色想象成一条线上的数字,那么三个数字最佳间隔如下:

      |一个----- ----- bç|

      在不移动a,b和c的情况下在其中打包另外一个数字显然比重新调整所有颜色更糟糕。

    2. 无法保证算法终止。如果没有足够的颜色形成列表中现有的颜色怎么办?循环将永远持续

    3. 正确的解决方案

      嗯..我没有。

答案 2 :(得分:4)

您希望转换为HSL,然后迭代色调(H)的值,同时保持其他2个值不变。

对于每个值convert from HSL back to RGB

查看我的答案herehere

如果您的N非常大,因此颜色在视觉上不明显,那么您可以在该点重新遍历所有相同的色调并更改其他组件以改变饱和度或亮度。所以基本上你可以使用最大数量的色调值,一旦被击中,你可以重新开始使用不同的饱和度或亮度。

答案 3 :(得分:4)

100是很多颜色,但你可以通过在HSB或HSL空间中尽可能稀疏地分配它们来实现它;用RGB做这件事可能很困难。

例如,您可能决定使用10种不同的色调,4种不同的饱和度和3种不同的亮度设置,最多可以提供120种颜色。您需要仔细选择饱和度和亮度值;人眼是复杂而混乱的传感器。如果将色彩空间视为圆锥体,则每种亮度/饱和度水平可能需要不同数量的色调。

以下是维基百科entry on HSB的链接。

答案 4 :(得分:2)

不是您的问题的答案,但是,如果 n 具有最大值且您的应用程序允许,您可以使用预定义的颜色列表,如下所示:

http://en.wikipedia.org/wiki/List_of_colors

一个优点是,您可以在工具提示中为有色盲的人显示一个人类可读的颜色名称。

答案 5 :(得分:1)

对于初学者,不要使用RGB空间;这个问题很难找到更糟糕的色彩空间。 (根据您是使用显示颜色还是打印颜色,您可能在黑色或近白色附近有大量难以区分的颜色。)

如果使用Lab空间,可以使用感知颜色模型(CIE 1996?和CIE 2000)来测量颜色的视觉接近度(分别用于打印和显示)。

你没有说你是否要计算一次颜色并存储结果,或者是否需要动态重新计算(在这种情况下,如果它必须是确定性的)。显然,关于如何最好地生成集合的讨论将取决于此。

虽然我建议均匀划分颜色空间的轴(比如8)并使用那些作为初始点比任何随机过程都要有效得多。当然,你只需要将任何一点与它的邻居进行比较(并且只有它们已经在集合中),这将为你节省大量的比较。