#python #colors #color-palette
#python #Цвет #цвет-палитра
Вопрос:
У меня много цветовых палитр разной длины (все не менее 3 цветов), и я хочу определить способ, с помощью которого я могу извлечь 3 наиболее представительных цвета или найти цвета, которые максимизировали бы «дисперсию» палитры. Например, одна палитра (в шестнадцатеричном формате) равна
['#D2691E', '#8B4513', '#A0522D', '#0000FF', '#668B8B', '#FFC0CB']
это в основном три оттенка коричневого, затем два оттенка синего, затем один оттенок розового. Поэтому я бы хотел, чтобы моя «репрезентативная палитра» была одним из оттенков коричневого, одного синего и одного розового, возможно
['#D2691E', '#0000FF', '#FFC0CB']
или что-то подобное. Я понимаю, что это может быть не совсем просто, но я открыт для интерпретации того, что представляет собой репрезентативность или дисперсию в цветовых палитрах, если это разумно. Спасибо.
Комментарии:
1. «K-означает кластеризацию» может быть … docs.opencv.org/master/d1/d5c/tutorial_py_kmeans_opencv.html
2. О, это прекрасно! Я могу просто преобразовать шестнадцатеричное значение в rgb, а затем сделать rgb полностью числовым и использовать кластеризацию k означает для этих 3D-точек. Отлично!
Ответ №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']
максимально удалены друг от друга.
[Обратите внимание, что это решение может быть оптимизировано, но для этого небольшого приложения, вероятно, оно того не стоит.]