Сведения о вопросе

rjevskii

16:03, 1st July, 2020

Теги

Последующие действия: "Sorting" цветов по различительности

Просмотров: 445   Ответов: 9

первоначальный вопрос

Если вам дано N максимально удаленных цветов (и некоторая связанная метрика расстояния), можете ли вы придумать способ сортировки этих цветов в некотором порядке, чтобы первые M также были разумно близки к максимально отличному набору?

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

Рандомизация-это OK, но, конечно, не оптимально.

Уточнение: учитывая некоторый большой и визуально различимый набор цветов (скажем, 256 или 1024), я хочу отсортировать их так, чтобы при использовании первого, скажем, 16 из них я получал относительно визуально различимое подмножество цветов. Это эквивалентно, грубо говоря, тому, что я хочу отсортировать этот список 1024 так, чтобы чем ближе отдельные цвета визуально, тем дальше они находятся в списке.



  Сведения об ответе

prince

18:03, 1st July, 2020

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

Например, вот один из способов, возможно, сделать то, что вы хотите.

  1. Вычислите расстояние (ref ваш другой пост ) от каждого цвета до всех других цветов
  2. Суммируйте расстояния для каждого цвета, это даст вам представление о том, как далеко этот цвет находится от всех других цветов в целом
  3. Упорядочивайте список по расстоянию, спускаясь вниз

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

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


  Сведения об ответе

padenie

18:03, 1st July, 2020

Эта проблема называется цветовым квантованием и имеет много хорошо известных алгоритмов: http://en.wikipedia.org/wiki/Color_quantization я знаю людей, которые реализовали подход octree для хорошего эффекта.


  Сведения об ответе

+-*/

18:03, 1st July, 2020

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

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


  Сведения об ответе

lool

18:03, 1st July, 2020

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


  Сведения об ответе

ЯЯ__4

18:03, 1st July, 2020

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

Используя цвет Евклидово расстояние:

public double colordistance(Color color0, Color color1) {
    int c0 = color0.getRGB();
    int c1 = color1.getRGB();
    return distance(((c0>>16)&0xFF), ((c0>>8)&0xFF), (c0&0xFF), ((c1>>16)&0xFF), ((c1>>8)&0xFF), (c1&0xFF));
}

public double distance(int r1, int g1, int b1, int r2, int g2, int b2) {
    int dr = (r1 - r2);
    int dg = (g1 - g2);
    int db = (b1 - b2);
    return Math.sqrt(dr * dr + dg * dg + db * db);
}

Хотя вы можете заменить его на все, что захотите. Ему просто нужна процедура цветового расстояния.

public void colordistancesort(Color[] candidateColors, Color[] indexColors) {
    double current;

    double distance[] = new double[candidateColors.length];
    for (int j = 0; j < candidateColors.length; j++) {
        distance[j] = -1;
        for (int k = 0; k < indexColors.length; k++) {
            current = colordistance(indexColors[k], candidateColors[j]);
            if ((distance[j] == -1) || (current < distance[j])) {
                distance[j] = current;
            }
        }
    }

    //just sorts.
    for (int j = 0; j < candidateColors.length; j++) {
        for (int k = j + 1; k < candidateColors.length; k++) {
            if (distance[j] > distance[k]) {
                double d = distance[k];
                distance[k] = distance[j];
                distance[j] = d;

                Color m = candidateColors[k];
                candidateColors[k] = candidateColors[j];
                candidateColors[j] = m;
            }
        }
    }
}


  Сведения об ответе

ASER

18:03, 1st July, 2020

  1. Начните с двух списков. CandidateColors, который изначально содержит ваши различные цвета и SortedColors, который изначально пуст.
  2. Выберите любой цвет, удалите его из CandidateColors и поместите в SortedColors. Это первый цвет и будет наиболее распространенным, поэтому это хорошее место, чтобы выбрать цвет, который хорошо сочетается с вашим приложением.
  3. Для каждого цвета в CandidateColors вычислите его общее расстояние. Общее расстояние - это сумма расстояний от CandidateColor до каждого из цветов в SortedColors.
  4. Удалите цвет с наибольшим общим расстоянием от CandidateColors и добавьте его в конец SortedColors.
  5. Если CandidateColors не пусто, вернитесь к шагу 3.

Этот жадный алгоритм должен дать вам хорошие результаты.


  Сведения об ответе

PROGA

18:03, 1st July, 2020

Если я правильно понимаю вопрос, вы хотите получить подмножество M цветов с наибольшим средним расстоянием между цветами, учитывая некоторую функцию расстояния d .

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

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

  1. Генерация M случайных точек в цветовом пространстве
  2. Вычислите расстояние между каждой точкой
  3. Вычислите векторы отталкивания для каждой точки, которая будет отдалять ее от всех других точек (используя 1 / (расстояние ^ 2) в качестве величины вектора)
  4. Суммируйте векторы отталкивания для каждой точки
  5. Обновите положение каждой точки в соответствии с суммированными векторами отталкивания
  6. Ограничьте любые из связанных координат (например, светимость становится отрицательной или выше единицы)
  7. Повторите с шага 2, пока точки не стабилизируются
  8. Для каждой точки выберите ближайший цвет из исходного набора N

Это далеко не эффективно, но для малых м это может быть достаточно эффективно, и это даст почти оптимальные результаты.

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


  Сведения об ответе

repe

18:03, 1st July, 2020

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

В качестве лучшего примера уменьшите истинный цвет (24-битное цветовое пространство) до 8-битного отображенного цветового пространства (GIF?).

Для этого существуют алгоритмы квантования, такие как алгоритм адаптивного пространственного разделения , используемый ImageMagic.

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

Если вам нужно что-то еще, то я не понял вашего вопроса :)


  Сведения об ответе

DO__IT

18:03, 1st July, 2020

Вы можете разделить их в формате RGB HEX, чтобы можно было сравнить R с R другого цвета, то же самое с G и B.

Тот же формат, что и HTML

XX XX XX
RR GG BB

00 00 00 = black
ff ff ff = white
ff 00 00 = red
00 ff 00 = green
00 00 ff = blue

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться