Python PIL - 寻找最近的颜色(四舍五入颜色)

6
有一款名为Roblox的游戏,玩家可以自己制作游戏,通常是使用乐高式积木创建。在Roblox中,对于积木颜色,您可以使用典型的RGB值,但这会导致文件大小不够高效。相比使用RGB值,BrickColor在文件大小方面更加经济实惠。它使用一个整数来表示特定的颜色。这就是我想要表达的意思:Color Codes以下是我的代码片段:
import Image
f = raw_input('Image:\n')
im = Image.open(f)
rgb_im = im.convert('RGB')
r, g, b = rgb_im.getpixel((x, y))

在我的程序中,我需要找到最接近RGB值的颜色代码。

如何实现呢?


1
你有查过乐高颜色指南吗?应该会有一个包括RGB和Pantone的指南来匹配颜色。 - user4171906
2个回答

10

在您的表格中创建一个颜色列表(我称之为colors)。 按照您所询问的r、g、b点的距离对列表进行排序。 列表中的第一个元素是最接近的颜色。

def distance(c1, c2):
    (r1,g1,b1) = c1
    (r2,g2,b2) = c2
    return math.sqrt((r1 - r2)**2 + (g1 - g2) ** 2 + (b1 - b2) **2)

colors = list(rgb_code_dictionary.keys())
closest_colors = sorted(colors, key=lambda color: distance(color, point))
closest_color = closest_colors[0]
code = rgb_code_dictionary[closest_color]

我已经实现了在RGB值表中查找最近的RGB值,但如何将其转换为查找颜色整数(即我在问题中提供的颜色代码)? - Rontron
1
每个RGB值都应该被映射为一个整数作为它们的颜色代码。你可以创建一个字典,其中键是RGB值,值是整数。我要注意的是,RGB值必须是一个元组,而不是一个列表,这样才能成为字典中的键。请参考https://dev59.com/rXI-5IYBdhLWcg3wQWGc - mattsap
2
谢谢,我通过以下方式格式化颜色表使其运行:{(27,42,53):26, (242,243,243):1, (163,162,165):194, etc.} - Rontron
1
这个颜色相似度函数并不是很好,可以参考 https://dev59.com/h2435IYBdhLWcg3weQBy - logi-kal

10

在mattsap的答案基础上进行扩展:

我们不需要对所有颜色进行排序,因为我们只需要找到最接近的那个。也就是说,我们可以避免计算成本高昂的sort,改用min

我们也不需要计算颜色之间的绝对距离,因为我们只关心相对距离。也就是说,我们还可以避免使用勾股定理中的“平方根”部分。

于是我们得到了:

colours = ( (255, 255, 255, "white"),
            (255, 0, 0, "red"),
            (128, 0, 0, "dark red"),
            (0, 255, 0, "green") )


def nearest_colour( subjects, query ):
    return min( subjects, key = lambda subject: sum( (s - q) ** 2 for s, q in zip( subject, query ) ) )


print( nearest_colour( colours, (64, 0, 0) ) ) # dark red
print( nearest_colour( colours, (0, 192, 0) ) ) # green
print( nearest_colour( colours, (255, 255, 64) ) ) # white

当然,一旦考虑到不同的颜色空间以及每个颜色分量对人眼感知的贡献,就会有一个完整的兔子洞要去探究,如这个问题所述,但对于大多数情况来说,这可能过于冗余。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接