Подтвердить что ты не робот

Последующее наблюдение: "Сортировка" цветов по своеобразию

Оригинальный вопрос

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

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

Рандомизация в порядке, но, конечно, не оптимальная.

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

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

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

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

Ответ 6

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

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

Ответ 7

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

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

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;
            }
        }
    }
}

Ответ 8

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

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

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

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

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

Ответ 9

Вы можете разбить их на формат 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

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