Создавайте четко разные цвета RGB на графиках

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

Есть идеи о том, как это можно решить и как можно было бы генерировать отчетливо разные цвета?

Было бы здорово, если бы какие-либо примеры (не стесняйтесь просто обсудить проблему и решение без примеров, если вам так проще) были в цветах C# и RGB.

см. stackoverflow.com/questions/470690/…

Ohad Schneider 08.12.2010 01:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
88
1
71 747
12
Перейти к ответу Данный вопрос помечен как решенный

Ответы 12

Я бы начал с установленной яркости 100% и сначала обошел бы основные цвета:

FF0000, 00FF00, 0000FF

затем комбинации

FFFF00, FF00FF, 00FFFF

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

+1 за отличное предложение использовать разные стили линий вместо исключительно цветов.

Iiridayn 15.08.2012 19:45
Ответ принят как подходящий

У вас есть три цветовых канала от 0 до 255: R, G и B.

Сначала пройди

0, 0, 255
0, 255, 0
255, 0, 0

Тогда пройдите

0, 255, 255
255, 0, 255
255, 255, 0

Затем разделите на 2 => 128 и начните снова:

0, 0, 128
0, 128, 0
128, 0, 0
0, 128, 128
128, 0, 128
128, 128, 0

Разделить на 2 => 64

В следующий раз прибавьте 64 к 128 => 192

следовать шаблону.

Легко программировать и дает довольно четкие цвета.

Обновлено: запрос на образец кода

Также - добавьте дополнительный узор, как показано ниже, если серый является приемлемым цветом:

255, 255, 255
128, 128, 128 

Есть несколько способов их создания в коде.

Легкий путь

Если вы можете гарантировать, что вам никогда не понадобится больше фиксированного количества цветов, просто сгенерируйте массив цветов по этому шаблону и используйте их:

    static string[] ColourValues = new string[] { 
        "FF0000", "00FF00", "0000FF", "FFFF00", "FF00FF", "00FFFF", "000000", 
        "800000", "008000", "000080", "808000", "800080", "008080", "808080", 
        "C00000", "00C000", "0000C0", "C0C000", "C000C0", "00C0C0", "C0C0C0", 
        "400000", "004000", "000040", "404000", "400040", "004040", "404040", 
        "200000", "002000", "000020", "202000", "200020", "002020", "202020", 
        "600000", "006000", "000060", "606000", "600060", "006060", "606060", 
        "A00000", "00A000", "0000A0", "A0A000", "A000A0", "00A0A0", "A0A0A0", 
        "E00000", "00E000", "0000E0", "E0E000", "E000E0", "00E0E0", "E0E0E0", 
    };

Трудный путь

Если вы не знаете, сколько цветов вам понадобится, приведенный ниже код сгенерирует до 896 цветов с использованием этого шаблона. (896 = 256 * 7/2) 256 - это цветовое пространство на канал, у нас есть 7 шаблонов, и мы останавливаемся, прежде чем перейдем к цветам, разделенным только одним цветовым значением.

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

using System;

class Program {
    static void Main(string[] args) {
        ColourGenerator generator = new ColourGenerator();
        for (int i = 0; i < 896; i++) {
            Console.WriteLine(string.Format("{0}: {1}", i, generator.NextColour()));
        }
    }
}

public class ColourGenerator {

    private int index = 0;
    private IntensityGenerator intensityGenerator = new IntensityGenerator();

    public string NextColour() {
        string colour = string.Format(PatternGenerator.NextPattern(index),
            intensityGenerator.NextIntensity(index));
        index++;
        return colour;
    }
}

public class PatternGenerator {
    public static string NextPattern(int index) {
        switch (index % 7) {
        case 0: return "{0}0000";
        case 1: return "00{0}00";
        case 2: return "0000{0}";
        case 3: return "{0}{0}00";
        case 4: return "{0}00{0}";
        case 5: return "00{0}{0}";
        case 6: return "{0}{0}{0}";
        default: throw new Exception("Math error");
        }
    }
}

public class IntensityGenerator {
    private IntensityValueWalker walker;
    private int current;

    public string NextIntensity(int index) {
        if (index == 0) {
            current = 255;
        }
        else if (index % 7 == 0) {
            if (walker == null) {
                walker = new IntensityValueWalker();
            }
            else {
                walker.MoveNext();
            }
            current = walker.Current.Value;
        }
        string currentText = current.ToString("X");
        if (currentText.Length == 1) currentText = "0" + currentText;
        return currentText;
    }
}

public class IntensityValue {

    private IntensityValue mChildA;
    private IntensityValue mChildB;

    public IntensityValue(IntensityValue parent, int value, int level) {
        if (level > 7) throw new Exception("There are no more colours left");
        Value = value;
        Parent = parent;
        Level = level;
    }

    public int Level { get; set; }
    public int Value { get; set; }
    public IntensityValue Parent { get; set; }

    public IntensityValue ChildA {
        get {
            return mChildA ?? (mChildA = new IntensityValue(this, this.Value - (1<<(7-Level)), Level+1));
        }
    }

    public IntensityValue ChildB {
        get {
            return mChildB ?? (mChildB = new IntensityValue(this, Value + (1<<(7-Level)), Level+1));
        }
    }
}

public class IntensityValueWalker {

    public IntensityValueWalker() {
        Current = new IntensityValue(null, 1<<7, 1);
    }

    public IntensityValue Current { get; set; }

    public void MoveNext() {
        if (Current.Parent == null) {
            Current = Current.ChildA;
        }
        else if (Current.Parent.ChildA == Current) {
            Current = Current.Parent.ChildB;
        }
        else {
            int levelsUp = 1;
            Current = Current.Parent;
            while (Current.Parent != null && Current == Current.Parent.ChildB) {
                Current = Current.Parent;
                levelsUp++;
            }
            if (Current.Parent != null) {
                Current = Current.Parent.ChildB;
            }
            else {
                levelsUp++;
            }
            for (int i = 0; i < levelsUp; i++) {
                Current = Current.ChildA;
            }

        }
    }
}

Я не полностью следую этому примеру. Может ли кто-нибудь предоставить для этого пример C#?

McBainUK 09.02.2010 18:23

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

Sam Meldrum 10.02.2010 13:39

Обратите внимание, что этот алгоритм будет создавать ОЧЕНЬ похожие цветовые пары (особенно в очень темных или светлых областях с низкой насыщенностью). Он хорошо справляется с работой в областях с высокой насыщенностью и легкостью, но пропускает много тонких цветов, которые все еще визуально различимы.

Phrogz 23.02.2012 02:40

Я закончил тем, что сделал что-то похожее в Javascript - похоже, есть мысленный костыль / ограничивающий реагент, построенный на rgb. Если бы у нас было 256 цветовых каналов четыре, могли бы мы писать формулы с (* п) большим количеством цветов? Даже в этом случае критика @Phrogz и @dean все равно останется в силе (и поэтому я искал в SO лучший ответ). Должен быть способ захватывать отчетливо разные оттенки на каждом шаге интенсивности. Ответ Phrogz: ниже находится на правильном пути, но не доступен для таких людей, как я, если мне нужны сотни цветов с помощью какого-нибудь счетчика int.

