颜色名称与值配对

1 投票
2 回答
555 浏览
提问于 2025-04-17 14:50

我正在从科学论文中的图形提取信息,主要是对图像本身进行处理,同时对图的说明文字进行自然语言处理。

现在我已经把图像中的物体分离出来,并为每个物体得到了一个“平均”颜色(我用的是RGB和Lab两种颜色空间,但还不确定哪种更好)。从说明文字中,我提取了一份物体的列表,以及用来描述它们的颜色名称。

所以我现在有两个列表:

names = ['Red', 'Brown', 'Yellow', 'Magenta'];
rgbs = [ (249,0,252), (253,0,1), (250,248,60), (140,70,20)];

我想找一个自动化的方法来确定名称和颜色值之间的最佳配对。想了想,我觉得可以先用一个查找表,把所有常见的颜色名称转换成它们的“标准”RGB值。然后我可以计算每个RGB值和每个名称对应的RGB值之间的“距离”(可能是欧几里得距离?)。在这个阶段,我应该能用这些距离来找到最佳配对,但我不太确定具体该怎么做。

有没有人有好的想法,或者知道有什么库可以提供有用的工具?

2 个回答

1

我也碰巧需要一个值转名字的功能,发现这里的帖子很有帮助。不过,我自己想出来的东西是这样的:

from bs4 import BeautifulSoup
import requests
import sys 

def squ_diff(c1, c2):
    return ((c1 & 0x0000FF) - (c2 & 0x0000FF))**2 +\
           (((c1 & 0x00FF00)>>8) - ((c2 & 0x00FF00)>>8))**2 +\
           (((c1 & 0xFF0000)>>16) - ((c2 & 0xFF0000)>>16))**2

def best_match(c, ref):
    """Find the best match for color c.
    Uses least square to determine fitness.
    """
    diff = squ_diff(0xFFFFFF, 0x000000)
    best = "None"
    for ref_color in ref:
        curr_diff = squ_diff(c, ref_color[1])
        #if curr_diff < 1000:
        #    print curr_diff, ref_color[0], hex(ref_color[1])
        if curr_diff < diff:
            diff = curr_diff
            best = ref_color[0]
    return best

def get_ref():
    """Retreives some reference colors.
    Format:
        [("red", 0xFF0000), ("green", 0x00FF00), ("blue", 0x0000FF)]
    """
    html = requests.get("http://jadecat.com/tuts/colorsplus.html").content
    soup = BeautifulSoup(html)
    return [(e.text[:-6].strip(), int(e.text[-6:], 16)) for e in soup.find_all("td")[2:]]

if __name__ == "__main__":
    """For testing, just provide a hex value as the argument.
    """
    r = get_ref()
    print best_match(int(sys.argv[1], 16), r)

这个代码会根据一个参考表(我随便从网上找的)来计算最小平方差,从而把一个名字和给定的颜色值配对起来。我并没有特别考虑人类的颜色感知,所以这个方法可能不是特别科学,但效果还算不错。希望这个对某些人有用,你可以根据自己的需要修改评分函数。

Shai提到的工作真的很有意思,这也意味着我的算法在某些颜色上可能会出错。不过,这个方法的核心思想是尽量给尽可能多的颜色起名字,以减少这种错误的发生。比如,你甚至可以把多个颜色值都映射到“红色”。

2

试着看看这篇文章,它似乎解决了一个类似的问题。

你能从不同的图形中获取这样的名称和RGB值的配对列表吗?
如果可以的话,通过对比这些列表,你可能会找到一些颜色名称,它们在多个配对中是共同的(只有这种颜色),然后再试着找出那个“尽可能常见”的RGB三元组(可以有一点点偏差)。
你可以继续这个筛选过程,直到找出所有的颜色。

举个例子:假设你有

{ ['Red','Green'], {[1 0 0], [0 1 0]} }
{ ['Red','blue'] , {[.9 .1. 1], [ .2 .3 .9] }

你在交集中得到了'红色',以及[1 0 0]和[0.9 0.1 0.1]这两个最接近的颜色。

撰写回答