Как сгенерировать n разных цветов для любого натурального числа n?

Скажите n = 100; Как создать 100 визуально различных цветов? Возможно ли это математически?

Ответ 1

100 - это много цветов, но вы можете сделать это, распределив их как можно более редко в пространстве HSB или HSL; делать это в RGB, вероятно, сложно.

Например, вы можете использовать 10 разных оттенков, 4 разных уровня насыщенности и 3 разных параметра яркости, что даст вам до 120 цветов. Вы должны тщательно выбрать значения насыщенности и яркости; глаза человека сложны и запутывают датчики. Если вы рассматриваете цветовое пространство как конус, вы, вероятно, захотите различного количества оттенков на каждом уровне яркости/насыщенности.

Здесь ссылка на запись wikipedia в HSB.

Ответ 2

Да. Определение различий - это произведение отсрочки на цветовое пространство, тогда, когда мы говорим о максимально разных цветах, то, что мы хотим сказать, это цвета, которые так же далеки от всех других цветов. Но поскольку цветовое пространство не меняется, ответ не изменится. И внедряя что-то, что лучше подходит человеческим глазам и как человеческие глаза видят цвет, как расстояние между цветами 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 в начале, а затем отображая цветовое пространство. Итак, да, грубая сила и алгоритм цветного цвета высокого уровня, и вы сами настроитесь на этот же набор цветов. В течение дня или около того.

Ответ 3

Edit:

У меня нет опыта в этой области, и мои математические навыки довольно средние. Но я считаю, что решение этой проблемы более сложное и интересное, чем многие из предложенных здесь вариантов, поскольку я попытался сделать что-то подобное недавно и не нашел решения.

Разница цветов

Восприятие цвета, конечно, субъективно, но между людьми существует значительное согласие. Например, мы все можем согласиться с тем, что красный, зеленый и синий цвета очень разные, и даже люди с дальновидностью согласны с тем, что черно-белые очень разные.

RGB

Наиболее распространенным представлением цвета в компьютерных системах является вектор (r, g, b), который предлагает простую функцию расстояния, например,

RGB color difference

Позволяет установить диапазон для 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), что правдоподобно

До сих пор так хорошо. Однако проблема состоит в том, что синий и красный имеют одинаковое расстояние 1 от черного (0, 0, 0), но при просмотре изображения это выглядит не так:

blue and red on black

Также желтые (1, 1, 0) и пурпурные (1, 0, 1) имеют одинаковое расстояние 1 от белого (1, 1, 1), что не кажется имеет смысл:

yellow and magenta on white

HSL и HSV

Я думаю, можно с уверенностью предположить, что аналогичные показатели для цветовых схем HSL и HSV имеют те же проблемы. Эти цветовые схемы не предназначены для сравнения цвета.

CIEDE2000

К счастью, есть ученые, которые уже пытаются найти хороший способ сравнить цвета. Они придумали некоторые сложные методы, последний из которых 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

У этого алгоритма есть некоторые проблемы:

  • Интервал между цветами не является оптимальным. Если мы предположим, что цвета будут похожими на числа на линии, три числа будут оптимально распределены следующим образом:

    | ----- ----- Ь с |

    Упаковка дополнительного одного номера там без перемещения a, b и c явно хуже, чем перестановка всех цветов.

  • Алгоритм не гарантирует завершение. Что делать, если нет цвета, который достаточно далеко от существующих цветов в списке? Цикл будет продолжаться вечно

Правильное решение

Ну.. у меня его нет.

Ответ 4

Вы хотите преобразовать в HSL, а затем итерации по значениям оттенка (H), сохраняя при этом другие 2 значения.

Для каждого значения вы конвертируете из HSL обратно в RGB.

Смотрите мои ответы здесь и здесь.

Если ваш N очень большой, и поэтому цвета НЕ визуально различны, вы можете в этот момент повторно повторить все одинаковые оттенки и изменить другие компоненты, чтобы изменить насыщенность или яркость. Таким образом, в основном вы можете использовать максимальное количество значений оттенков, и как только это ударит, вы можете начать с другой насыщенности или яркости.

Ответ 5

Не ответ на ваш вопрос, но если n имеет максимальное значение и ваше приложение позволяет это, вы можете использовать предопределенный список цветов, например:

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

Одно из преимуществ заключается в том, что вы можете показать человечно читаемое имя цвета во всплывающей подсказке для людей с цветной слепотой.

Ответ 6

Для начала не используйте RGB-пространство; трудно найти худшее цветовое пространство для этой проблемы. (В зависимости от того, используете ли вы цвета для отображения или для печати, у вас есть огромное количество неразличимых цветов рядом с черным или почти белым.)

Если вы используете лабораторное пространство, есть цветные модели восприятия (CIE 1996? и CIE 2000) для измерения визуальной близости цветов (для печати и отображения соответственно).

Вы не говорите, если вы собираетесь вычислить цвета один раз и сохранить результат, или если их нужно передумать "на лету" (и в этом случае, если он должен быть детерминированным или нет). Очевидно, что любое обсуждение того, как лучше всего сгенерировать набор, будет зависеть от этого.

Хотя я бы предположил, что равномерное разделение осей цветового пространства (скажем, на 8) и использование их в качестве исходных точек было бы намного более эффективным, чем любой случайный процесс. Конечно, вам нужно только сравнить любую точку со своими соседями (и только если они уже находятся в наборе), что позволит вам сэкономить огромное количество сравнений.