ruffin 21.08.2012 19:36

Я добавил ответ, программно решающий вопрос. Этот ответ здесь на самом деле неверен. Когда вы добавляете 128 к смеси. Вы не просто узнаете его с помощью 0. Вы узнаете его с помощью 0 И 255. Список цветов «Easy Way» в этом отношении также нарушен. Это в основном белые, черные, R, G, B, C, Y, M, постепенно более тусклые и тусклые.

Tatarize 03.09.2012 09:27

Вы можете получить случайный набор из 3 255 значений и сравнить его с последним набором из 3 значений, убедившись, что каждое из них находится как минимум на X от старых значений, прежде чем использовать их.

СТАРАЯ: 190, 120, 100

НОВИНКА: 180, 200, 30

Если X = 20, то новый набор будет регенерирован снова.

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

Tatarize 25.05.2015 11:32

Хм. Как ни странно, в вашем ответе говорится, что значение Любые r, слишком близкое к другому значению R, вызовет регенерацию, в лучшем случае менее 12. Хотя это странно назвало бы цвета Красный и Синий слишком близкими, потому что оба имеют зеленый 0, который находится в пределах 20. Я имею в виду, что буквально ваш пример говорит: colorcodehex.com/be7864colorcodehex.com/b4c81e Слишком близко друг к другу и должны быть регенерированы.

Tatarize 25.05.2015 11:40

Я думаю, что у пространства HSV (или HSL) здесь больше возможностей. Если вы не возражаете против дополнительного преобразования, довольно легко перебрать все цвета, просто повернув значение Hue. Если этого недостаточно, вы можете изменить значения Saturation / Value / Lightness и снова выполнить вращение. Или вы всегда можете сместить значения оттенка или изменить свой «шаговый» угол и повернуть больше раз.

Однако обратите внимание, что даже равномерно переходя по оттенку производит неидеальное перцепционное разделение.

Phrogz 07.05.2014 17:22

Я реализовал этот алгоритм короче

void ColorValue::SetColorValue( double r, double g, double b, ColorType myType )
{
   this->c[0] = r;
   this->c[1] = g;
   this->c[2] = b;

   this->type = myType;
}


DistinctColorGenerator::DistinctColorGenerator()
{
   mFactor = 255;
   mColorsGenerated = 0;
   mpColorCycle = new ColorValue[6];
   mpColorCycle[0].SetColorValue( 1.0, 0.0, 0.0, TYPE_RGB);
   mpColorCycle[1].SetColorValue( 0.0, 1.0, 0.0, TYPE_RGB);
   mpColorCycle[2].SetColorValue( 0.0, 0.0, 1.0, TYPE_RGB);
   mpColorCycle[3].SetColorValue( 1.0, 1.0, 0.0, TYPE_RGB);
   mpColorCycle[4].SetColorValue( 1.0, 0.0, 1.0, TYPE_RGB);
   mpColorCycle[5].SetColorValue( 0.0, 1.0, 1.0, TYPE_RGB);
}

//----------------------------------------------------------

ColorValue DistinctColorGenerator::GenerateNewColor()
{
   int innerCycleNr = mColorsGenerated % 6;
   int outerCycleNr = mColorsGenerated / 6;
   int cycleSize = pow( 2, (int)(log((double)(outerCycleNr)) / log( 2.0 ) ) );
   int insideCycleCounter = outerCycleNr % cyclesize;

   if ( outerCycleNr == 0)
   {
      mFactor = 255;
   }
   else
   {
      mFactor = ( 256 / ( 2 * cycleSize ) ) + ( insideCycleCounter * ( 256 / cycleSize ) );
   }

   ColorValue newColor = mpColorCycle[innerCycleNr] * mFactor;

   mColorsGenerated++;
   return newColor;
}

Вы также можете рассматривать цветовое пространство как все комбинации трех чисел от 0 до 255 включительно. Это представление числа от 0 до 255 ^ 3 в формате base-255, с обязательным использованием трех десятичных знаков (при необходимости добавьте нули в конец).

Итак, чтобы сгенерировать x цветов, вы должны вычислить x равномерно распределенных процентов, от 0 до 100. Получите числа, умножив эти проценты на 255 ^ 3, преобразуя эти числа в основание 255 и добавив нули, как упоминалось ранее.

