Скажите n = 100; Как создать 100 визуально различных цветов? Возможно ли это математически?
Как сгенерировать n разных цветов для любого натурального числа n?
Ответ 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 в качестве изображения.
(слева направо) (сверху вниз). Вы могли бы получить несколько более ярких цветов, если бы вы удостоверились, что каждый цвет был как можно более равноудаленным в цветовом пространстве. Эта таблица поиска выбирает каждый дополнительный цвет как максимально отличающийся от всех предыдущих цветов, а не обозначая N в начале, а затем отображая цветовое пространство. Итак, да, грубая сила и алгоритм цветного цвета высокого уровня, и вы сами настроитесь на этот же набор цветов. В течение дня или около того.
Ответ 3
Edit:
У меня нет опыта в этой области, и мои математические навыки довольно средние. Но я считаю, что решение этой проблемы более сложное и интересное, чем многие из предложенных здесь вариантов, поскольку я попытался сделать что-то подобное недавно и не нашел решения.
Разница цветов
Восприятие цвета, конечно, субъективно, но между людьми существует значительное согласие. Например, мы все можем согласиться с тем, что красный, зеленый и синий цвета очень разные, и даже люди с дальновидностью согласны с тем, что черно-белые очень разные.
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), что правдоподобно
До сих пор так хорошо. Однако проблема состоит в том, что синий и красный имеют одинаковое расстояние 1 от черного (0, 0, 0), но при просмотре изображения это выглядит не так:
Также желтые (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
У этого алгоритма есть некоторые проблемы:
-
Интервал между цветами не является оптимальным. Если мы предположим, что цвета будут похожими на числа на линии, три числа будут оптимально распределены следующим образом:
| ----- ----- Ь с |
Упаковка дополнительного одного номера там без перемещения 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) и использование их в качестве исходных точек было бы намного более эффективным, чем любой случайный процесс. Конечно, вам нужно только сравнить любую точку со своими соседями (и только если они уже находятся в наборе), что позволит вам сэкономить огромное количество сравнений.