首页 > 解决方案 > Python Webcolors - 没有定义的颜色名称

问题描述

我想使用webcolors获取十六进制颜色值的名称。

我为每个规格运行了一个图像css2, css21, css3, html4

每次我运行时,都会出现以下错误:

'#30403c' has no defined color name in css3
'#d4b6c0' has no defined color name in css3
'#8e7766' has no defined color name in css3

'#30403c' has no defined color name in html4
'#d4b6c0' has no defined color name in html4
'#8e7766' has no defined color name in html4
.
.

这是示例图像

这是我用来产生错误的代码:

import cv2
import webcolors
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from collections import Counter


# Source: https://gist.github.com/kb22/f17e59a79d4fcca02188c23cca932be5#file-rgb2hex-py
def rgb2hex(c):
    return "#{:02x}{:02x}{:02x}".format(int(c[0]), int(c[1]), int(c[2]))  # format(int(c[0]), int(c[1]), int(c[2]))



def hex2name(c):
    h_color = '#{:02x}{:02x}{:02x}'.format(int(c[0]), int(c[1]), int(c[2]))
    try:
        nm = webcolors.hex_to_name(h_color, spec='css3')
    except ValueError as v_error:
        print("{}".format(v_error))
        nm = h_color
    return nm


img = cv2.imread("img/landscape.jpg")
img2 = img.reshape(img.shape[0] * img.shape[1], 3)
color = KMeans(n_clusters=3)
lbl = color.fit_predict(img2)
cnt = Counter(lbl)
center_color = color.cluster_centers_
ord_color = [center_color[i] for i in cnt.keys()]
hex_color = [rgb2hex(ord_color[i]) for i in cnt.keys()]
lbl_color = [hex2name(ord_color[i]) for i in cnt.keys()]
plt.pie(cnt.values(), labels=lbl_color, colors=hex_color)
plt.show()

结论是当前规范中不存在生成的十六进制值。

因此,是否可以选择最接近我当前十六进制值的可用十六进制值?

或赞赏任何其他解决方案。

问候

标签: pythonopencv

解决方案


正如@fmw42 建议的那样,我们可以获得最接近的图像。(非常感谢楼主,谢谢你的建议。)

  • 计算您的测试颜色与所有颜色名称的颜色值之间的 rmse 差异。取 rmse 最小的那个。您需要将十六进制转换为 r,g,b 以进行 rmse 计算。

对于每个图像名称,十六进制值,将每个十六进制值转换为 rgb。

for img_clr, img_hex in webcolors.CSS3_NAMES_TO_HEX.items():
    cur_clr = webcolors.hex_to_rgb(img_hex)

计算均方根误差 (RMSE)

rmse = np.sqrt(mean_squared_error(c, cur_clr))

其中c变量是我们的当前rgb值。

将其存储在列表中

rms_lst.append(rmse)

获取最接近的图像名称的索引

closest_color = rms_lst.index(min(rms_lst))

获取图片名称

nm = list(webcolors.CSS3_NAMES_TO_HEX.items())[closest_color][0]

例子:

在此处输入图像描述

代码:


import cv2
import sys
import glob
import webcolors
import numpy as np
import matplotlib.pyplot as plt

from sklearn.cluster import KMeans
from sklearn.metrics import mean_squared_error
from collections import Counter


# Source: https://gist.github.com/kb22/f17e59a79d4fcca02188c23cca932be5#file-rgb2hex-py
def rgb2hex(c):
    return "#{:02x}{:02x}{:02x}".format(int(c[0]), int(c[1]), int(c[2]))  # format(int(c[0]), int(c[1]), int(c[2]))


def hex2name(c):
    h_color = '#{:02x}{:02x}{:02x}'.format(int(c[0]), int(c[1]), int(c[2]))
    try:
        nm = webcolors.hex_to_name(h_color, spec='css3')
    except ValueError as v_error:
        print("{}".format(v_error))
        rms_lst = []
        for img_clr, img_hex in webcolors.CSS3_NAMES_TO_HEX.items():
            cur_clr = webcolors.hex_to_rgb(img_hex)
            rmse = np.sqrt(mean_squared_error(c, cur_clr))
            rms_lst.append(rmse)

        closest_color = rms_lst.index(min(rms_lst))

        nm = list(webcolors.CSS3_NAMES_TO_HEX.items())[closest_color][0]
    return nm


img = cv2.imread("img/landscape.jpg")
img2 = img.reshape(img.shape[0] * img.shape[1], 3)
color = KMeans(n_clusters=3)
lbl = color.fit_predict(img2)
cnt = Counter(lbl)
center_color = color.cluster_centers_
ord_color = [center_color[i] for i in cnt.keys()]
hex_color = [rgb2hex(ord_color[i]) for i in cnt.keys()]
lbl_color = [hex2name(ord_color[i]) for i in cnt.keys()]
plt.pie(cnt.values(), labels=lbl_color, colors=hex_color)
plt.show()

推荐阅读