Базовый алгоритм преобразования, для справки (в псевдокоде, довольно близком к C#):

int num = (number to convert);
int baseConvert = (desired base, 255 in this case);
(array of ints) nums = new (array of ints);
int x = num;
double digits = Math.Log(num, baseConvert); //or ln(num) / ln(baseConvert)
int numDigits = (digits - Math.Ceiling(digits) == 0 ? (int)(digits + 1) : (int)Math.Ceiling(digits)); //go up one if it turns out even
for (int i = 0; i < numDigits; i++)
{
  int toAdd = ((int)Math.Floor(x / Math.Pow((double)convertBase, (double)(numDigits - i - 1))));
  //Formula for 0th digit: d = num / (convertBase^(numDigits - 1))
  //Then subtract (d * convertBase^(numDigits - 1)) from the num and continue
  nums.Add(toAdd);
  x -= toAdd * (int)Math.Pow((double)convertBase, (double)(numDigits - i - 1));
}
return nums;

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

Этот вопрос имеет больше базового преобразования в .NET.

В предыдущих решениях RGB есть изъян. Они не используют все цветовое пространство, поскольку используют значение цвета и 0 для каналов:

#006600
#330000
#FF00FF

Вместо этого они должны использовать все возможные значения цвета для создания смешанных цветов, которые могут иметь до 3 различных значений по цветовым каналам:

#336600
#FF0066
#33FF66

Используя полное цветовое пространство, вы можете создавать более четкие цвета. Например, если у вас есть 4 значения на канал, то можно сгенерировать 4 * 4 * 4 = 64 цветов. С другой схемой можно сгенерировать только 4 * 7 + 1 = 29 цветов.

Если вы хотите N цветов, то необходимое количество значений на канал: ceil (cube_root (N))

При этом вы можете определить возможные значения (диапазон 0-255) (python):

max = 255
segs = int(num**(Decimal("1.0")/3))
step = int(max/segs)
p = [(i*step) for i in xrange(segs)]
values = [max]
values.extend(p)

Затем вы можете перебирать цвета RGB (это не рекомендуется):

total = 0
for red in values:
  for green in values:
    for blue in values:
      if total <= N:
        print color(red, green, blue)
      total += 1

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

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

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

Вот пример из 64 сгенерированных цветов: 64 цвета

Я разместил в Интернете страницу для процедурной генерации визуально отличных цветов:
http://phrogz.net/css/distinct-colors.html

В отличие от других ответов здесь, которые равномерно переходят в пространство RGB или HSV (где есть нелинейная связь между значениями оси и различиями восприятия), моя страница использует стандартный алгоритм цветового расстояния CMI (I: c), чтобы два цвета не были слишком визуально близки.

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

На момент написания этой статьи он хорошо работает только в Chrome и Safari с прокладкой для Firefox; в интерфейсе используются ползунки ввода диапазона HTML5, которые IE9 и Firefox пока не поддерживают изначально.

Это отличный инструмент, спасибо за его создание. Я использовал его для создания 145 различных цветов, и я очень доволен результатами, полученными с помощью вашего инструмента различных цветов.

Malachy 07.05.2014 16:07

Идея звучит неплохо, но я не понимаю, как работает интерфейс. Скажем, я хочу сгенерировать 64 цвета в пространстве Lаb, какой параметр мне следует использовать? Я не могу получить больше 50 цветов.

wip 06.06.2016 11:10

@wil При настройках по умолчанию на странице «Лаборатория» вы можете выбрать из 480 цветов. Когда вы переходите на вкладку «Уточнить», настройте порог, чтобы увидеть больше или меньше образцов.

Phrogz 06.06.2016 17:12

Хотя с 36 цветами я все еще получаю несколько очень похожих цветов.

Nemo 25.11.2017 22:39

Чтобы реализовать список вариантов, в котором идут ваши цвета, 255 затем используйте все возможности этого вверх, затем добавьте 0 и все шаблоны RGB с этими двумя значениями. Затем добавьте к ним 128 и все комбинации RGB. Потом 64. Потом 192. И т. Д.

В Java

public Color getColor(int i) {
    return new Color(getRGB(i));
}

public int getRGB(int index) {
    int[] p = getPattern(index);
    return getElement(p[0]) << 16 | getElement(p[1]) << 8 | getElement(p[2]);
}

public int getElement(int index) {
    int value = index - 1;
    int v = 0;
    for (int i = 0; i < 8; i++) {
        v = v | (value & 1);
        v <<= 1;
        value >>= 1;
    }
    v >>= 1;
    return v & 0xFF;
}

public int[] getPattern(int index) {
    int n = (int)Math.cbrt(index);
    index -= (n*n*n);
    int[] p = new int[3];
    Arrays.fill(p,n);
    if (index == 0) {
        return p;
    }
    index--;
    int v = index % 3;
    index = index / 3;
    if (index < n) {
        p[v] = index % n;
        return p;
    }
    index -= n;
    p[v      ] = index / n;
    p[++v % 3] = index % n;
    return p;
}

Это будет создавать шаблоны этого типа бесконечно (2 ^ 24) в будущем. Однако после сотни или около того пятен вы, вероятно, не заметите большой разницы между цветом с 0 или 32 вместо синего.

Возможно, вам лучше нормализовать это в другом цветовом пространстве. Цветовое пространство LAB, например, с нормализованными и преобразованными значениями L, A, B. Таким образом, отчетливость цвета проявляется в чем-то более похожем на человеческий глаз.

getElement () меняет порядок байтов 8-битного числа и начинает отсчет с -1, а не с 0 (маскирование с 255). Итак, 255,0,127,192,64, ... по мере того, как число растет, оно перемещает все менее и менее значимые биты, разделяя число.

getPattern () определяет, каким должен быть самый важный элемент в шаблоне (это корень куба). Затем переходит к разбиению 3N² + 3N + 1 различных паттернов, которые включают этот наиболее значимый элемент.

Этот алгоритм выдаст (первые 128 значений):

#FFFFFF 
#000000 
#FF0000 
#00FF00 
#0000FF 
#FFFF00 
#00FFFF 
#FF00FF 
#808080 
#FF8080 
#80FF80 
#8080FF 
#008080 
#800080 
#808000 
#FFFF80 
#80FFFF 
#FF80FF 
#FF0080 
#80FF00 
#0080FF 
#00FF80 
#8000FF 
#FF8000 
#000080 
#800000 
#008000 
#404040 
#FF4040 
#40FF40 
#4040FF 
#004040 
#400040 
#404000 
#804040 
#408040 
#404080 
#FFFF40 
#40FFFF 
#FF40FF 
#FF0040 
#40FF00 
#0040FF 
#FF8040 
#40FF80 
#8040FF 
#00FF40 
#4000FF 
#FF4000 
#000040 
#400000 
#004000 
#008040 
#400080 
#804000 
#80FF40 
#4080FF 
#FF4080 
#800040 
#408000 
#004080 
#808040 
#408080 
#804080 
#C0C0C0 
#FFC0C0 
#C0FFC0 
#C0C0FF 
#00C0C0 
#C000C0 
#C0C000 
#80C0C0 
#C080C0 
#C0C080 
#40C0C0 
#C040C0 
#C0C040 
#FFFFC0 
#C0FFFF 
#FFC0FF 
#FF00C0 
#C0FF00 
#00C0FF 
#FF80C0 
#C0FF80 
#80C0FF 
#FF40C0 
#C0FF40 
#40C0FF 
#00FFC0 
#C000FF 
#FFC000 
#0000C0 
#C00000 
#00C000 
#0080C0 
#C00080 
#80C000 
#0040C0 
#C00040 
#40C000 
#80FFC0 
#C080FF 
#FFC080 
#8000C0 
#C08000 
#00C080 
#8080C0 
#C08080 
#80C080 
#8040C0 
#C08040 
#40C080 
#40FFC0 
#C040FF 
#FFC040 
#4000C0 
#C04000 
#00C040 
#4080C0 
#C04080 
#80C040 
#4040C0 
#C04040 
#40C040 
#202020 
#FF2020 
#20FF20 

Читайте слева направо, сверху вниз. 729 цветов (9³). Итак, все шаблоны до n = 9. Вы заметите, с какой скоростью они начинают конфликтовать. Вариантов WRGBCYMK так много. И это решение, хотя и умное, в основном только использует разные оттенки основных цветов.

Color Grid, 729 16x16

Большая часть противоречий связана с зеленым цветом и тем, насколько он похож на большинство людей. Требование, чтобы все они были максимально разными вначале, а не были достаточно разными, чтобы не быть одного цвета. И основные недоработки идеи, приведшие к шаблонам основных цветов и идентичным оттенкам.


Использование CIELab2000 Color Space и Distance Routine для случайного выбора и опробования 10 тысяч различных цветов и нахождения максимально удаленного минимального расстояния от предыдущих цветов (в значительной степени определение запроса) позволяет избежать конфликтов дольше, чем в приведенном выше решении:

Max Color Distance

Это можно было бы назвать статическим списком для Easy Way. На создание 729 записей ушло полтора часа:

#9BC4E5
#310106
#04640D
#FEFB0A
#FB5514
#E115C0
#00587F
#0BC582
#FEB8C8
#9E8317
#01190F
#847D81
#58018B
#B70639
#703B01
#F7F1DF
#118B8A
#4AFEFA
#FCB164
#796EE6
#000D2C
#53495F
#F95475
#61FC03
#5D9608
#DE98FD
#98A088
#4F584E
#248AD0
#5C5300
#9F6551
#BCFEC6
#932C70
#2B1B04
#B5AFC4
#D4C67A
#AE7AA1
#C2A393
#0232FD
#6A3A35
#BA6801
#168E5C
#16C0D0
#C62100
#014347
#233809
#42083B
#82785D
#023087
#B7DAD2
#196956
#8C41BB
#ECEDFE
#2B2D32
#94C661
#F8907D
#895E6B
#788E95
#FB6AB8
#576094
#DB1474
#8489AE
#860E04
#FBC206
#6EAB9B
#F2CDFE
#645341
#760035
#647A41
#496E76
#E3F894
#F9D7CD
#876128
#A1A711
#01FB92
#FD0F31
#BE8485
#C660FB
#120104
#D48958
#05AEE8
#C3C1BE
#9F98F8
#1167D9
#D19012
#B7D802
#826392
#5E7A6A
#B29869
#1D0051
#8BE7FC
#76E0C1
#BACFA7
#11BA09
#462C36
#65407D
#491803
#F5D2A8
#03422C
#72A46E
#128EAC
#47545E
#B95C69
#A14D12
#C4C8FA
#372A55
#3F3610
#D3A2C6
#719FFA
#0D841A
#4C5B32
#9DB3B7
#B14F8F
#747103
#9F816D
#D26A5B
#8B934B
#F98500
#002935
#D7F3FE
#FCB899
#1C0720
#6B5F61
#F98A9D
#9B72C2
#A6919D
#2C3729
#D7C70B
#9F9992
#EFFBD0
#FDE2F1
#923A52
#5140A7
#BC14FD
#6D706C
#0007C4
#C6A62F
#000C14
#904431
#600013
#1C1B08
#693955
#5E7C99
#6C6E82
#D0AFB3
#493B36
#AC93CE
#C4BA9C
#09C4B8
#69A5B8
#374869
#F868ED
#E70850
#C04841
#C36333
#700366
#8A7A93
#52351D
#B503A2
#D17190
#A0F086
#7B41FC
#0EA64F
#017499
#08A882
#7300CD
#A9B074
#4E6301
#AB7E41
#547FF4
#134DAC
#FDEC87
#056164
#FE12A0
#C264BA
#939DAD
#0BCDFA
#277442
#1BDE4A
#826958
#977678
#BAFCE8
#7D8475
#8CCF95
#726638
#FEA8EB
#EAFEF0
#6B9279
#C2FE4B
#304041
#1EA6A7
#022403
#062A47
#054B17
#F4C673
#02FEC7
#9DBAA8
#775551
#835536
#565BCC
#80D7D2
#7AD607
#696F54
#87089A
#664B19
#242235
#7DB00D
#BFC7D6
#D5A97E
#433F31
#311A18
#FDB2AB
#D586C9
#7A5FB1
#32544A
#EFE3AF
#859D96
#2B8570
#8B282D
#E16A07
#4B0125
#021083
#114558
#F707F9
#C78571
#7FB9BC
#FC7F4B
#8D4A92
#6B3119
#884F74
#994E4F
#9DA9D3
#867B40
#CED5C4
#1CA2FE
#D9C5B4
#FEAA00
#507B01
#A7D0DB
#53858D
#588F4A
#FBEEEC
#FC93C1
#D7CCD4
#3E4A02
#C8B1E2
#7A8B62
#9A5AE2
#896C04
#B1121C
#402D7D
#858701
#D498A6
#B484EF
#5C474C
#067881
#C0F9FC
#726075
#8D3101
#6C93B2
#A26B3F
#AA6582
#4F4C4F
#5A563D
#E83005
#32492D
#FC7272
#B9C457
#552A5B
#B50464
#616E79
#DCE2E4
#CF8028
#0AE2F0
#4F1E24
#FD5E46
#4B694E
#C5DEFC
#5DC262
#022D26
#7776B8
#FD9F66
#B049B8
#988F73
#BE385A
#2B2126
#54805A
#141B55
#67C09B
#456989
#DDC1D9
#166175
#C1E29C
#A397B5
#2E2922
#ABDBBE
#B4A6A8
#A06B07
#A99949
#0A0618
#B14E2E
#60557D
#D4A556
#82A752
#4A005B
#3C404F
#6E6657
#7E8BD5
#1275B8
#D79E92
#230735
#661849
#7A8391
#FE0F7B
#B0B6A9
#629591
#D05591
#97B68A
#97939A
#035E38
#53E19E
#DFD7F9
#02436C
#525A72
#059A0E
#3E736C
#AC8E87
#D10C92
#B9906E
#66BDFD
#C0ABFD
#0734BC
#341224
#8AAAC1
#0E0B03
#414522
#6A2F3E
#2D9A8A
#4568FD
#FDE6D2
#FEE007
#9A003C
#AC8190
#DCDD58
#B7903D
#1F2927
#9B02E6
#827A71
#878B8A
#8F724F
#AC4B70
#37233B
#385559
#F347C7
#9DB4FE
#D57179
#DE505A
#37F7DD
#503500
#1C2401
#DD0323
#00A4BA
#955602
#FA5B94
#AA766C
#B8E067
#6A807E
#4D2E27
#73BED7
#D7BC8A
#614539
#526861
#716D96
#829A17
#210109
#436C2D
#784955
#987BAB
#8F0152
#0452FA
#B67757
#A1659F
#D4F8D8
#48416F
#DEBAAF
#A5A9AA
#8C6B83
#403740
#70872B
#D9744D
#151E2C
#5C5E5E
#B47C02
#F4CBD0
#E49D7D
#DD9954
#B0A18B
#2B5308
#EDFD64
#9D72FC
#2A3351
#68496C
#C94801
#EED05E
#826F6D
#E0D6BB
#5B6DB4
#662F98
#0C97CA
#C1CA89
#755A03
#DFA619
#CD70A8
#BBC9C7
#F6BCE3
#A16462
#01D0AA
#87C6B3
#E7B2FA
#D85379
#643AD5
#D18AAE
#13FD5E
#B3E3FD
#C977DB
#C1A7BB
#9286CB
#A19B6A
#8FFED7
#6B1F17
#DF503A
#10DDD7
#9A8457
#60672F
#7D327D
#DD8782
#59AC42
#82FDB8
#FC8AE7
#909F6F
#B691AE
#B811CD
#BCB24E
#CB4BD9
#2B2304
#AA9501
#5D5096
#403221
#F9FAB4
#3990FC
#70DE7F
#95857F
#84A385
#50996F
#797B53
#7B6142
#81D5FE
#9CC428
#0B0438
#3E2005
#4B7C91
#523854
#005EA9
#F0C7AD
#ACB799
#FAC08E
#502239
#BFAB6A
#2B3C48
#0EB5D8
#8A5647
#49AF74
#067AE9
#F19509
#554628
#4426A4
#7352C9
#3F4287
#8B655E
#B480BF
#9BA74C
#5F514C
#CC9BDC
#BA7942
#1C4138
#3C3C3A
#29B09C
#02923F
#701D2B
#36577C
#3F00EA
#3D959E
#440601
#8AEFF3
#6D442A
#BEB1A8
#A11C02
#8383FE
#A73839
#DBDE8A
#0283B3
#888597
#32592E
#F5FDFA
#01191B
#AC707A
#B6BD03
#027B59
#7B4F08
#957737
#83727D
#035543
#6F7E64
#C39999
#52847A
#925AAC
#77CEDA
#516369
#E0D7D0
#FCDD97
#555424
#96E6B6
#85BB74
#5E2074
#BD5E48
#9BEE53
#1A351E
#3148CD
#71575F
#69A6D0
#391A62
#E79EA0
#1C0F03
#1B1636
#D20C39
#765396
#7402FE
#447F3E
#CFD0A8
#3A2600
#685AFC
#A4B3C6
#534302
#9AA097
#FD5154
#9B0085
#403956
#80A1A7
#6E7A9A
#605E6A
#86F0E2
#5A2B01
#7E3D43
#ED823B
#32331B
#424837
#40755E
#524F48
#B75807
#B40080
#5B8CA1
#FDCFE5
#CCFEAC
#755847
#CAB296
#C0D6E3
#2D7100
#D5E4DE
#362823
#69C63C
#AC3801
#163132
#4750A6
#61B8B2
#FCC4B5
#DEBA2E
#FE0449
#737930
#8470AB
#687D87
#D7B760
#6AAB86
#8398B8
#B7B6BF
#92C4A1
#B6084F
#853B5E
#D0BCBA
#92826D
#C6DDC6
#BE5F5A
#280021
#435743
#874514
#63675A
#E97963
#8F9C9E
#985262
#909081
#023508
#DDADBF
#D78493
#363900
#5B0120
#603C47
#C3955D
#AC61CB
#FD7BA7
#716C74
#8D895B
#071001
#82B4F2
#B6BBD8
#71887A
#8B9FE3
#997158
#65A6AB
#2E3067
#321301
#FEECCB
#3B5E72
#C8FE85
#A1DCDF
#CB49A6
#B1C5E4
#3E5EB0
#88AEA7
#04504C
#975232
#6786B9
#068797
#9A98C4
#A1C3C2
#1C3967
#DBEA07
#789658
#E7E7C6
#A6C886
#957F89
#752E62
#171518
#A75648
#01D26F
#0F535D
#047E76
#C54754
#5D6E88
#AB9483
#803B99
#FA9C48
#4A8A22
#654A5C
#965F86
#9D0CBB
#A0E8A0
#D3DBFA
#FD908F
#AEAB85
#A13B89
#F1B350
#066898
#948A42
#C8BEDE
#19252C
#7046AA
#E1EEFC
#3E6557
#CD3F26
#2B1925
#DDAD94
#C0B109
#37DFFE
#039676
#907468
#9E86A5
#3A1B49
#BEE5B7
#C29501
#9E3645
#DC580A
#645631
#444B4B
#FD1A63
#DDE5AE
#887800
#36006F
#3A6260
#784637
#FEA0B7
#A3E0D2
#6D6316
#5F7172
#B99EC7
#777A7E
#E0FEFD
#E16DC5
#01344B
#F8F8FC
#9F9FB5
#182617
#FE3D21
#7D0017
#822F21
#EFD9DC
#6E68C4
#35473E
#007523
#767667
#A6825D
#83DC5F
#227285
#A95E34
#526172
#979730
#756F6D
#716259
#E8B2B5
#B6C9BB
#9078DA
#4F326E
#B2387B
#888C6F
#314B5F
#E5B678
#38A3C6
#586148
#5C515B
#CDCCE1
#C8977F

Использование грубой силы (тестирование всех 16 777 216 цветов RGB с помощью CIELab Delta2000 / Начиная с черного) дает серию. Которые начинают конфликтовать около 26, но могут дойти до 30 или 40 при визуальном осмотре и ручном сбросе (что не может быть выполнено с помощью компьютера). Таким образом, делая абсолютный максимум, можно программно создать только пару десятков различных цветов. Дискретный список - ваш лучший выбор. Вы получите больше дискретных цветов со списком, чем программно. Простой способ - лучшее решение, начните смешивать и сопоставлять с другими способами изменения ваших данных, кроме цвета.

Maximally Different

#000000
#00FF00
#0000FF
#FF0000
#01FFFE
#FFA6FE
#FFDB66
#006401
#010067
#95003A
#007DB5
#FF00F6
#FFEEE8
#774D00
#90FB92
#0076FF
#D5FF00
#FF937E
#6A826C
#FF029D
#FE8900
#7A4782
#7E2DD2
#85A900
#FF0056
#A42400
#00AE7E
#683D3B
#BDC6FF
#263400
#BDD393
#00B917
#9E008E
#001544
#C28C9F
#FF74A3
#01D0FF
#004754
#E56FFE
#788231
#0E4CA1
#91D0CB
#BE9970
#968AE8
#BB8800
#43002C
#DEFF74
#00FFC6
#FFE502
#620E00
#008F9C
#98FF52
#7544B1
#B500FF
#00FF78
#FF6E41
#005F39
#6B6882
#5FAD4E
#A75740
#A5FFD2
#FFB167
#009BFF
#E85EBE

Обновлять: Я продолжал это около месяца, так что при брутфорсе 1024. 1024

public 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",
        "#7A7BFF", "#D68E01", "#353339", "#78AFA1", "#FEB2C6", "#75797C", "#837393", "#943A4D",
        "#B5F4FF", "#D2DCD5", "#9556BD", "#6A714A", "#001325", "#02525F", "#0AA3F7", "#E98176",
        "#DBD5DD", "#5EBCD1", "#3D4F44", "#7E6405", "#02684E", "#962B75", "#8D8546", "#9695C5",
        "#E773CE", "#D86A78", "#3E89BE", "#CA834E", "#518A87", "#5B113C", "#55813B", "#E704C4",
        "#00005F", "#A97399", "#4B8160", "#59738A", "#FF5DA7", "#F7C9BF", "#643127", "#513A01",
        "#6B94AA", "#51A058", "#A45B02", "#1D1702", "#E20027", "#E7AB63", "#4C6001", "#9C6966",
        "#64547B", "#97979E", "#006A66", "#391406", "#F4D749", "#0045D2", "#006C31", "#DDB6D0",
        "#7C6571", "#9FB2A4", "#00D891", "#15A08A", "#BC65E9", "#FFFFFE", "#C6DC99", "#203B3C",
        "#671190", "#6B3A64", "#F5E1FF", "#FFA0F2", "#CCAA35", "#374527", "#8BB400", "#797868",
        "#C6005A", "#3B000A", "#C86240", "#29607C", "#402334", "#7D5A44", "#CCB87C", "#B88183",
        "#AA5199", "#B5D6C3", "#A38469", "#9F94F0", "#A74571", "#B894A6", "#71BB8C", "#00B433",
        "#789EC9", "#6D80BA", "#953F00", "#5EFF03", "#E4FFFC", "#1BE177", "#BCB1E5", "#76912F",
        "#003109", "#0060CD", "#D20096", "#895563", "#29201D", "#5B3213", "#A76F42", "#89412E",
        "#1A3A2A", "#494B5A", "#A88C85", "#F4ABAA", "#A3F3AB", "#00C6C8", "#EA8B66", "#958A9F",
        "#BDC9D2", "#9FA064", "#BE4700", "#658188", "#83A485", "#453C23", "#47675D", "#3A3F00",
        "#061203", "#DFFB71", "#868E7E", "#98D058", "#6C8F7D", "#D7BFC2", "#3C3E6E", "#D83D66",
        "#2F5D9B", "#6C5E46", "#D25B88", "#5B656C", "#00B57F", "#545C46", "#866097", "#365D25",
        "#252F99", "#00CCFF", "#674E60", "#FC009C", "#92896B", "#1E2324", "#DEC9B2", "#9D4948",
        "#85ABB4", "#342142", "#D09685", "#A4ACAC", "#00FFFF", "#AE9C86", "#742A33", "#0E72C5",
        "#AFD8EC", "#C064B9", "#91028C", "#FEEDBF", "#FFB789", "#9CB8E4", "#AFFFD1", "#2A364C",
        "#4F4A43", "#647095", "#34BBFF", "#807781", "#920003", "#B3A5A7", "#018615", "#F1FFC8",
        "#976F5C", "#FF3BC1", "#FF5F6B", "#077D84", "#F56D93", "#5771DA", "#4E1E2A", "#830055",
        "#02D346", "#BE452D", "#00905E", "#BE0028", "#6E96E3", "#007699", "#FEC96D", "#9C6A7D",
        "#3FA1B8", "#893DE3", "#79B4D6", "#7FD4D9", "#6751BB", "#B28D2D", "#E27A05", "#DD9CB8",
        "#AABC7A", "#980034", "#561A02", "#8F7F00", "#635000", "#CD7DAE", "#8A5E2D", "#FFB3E1",
        "#6B6466", "#C6D300", "#0100E2", "#88EC69", "#8FCCBE", "#21001C", "#511F4D", "#E3F6E3",
        "#FF8EB1", "#6B4F29", "#A37F46", "#6A5950", "#1F2A1A", "#04784D", "#101835", "#E6E0D0",
        "#FF74FE", "#00A45F", "#8F5DF8", "#4B0059", "#412F23", "#D8939E", "#DB9D72", "#604143",
        "#B5BACE", "#989EB7", "#D2C4DB", "#A587AF", "#77D796", "#7F8C94", "#FF9B03", "#555196",
        "#31DDAE", "#74B671", "#802647", "#2A373F", "#014A68", "#696628", "#4C7B6D", "#002C27",
        "#7A4522", "#3B5859", "#E5D381", "#FFF3FF", "#679FA0", "#261300", "#2C5742", "#9131AF",
        "#AF5D88", "#C7706A", "#61AB1F", "#8CF2D4", "#C5D9B8", "#9FFFFB", "#BF45CC", "#493941",
        "#863B60", "#B90076", "#003177", "#C582D2", "#C1B394", "#602B70", "#887868", "#BABFB0",
        "#030012", "#D1ACFE", "#7FDEFE", "#4B5C71", "#A3A097", "#E66D53", "#637B5D", "#92BEA5",
        "#00F8B3", "#BEDDFF", "#3DB5A7", "#DD3248", "#B6E4DE", "#427745", "#598C5A", "#B94C59",
        "#8181D5", "#94888B", "#FED6BD", "#536D31", "#6EFF92", "#E4E8FF", "#20E200", "#FFD0F2",
        "#4C83A1", "#BD7322", "#915C4E", "#8C4787", "#025117", "#A2AA45", "#2D1B21", "#A9DDB0",
        "#FF4F78", "#528500", "#009A2E", "#17FCE4", "#71555A", "#525D82", "#00195A", "#967874",
        "#555558", "#0B212C", "#1E202B", "#EFBFC4", "#6F9755", "#6F7586", "#501D1D", "#372D00",
        "#741D16", "#5EB393", "#B5B400", "#DD4A38", "#363DFF", "#AD6552", "#6635AF", "#836BBA",
        "#98AA7F", "#464836", "#322C3E", "#7CB9BA", "#5B6965", "#707D3D", "#7A001D", "#6E4636",
        "#443A38", "#AE81FF", "#489079", "#897334", "#009087", "#DA713C", "#361618", "#FF6F01",
        "#006679", "#370E77", "#4B3A83", "#C9E2E6", "#C44170", "#FF4526", "#73BE54", "#C4DF72",
        "#ADFF60", "#00447D", "#DCCEC9", "#BD9479", "#656E5B", "#EC5200", "#FF6EC2", "#7A617E",
        "#DDAEA2", "#77837F", "#A53327", "#608EFF", "#B599D7", "#A50149", "#4E0025", "#C9B1A9",
        "#03919A", "#1B2A25", "#E500F1", "#982E0B", "#B67180", "#E05859", "#006039", "#578F9B",
        "#305230", "#CE934C", "#B3C2BE", "#C0BAC0", "#B506D3", "#170C10", "#4C534F", "#224451",
        "#3E4141", "#78726D", "#B6602B", "#200441", "#DDB588", "#497200", "#C5AAB6", "#033C61",
        "#71B2F5", "#A9E088", "#4979B0", "#A2C3DF", "#784149", "#2D2B17", "#3E0E2F", "#57344C",
        "#0091BE", "#E451D1", "#4B4B6A", "#5C011A", "#7C8060", "#FF9491", "#4C325D", "#005C8B",
        "#E5FDA4", "#68D1B6", "#032641", "#140023", "#8683A9", "#CFFF00", "#A72C3E", "#34475A",
        "#B1BB9A", "#B4A04F", "#8D918E", "#A168A6", "#813D3A", "#425218", "#DA8386", "#776133",
        "#563930", "#8498AE", "#90C1D3", "#B5666B", "#9B585E", "#856465", "#AD7C90", "#E2BC00",
        "#E3AAE0", "#B2C2FE", "#FD0039", "#009B75", "#FFF46D", "#E87EAC", "#DFE3E6", "#848590",
        "#AA9297", "#83A193", "#577977", "#3E7158", "#C64289", "#EA0072", "#C4A8CB", "#55C899",
        "#E78FCF", "#004547", "#F6E2E3", "#966716", "#378FDB", "#435E6A", "#DA0004", "#1B000F",
        "#5B9C8F", "#6E2B52", "#011115", "#E3E8C4", "#AE3B85", "#EA1CA9", "#FF9E6B", "#457D8B",
        "#92678B", "#00CDBB", "#9CCC04", "#002E38", "#96C57F", "#CFF6B4", "#492818", "#766E52",
        "#20370E", "#E3D19F", "#2E3C30", "#B2EACE", "#F3BDA4", "#A24E3D", "#976FD9", "#8C9FA8",
        "#7C2B73", "#4E5F37", "#5D5462", "#90956F", "#6AA776", "#DBCBF6", "#DA71FF", "#987C95",
        "#52323C", "#BB3C42", "#584D39", "#4FC15F", "#A2B9C1", "#79DB21", "#1D5958", "#BD744E",
        "#160B00", "#20221A", "#6B8295", "#00E0E4", "#102401", "#1B782A", "#DAA9B5", "#B0415D",
        "#859253", "#97A094", "#06E3C4", "#47688C", "#7C6755", "#075C00", "#7560D5", "#7D9F00",
        "#C36D96", "#4D913E", "#5F4276", "#FCE4C8", "#303052", "#4F381B", "#E5A532", "#706690",
        "#AA9A92", "#237363", "#73013E", "#FF9079", "#A79A74", "#029BDB", "#FF0169", "#C7D2E7",
        "#CA8869", "#80FFCD", "#BB1F69", "#90B0AB", "#7D74A9", "#FCC7DB", "#99375B", "#00AB4D",
        "#ABAED1", "#BE9D91", "#E6E5A7", "#332C22", "#DD587B", "#F5FFF7", "#5D3033", "#6D3800",
        "#FF0020", "#B57BB3", "#D7FFE6", "#C535A9", "#260009", "#6A8781", "#A8ABB4", "#D45262",
        "#794B61", "#4621B2", "#8DA4DB", "#C7C890", "#6FE9AD", "#A243A7", "#B2B081", "#181B00",
        "#286154", "#4CA43B", "#6A9573", "#A8441D", "#5C727B", "#738671", "#D0CFCB", "#897B77",
        "#1F3F22", "#4145A7", "#DA9894", "#A1757A", "#63243C", "#ADAAFF", "#00CDE2", "#DDBC62",
        "#698EB1", "#208462", "#00B7E0", "#614A44", "#9BBB57", "#7A5C54", "#857A50", "#766B7E",
        "#014833", "#FF8347", "#7A8EBA", "#274740", "#946444", "#EBD8E6", "#646241", "#373917",
        "#6AD450", "#81817B", "#D499E3", "#979440", "#011A12", "#526554", "#B5885C", "#A499A5",
        "#03AD89", "#B3008B", "#E3C4B5", "#96531F", "#867175", "#74569E", "#617D9F", "#E70452",
        "#067EAF", "#A697B6", "#B787A8", "#9CFF93", "#311D19", "#3A9459", "#6E746E", "#B0C5AE",
        "#84EDF7", "#ED3488", "#754C78", "#384644", "#C7847B", "#00B6C5", "#7FA670", "#C1AF9E",
        "#2A7FFF", "#72A58C", "#FFC07F", "#9DEBDD", "#D97C8E", "#7E7C93", "#62E674", "#B5639E",
        "#FFA861", "#C2A580", "#8D9C83", "#B70546", "#372B2E", "#0098FF", "#985975", "#20204C",
        "#FF6C60", "#445083", "#8502AA", "#72361F", "#9676A3", "#484449", "#CED6C2", "#3B164A",
        "#CCA763", "#2C7F77", "#02227B", "#A37E6F", "#CDE6DC", "#CDFFFB", "#BE811A", "#F77183",
        "#EDE6E2", "#CDC6B4", "#FFE09E", "#3A7271", "#FF7B59", "#4E4E01", "#4AC684", "#8BC891",
        "#BC8A96", "#CF6353", "#DCDE5C", "#5EAADD", "#F6A0AD", "#E269AA", "#A3DAE4", "#436E83",
        "#002E17", "#ECFBFF", "#A1C2B6", "#50003F", "#71695B", "#67C4BB", "#536EFF", "#5D5A48",
        "#890039", "#969381", "#371521", "#5E4665", "#AA62C3", "#8D6F81", "#2C6135", "#410601",
        "#564620", "#E69034", "#6DA6BD", "#E58E56", "#E3A68B", "#48B176", "#D27D67", "#B5B268",
        "#7F8427", "#FF84E6", "#435740", "#EAE408", "#F4F5FF", "#325800", "#4B6BA5", "#ADCEFF",
        "#9B8ACC", "#885138", "#5875C1", "#7E7311", "#FEA5CA", "#9F8B5B", "#A55B54", "#89006A",
        "#AF756F", "#2A2000", "#576E4A", "#7F9EFF", "#7499A1", "#FFB550", "#00011E", "#D1511C",
        "#688151", "#BC908A", "#78C8EB", "#8502FF", "#483D30", "#C42221", "#5EA7FF", "#785715",
        "#0CEA91", "#FFFAED", "#B3AF9D", "#3E3D52", "#5A9BC2", "#9C2F90", "#8D5700", "#ADD79C",
        "#00768B", "#337D00", "#C59700", "#3156DC", "#944575", "#ECFFDC", "#D24CB2", "#97703C",
        "#4C257F", "#9E0366", "#88FFEC", "#B56481", "#396D2B", "#56735F", "#988376", "#9BB195",
        "#A9795C", "#E4C5D3", "#9F4F67", "#1E2B39", "#664327", "#AFCE78", "#322EDF", "#86B487",
        "#C23000", "#ABE86B", "#96656D", "#250E35", "#A60019", "#0080CF", "#CAEFFF", "#323F61",
        "#A449DC", "#6A9D3B", "#FF5AE4", "#636A01", "#D16CDA", "#736060", "#FFBAAD", "#D369B4",
        "#FFDED6", "#6C6D74", "#927D5E", "#845D70", "#5B62C1", "#2F4A36", "#E45F35", "#FF3B53",
        "#AC84DD", "#762988", "#70EC98", "#408543", "#2C3533", "#2E182D", "#323925", "#19181B",
        "#2F2E2C", "#023C32", "#9B9EE2", "#58AFAD", "#5C424D", "#7AC5A6", "#685D75", "#B9BCBD",
        "#834357", "#1A7B42", "#2E57AA", "#E55199", "#316E47", "#CD00C5", "#6A004D", "#7FBBEC",
        "#F35691", "#D7C54A", "#62ACB7", "#CBA1BC", "#A28A9A", "#6C3F3B", "#FFE47D", "#DCBAE3",
        "#5F816D", "#3A404A", "#7DBF32", "#E6ECDC", "#852C19", "#285366", "#B8CB9C", "#0E0D00",
        "#4B5D56", "#6B543F", "#E27172", "#0568EC", "#2EB500", "#D21656", "#EFAFFF", "#682021",
        "#2D2011", "#DA4CFF", "#70968E", "#FF7B7D", "#4A1930", "#E8C282", "#E7DBBC", "#A68486",
        "#1F263C", "#36574E", "#52CE79", "#ADAAA9", "#8A9F45", "#6542D2", "#00FB8C", "#5D697B",
        "#CCD27F", "#94A5A1", "#790229", "#E383E6", "#7EA4C1", "#4E4452", "#4B2C00", "#620B70",
        "#314C1E", "#874AA6", "#E30091", "#66460A", "#EB9A8B", "#EAC3A3", "#98EAB3", "#AB9180",
        "#B8552F", "#1A2B2F", "#94DDC5", "#9D8C76", "#9C8333", "#94A9C9", "#392935", "#8C675E",
        "#CCE93A", "#917100", "#01400B", "#449896", "#1CA370", "#E08DA7", "#8B4A4E", "#667776",
        "#4692AD", "#67BDA8", "#69255C", "#D3BFFF", "#4A5132", "#7E9285", "#77733C", "#E7A0CC",
        "#51A288", "#2C656A", "#4D5C5E", "#C9403A", "#DDD7F3", "#005844", "#B4A200", "#488F69",
        "#858182", "#D4E9B9", "#3D7397", "#CAE8CE", "#D60034", "#AA6746", "#9E5585", "#BA6200"
    };

