Преобразование цвета RGB в английское название цвета, например, "зеленый" с Python

Я хочу преобразовать цветовой кортеж в название цвета, например "желтый" или "синий"

>>> im = Image.open("test.jpg")
>>> n, color = max(im.getcolors(im.size[0]*im.size[1]))
>>> print color
(119, 172, 152)

Есть ли в python простой способ сделать это?

6 ответов

Решение

Похоже, веб-цвета позволят вам сделать это:

rgb_to_name (rgb_triplet, spec = 'css3')

Преобразовать три набора целых чисел, подходящих для использования в триплете цвета rgb(), в соответствующее ему нормализованное имя цвета, если такое имя существует; Допустимые значения: html4, css2, css21 и css3, а по умолчанию - css3.

Пример:

>>> rgb_to_name((0, 0, 0))
'black'

это наоборот:

>>> name_to_rgb('navy')
(0, 0, 128)

Чтобы найти ближайшее название цвета:

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

import webcolors

def closest_colour(requested_colour):
    min_colours = {}
    for key, name in webcolors.css3_hex_to_names.items():
        r_c, g_c, b_c = webcolors.hex_to_rgb(key)
        rd = (r_c - requested_colour[0]) ** 2
        gd = (g_c - requested_colour[1]) ** 2
        bd = (b_c - requested_colour[2]) ** 2
        min_colours[(rd + gd + bd)] = name
    return min_colours[min(min_colours.keys())]

def get_colour_name(requested_colour):
    try:
        closest_name = actual_name = webcolors.rgb_to_name(requested_colour)
    except ValueError:
        closest_name = closest_colour(requested_colour)
        actual_name = None
    return actual_name, closest_name

requested_colour = (119, 172, 152)
actual_name, closest_name = get_colour_name(requested_colour)

print "Actual colour name:", actual_name, ", closest colour name:", closest_name

Выход:

Actual colour name: None , closest colour name: cadetblue

Существует программа под названием pynche, которая может изменить RGB на цветное имя на английском языке для Python.

Вы можете попробовать использовать метод ColorDB.nearest() в ColorDB.py который может делать то, что вы хотите.

Вы можете найти больше информации об этом методе здесь: ColorDB Pynche

Для тех, кто, как и я, хочет более знакомое имя цвета, вы можете использовать имена цветов CSS 2.1, также предоставленные webcolors:

  • аква: #00ffff
  • черный: #000000
  • синий: #0000ff
  • фуксия: #ff00ff
  • зеленый: #008000
  • серый: #808080
  • Лайм: #00ff00
  • бордовый: #800000
  • темно-синий: #000080
  • оливковое: #808000
  • пурпурный: #800080
  • красный: #ff0000
  • Серебряный: #c0c0c0
  • чирок: #008080
  • белый: #ffffff
  • желтый: #ffff00
  • оранжевый: #ffa500

Просто используйте отличный ответ и код fraxel для получения наиболее близкого цвета, адаптированного к CSS 2.1:

def get_colour_name(rgb_triplet):
    min_colours = {}
    for key, name in webcolors.css21_hex_to_names.items():
        r_c, g_c, b_c = webcolors.hex_to_rgb(key)
        rd = (r_c - rgb_triplet[0]) ** 2
        gd = (g_c - rgb_triplet[1]) ** 2
        bd = (b_c - rgb_triplet[2]) ** 2
        min_colours[(rd + gd + bd)] = name
    return min_colours[min(min_colours.keys())]

Решение вашей проблемы состоит в отображении значений RGB в цветовое пространство HSL.

Если у вас есть цвет в цветовом пространстве HSL, вы можете использовать компонент H (оттенок), чтобы отобразить его цвет. Обратите внимание, что цвет является несколько субъективным понятием, поэтому вам придется определить, какие диапазоны H соответствуют данному цвету.

Я бы просто использовал словарь, чтобы выяснить основные цвета, а затем найти ближайший.:

      def get_color_name(rgb):
colors = {
    "red": (255, 0, 0),
    "green": (0, 255, 0),
    "blue": (0, 0, 255),
    "yellow": (255, 255, 0),
    "magenta": (255, 0, 255),
    "cyan": (0, 255, 255),
    "black": (0, 0, 0),
    "white": (255, 255, 255)
}
min_distance = float("inf")
closest_color = None
for color, value in colors.items():
    distance = sum([(i - j) ** 2 for i, j in zip(rgb, value)])
    if distance < min_distance:
        min_distance = distance
        closest_color = color
return closest_color

# Testing
print(get_color_name((255, 0, 0)))  # red
print(get_color_name((0, 255, 0)))  # green
print(get_color_name((0, 0, 255)))  # blue

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

Другие вопросы по тегам