Вычисление ближайшего цвета в словаре к входу - PullRequest
0 голосов
/ 29 августа 2018

У меня есть словарь цветов (ниже) и цвет, такой как #4a7dac, который 'steelblue' . Я хочу найти название ближайшего шестнадцатеричного цвета в диктаторе этого цвета. Таким образом, алгоритм выберет #0000ff и вернет 'blue' .

colors= {
    "red":"#FF0000",
    "yellow":"#FFFF00",
    "green":"#008000",
    "blue":"#0000FF",
    "black":"#000000",
    "white":"#FFFFFF",
    "gray":"#808080",
}

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

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

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

def diff(h1, h2):
    def hexs_to_ints(s):
        return [int(s[i:i+2], 16) for i in range(1,7,2)]
    return sum(abs(i - j) for i, j in zip(*map(hexs_to_ints, (h1, h2))))

И мы можем проверить это:

>>> diff('#ff00ff', '#0000ff')
255
>>> diff('#0000ff', '#00000a')
245

Итак, теперь мы можем создать функцию, которая использует эту функцию для выполнения задачи:

def get_col_name(hex, colors):
    return min([(n,diff(hex,c)) for n,c in colors.items()], key=lambda t: t[1])[0]

К сожалению, это не работает для ваших цветов, так как он выбирает gray, который [128, 128, 128] очень близок к steelblue, который [74, 125, 172] - ближе, чем blue, который [0, 0, 255]. Это означает, что разница меньше gray, чем blue. Я попытаюсь придумать лучший способ, но, может быть, кто-то знает и может оставить комментарий?

0 голосов
/ 29 августа 2018

Как насчет преобразования их в RGB и поиска доминирующего цвета?

Например

RED FF0000         rgb(255,0,0)
BLUE 0000FF        rgb(0,0,255)
steelblue 4A7DAC   rgb(74,125,172)

Скорее всего, вы можете достичь этой цели с помощью RGB, а не HEX

Остальное вы можете увидеть в этом алгоритме: https://stackoverflow.com/a/9018100/6198978

EDIT Дело в том, что вычисления RGB и HEX не смогут работать с серым цветом, поскольку каждый цвет имеет минимальное расстояние до серого. Для этого вы можете использовать значения цвета HSV, я также редактирую код с помощью HSV: D

Изучил много: D

Мне было весело с этим здесь вы идете:

    import math
    colors= {
    "red":"#FF0000",
    "yellow":"#FFFF00",
    "green":"#008000",
    "blue":"#0000FF",
    "black":"#000000",
    "white":"#FFFFFF",
    "grey": "#808080"
}

# function for HSV TAKEN FROM HERE: https://gist.github.com/mathebox/e0805f72e7db3269ec22
def rgb_to_hsv(r, g, b):
    r = float(r)
    g = float(g)
    b = float(b)
    high = max(r, g, b)
    low = min(r, g, b)
    h, s, v = high, high, high

    d = high - low
    s = 0 if high == 0 else d/high

    if high == low:
        h = 0.0
    else:
        h = {
            r: (g - b) / d + (6 if g < b else 0),
            g: (b - r) / d + 2,
            b: (r - g) / d + 4,
        }[high]
        h /= 6

return h, s, v

# COLOR YOU WANT TO TEST TESTED
check = "#808000".lstrip('#')
checkRGB = tuple(int(check[i:i+2], 16) for i in (0, 2 ,4))
checkHSV = rgb_to_hsv(checkRGB[0], checkRGB[1], checkRGB[2])


colorsRGB = {}
colorsHSV = {}

for c, v in colors.items():
    h = v.lstrip('#')
    colorsRGB[c] = tuple(int(h[i:i+2], 16) for i in (0, 2 ,4))

for c, v in colorsRGB.items():
    colorsHSV[c] = tuple(rgb_to_hsv(v[0], v[1], v[2]))

def colourdistanceRGB(color1, color2):
    r = float(color2[0] - color1[0])
    g = float(color2[1] - color1[1])
    b = float(color2[2] - color1[2])
    return math.sqrt( ((abs(r))**2) + ((abs(g))**2) + ((abs(b))**2) )

def colourdistanceHSV(color1, color2):
    dh = min(abs(color2[0]-color1[0]), 360-abs(color2[0]-color1[0])) / 180.0
    ds = abs(color2[1]-color1[1])
    dv = abs(color2[2]-color1[2]) / 255.0
    return math.sqrt(dh*dh+ds*ds+dv*dv)

resultRGB = {}
resultHSV = {}

for k, v in colorsRGB.items():
    resultRGB[k]=colourdistanceRGB(v, checkRGB)

for k,v in colorsHSV.items():
    resultHSV[k]=colourdistanceHSV(v, checkHSV)


#THIS WILL NOT WORK FOR GREY
print("RESULT WITH RGB FORMULA")
print(resultRGB)
print(min(resultRGB, key=resultRGB.get))


#THIS WILL WORK FOR EVEN GREY
print(resultHSV)
print(min(resultHSV, key=resultHSV.get))

#OUTPUT FOR RGB
#check = "#808000"  output=GREY
#check = "#4A7DAC"  output=GREY :D

#OUTPUT FOR RGB
#check = "#808000"  output=GREEN
#check = "#4A7DAC"  output=BLUE:D
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...