ИМХО намного лучше принятого ответа. И +1 за наглядные примеры и предварительно рассчитанные списки!

Griddo 08.04.2014 10:57

Я также провел исчерпывающий поиск, чтобы максимизировать CIEDE2000 между добавленным цветом и цветами, которые уже есть в наборе, с черным и белым в качестве предопределенных цветов. Как и вы, я рано получаю два «оттенка кожи»: # ff9d25 (имеет тенденцию к оранжевому) и # ffb46c (имеет тенденцию к розовому). Я думаю, они очень похожи, так что, возможно, CIEDE2000 не так хорош для измерения разницы в цвете. Хотя на данный момент нет ничего лучше. Заманчиво начать проводить свои собственные эксперименты с заметными различиями, возможно, сначала с сеткой sRGB 16x16x16 ...

Olli Niemitalo 21.03.2016 13:46

Я поднялся до 1024, но это заняло у меня больше месяца. Вы можете в равной степени использовать это с другими наборами цветов, у меня их большое количество, варьируя цветовую гамму. И действительно CIEDE2000 действительно лучший. Одно из исправлений в dE2k - это цвет кожи, он выглядит для нас по-другому и имеет большее значение для многих функций. В стандартном dE они намного больше, чем они должны быть на самом деле. А абрикосовый и тускло-желтый выглядят совершенно по-разному. godsnotwheregodsnot.blogspot.com/2012/09/…

