Максимальное разнообразие цветовой палитры

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

['#D2691E', '#8B4513', '#A0522D',  '#0000FF', '#668B8B', '#FFC0CB']

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

['#D2691E', '#0000FF', '#FFC0CB']

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


person Mitch Pudil    schedule 23.09.2020    source источник
comment
Кластеризация K-средних возможно ... docs.opencv .org / master / d1 / d5c / tutorial_py_kmeans_opencv.html   -  person Mark Setchell    schedule 23.09.2020
comment
О, это прекрасно! Я могу просто преобразовать шестнадцатеричный формат в rgb, а затем сделать rgb полностью числовым, и использовать k означает кластеризацию по этим трехмерным точкам. Большой!   -  person Mitch Pudil    schedule 23.09.2020


Ответы (1)


Сначала мы конвертируем шестнадцатеричное представление каждого цвета в палитре в его представление RGB.

from PIL import ImageColor

palette = ['#D2691E', '#8B4513', '#A0522D',  '#0000FF', '#668B8B', '#FFC0CB']
palette_rgb = list(map(lambda x: ImageColor.getcolor(x, "RGB"), palette))

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

from scipy.spatial.distance import pdist, squareform
from itertools import product

d = squareform(pdist(np.array(palette_rgb)))
best = None
best_dist = 0
for i, j, k in product(range(len(palette)), repeat=3):
    dist = d[i, j] + d[j, k] + d[k, i]
    if dist > best_dist:
        best = (i, j, k)
        best_dist = dist
furthest_colors = [palette[i] for i in best]

В этом случае цвета ['#8B4513', '#0000FF', '#FFC0CB'] максимально удалены друг от друга.

[Обратите внимание, что это решение можно оптимизировать, но для этого небольшого приложения оно, вероятно, не стоит того.]

person rlchqrd    schedule 23.09.2020