Tatarize 22.03.2016 20:44

Единственное серьезное улучшение, которое я заметил, - это статические списки. Поиск цвета, наиболее удаленного от всех других цветов, на самом деле может быть не оптимальным, если вам нужно ровно 20 цветов. Вы могли бы получить лучшие результаты, если бы выполнили кластеризацию и нашли 20 цветов, для которых цветовое расстояние между всеми цветами в наборе максимально. Это может фактически превратиться в коммивояжера, и перебор (2 ^ 24) ^ 20 с помощью очень дорогостоящего алгоритма цветового расстояния может занять много времени. Однако хороший алгоритм кластеризации может быстро дать хороший результат.

Tatarize 22.03.2016 20:58

Хорошая работа @Tatarize. Если вы все еще здесь, вы бы разместили 1024 цвета или обновили ссылку на BlogSpot?

Robert Lugg 26.08.2016 18:36

@RobertLugg Я могу полностью возобновить работу с заданной точки, но мне удалось получить 1024-й цвет, и он был введен в изображения, которые создавала программа, поэтому у меня есть изображение грубой силы для него. Но почему-то я потерял текстовый журнал, который он создавал одинаково, и поэтому не записал цвета 1023 и 1024. У меня только 1022 цвета. Пока я размышлял об исправлении этого и перезапуске программы. если память не изменяет, это примерно день работы для каждого нового цвета в этот момент.

Tatarize 26.08.2016 20:52

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

Tatarize 26.08.2016 20:56

для получения n-го цвета. Просто такого кода было бы достаточно. Это я использую в своей проблеме кластеризации opencv. Это создаст разные цвета при изменении col.

for(int col=1;col<CLUSTER_COUNT+1;col++){
switch(col%6)
   {
   case 1:cout<<Scalar(0,0,(int)(255/(int)(col/6+1)))<<endl;break;
   case 2:cout<<Scalar(0,(int)(255/(int)(col/6+1)),0)<<endl;break;
    case 3:cout<<Scalar((int)(255/(int)(col/6+1)),0,0)<<endl;break;
    case 4:cout<<Scalar(0,(int)(255/(int)(col/6+1)),(int)(255/(int)(col/6+1)))<<endl;break;
    case 5:cout<<Scalar((int)(255/(int)(col/6+1)),0,(int)(255/(int)(col/6+1)))<<endl;break;
    case 0:cout<<Scalar((int)(255/(int)(col/6)),(int)(255/(int)(col/6)),0)<<endl;break;
   }
}

Мне нужна была та же функциональность, но в простой форме.

Мне нужно было создать как можно более уникальные цвета на основе увеличивающегося значения индекса.

Вот код на C# (реализация на любом другом языке должна быть очень похожей)

Механизм очень простой

  1. Шаблон color_writers генерируется из значений indexA от 0 до 7.

  2. Для индексов <8 эти цвета = color_writer [indexA] * 255.

  3. Для индексов от 8 до 15 эти цвета: = color_writer [indexA] * 255 + (color_writer [indexA + 1]) * 127.

  4. Для индексов от 16 до 23 эти цвета: = color_writer [indexA] * 255 + (color_writer [indexA + 1]) * 127 + (color_writer [indexA + 2]) * 63.

И так далее:

Rand Color Generator

    private System.Drawing.Color GetRandColor(int index)
    {
        byte red = 0;
        byte green = 0;
        byte blue = 0;

        for (int t = 0; t <= index / 8; t++)
        {
            int index_a = (index+t) % 8;
            int index_b = index_a / 2;

            //Color writers, take on values of 0 and 1
            int color_red = index_a % 2;
            int color_blue = index_b % 2;
            int color_green = ((index_b + 1) % 3) % 2;

            int add = 255 / (t + 1);

            red = (byte)(red+color_red * add);
            green = (byte)(green + color_green * add);
            blue = (byte)(blue + color_blue * add);
        }

        Color color = Color.FromArgb(red, green, blue);
        return color;
    }

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

    int skip_index = 0;
    private System.Drawing.Color GetRandColor(int index)
    {
        index += skip_index;
        byte red = 0;
        byte green = 0;
        byte blue = 0;

        for (int t = 0; t <= index / 8; t++)
        {
            int index_a = (index+t) % 8;
            int index_b = index_a / 2;

            //Color writers, take on values of 0 and 1
            int color_red = index_a % 2;
            int color_blue = index_b % 2;
            int color_green = ((index_b + 1) % 3) % 2;

            int add = 255 / (t + 1);

            red = (byte)(red + color_red * add);
            green = (byte)(green + color_green * add);
            blue = (byte)(blue + color_blue * add);
        }

        if (red > 200 && green > 200)
        {
            skip_index++;
            return GetRandColor(index);
        }

        Color color = Color.FromArgb(red, green, blue);
        return color;
    }

Если кому-то нужно сгенерировать случайный темный цвет от среднего до высокого для белого переднего плана в C#, вот код.

[DllImport("shlwapi.dll")]
public static extern int ColorHLSToRGB(int H, int L, int S);

public static string GetRandomDarkColor()
{
    int h = 0, s = 0, l = 0;
    h = (RandomObject.Next(1, 2) % 2 == 0) ? RandomObject.Next(0, 180) : iApp.RandomObject.Next(181, 360);
    s = RandomObject.Next(90, 160);
    l = RandomObject.Next(80, 130);

    return System.Drawing.ColorTranslator.FromWin32(ColorHLSToRGB(h, l, s)).ToHex();
}

private static string ToHex(this System.Drawing.Color c)
{
    return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}

Вы можете заменить RandomObject своим собственным объектом класса Random.

Другие вопросы по теме