我有一个rgb值,如果它在我的数据库的颜色表中不存在,我需要找到最接近的颜色。我正在考虑比较所有值并找出差异(红色,绿色和蓝色)然后取平均值。最低的平均偏差应该是最接近的颜色。在我看来应该有一个更好的方法。有什么想法吗?
答案 0 :(得分:65)
将颜色视为三维空间中的矢量,然后可以使用3d毕达哥拉斯轻松计算差异:
d = sqrt((r2-r1)^2 + (g2-g1)^2 + (b2-b1)^2)
然而,请注意,由于颜色会被不太完美的眼睛解释,您可能需要调整颜色以避免它们具有相同的重要性。
例如,使用a typical weighted approach:
d = sqrt(((r2-r1)*0.3)^2 + ((g2-g1)*0.59)^2 + ((b2-b1)*0.11)^2)
由于眼睛对绿色最敏感,对蓝色最不敏感,因此只有蓝色成分不同的两种颜色必须具有更大的数值差异才能被认为是“更不同”,而不是相同的数字差异。绿色成分。
还有各种方法可以优化此计算。例如,由于您对实际的d
值并不感兴趣,因此您可以省去平方根:
d = ((r2-r1)*0.30)^2
+ ((g2-g1)*0.59)^2
+ ((b2-b1)*0.11)^2
请注意,在许多基于C语法的编程语言(如C#)中,^
并不意味着“提升功率”,而是“二进制独占或”。
因此,如果这是C#,您将使用Math.Pow
来计算该部分,或者只是展开并进行乘法。
已添加:根据Color difference on Wikipedia上的页面判断,有各种标准尝试处理感知差异。例如,名为CIE94的那个在L*C*h
颜色模型中使用了一个不同的公式,看起来值得研究,但这取决于你想要的准确度。
答案 1 :(得分:3)
以下内容完全符合您的描述:
select (abs(my_R - t.r) + abs(my_G - t.g) + abs(my_B - t.b)) / 3 as difference, t.*
from RGBtable t
order by difference desc;
但是,使用非线性的东西可能会获得更好的效果。在“取平均值”方法中,如果目标颜色为(25,25,25),则颜色(45,25,25)将比(35,35,35)更接近。但是,我敢打赌,第二个实际上看起来更接近,因为它也是灰色的。
我想到了一些想法:你可以在平均差异之前尝试平衡差异。或者你可以做一些复杂的事情,找到不同值之间最接近的比率的颜色。找到最接近的比率会使你最接近正确的色调,但不会考虑饱和度(如果我记得这些术语是正确的......)
答案 2 :(得分:3)
Euclidean distance difference = sqrt(sqr(red1 - red2) + sqr(green1 - green2) + sqr(blue1 - blue2))
是standard way,用于确定两种颜色的相似性。
但是,如果您将颜色放在一个简单的列表中,那么要找到最近的颜色,需要计算新颜色与列表中每种颜色的距离。这是O(n)操作。
sqrt()
是一项昂贵的操作,如果你只是比较两个距离,那么你可以简单地省略sqrt()
。
如果你有一个非常大的颜色调色板,可能会更快地将颜色组织成kd tree(或alternatives之一),以减少需要计算的diffreen数量
答案 3 :(得分:2)
让数据库为您完成:
select top 1
c.r,
c.b,
c.g
from
color c
order by
(square(c.r - @r) + square(c.g - @g) + square(c.b - @b))
@r
,@g
和@b
是您要搜索的颜色的r,g,b值(SQL Server参数语法,因为您没有指定数据库)。请注意,由于order by
中有函数调用,因此仍需要进行表扫描。
请注意,实际上不需要额外的平方根调用,因为它是单调函数。并不是说它可能非常重要,但仍然如此。
答案 4 :(得分:1)
从the Wikipedia page on Color difference开始,我们的想法是将RGB颜色视为三维中的点。两种颜色之间的差异与两点之间的距离相同:
difference = sqrt((red1 - red2)^2 + (green1 - green2)^2 + (blue1 - blue2)^2)
答案 5 :(得分:1)
比平均值更好的一步是最近的平方根:
((delta red)^2 + (delta green)^2 + (delta blue)^2)^0.5
这样可以最大限度地减少3D色彩空间中的距离。
由于root严格增加,您可以搜索广场的最大值。如何在SQL中表达它将取决于您正在使用的RDBMS。
答案 6 :(得分:0)
像这样计算平均值和距离:
(r + g + b) / 3 = average
(r - average) + (g - average) + (b - average) = distance
这可以让你对最接近的值有所了解。
答案 7 :(得分:0)
每次将颜色样本与整个颜色列表进行比较可能不是最佳选择。可以通过将颜色列表中的颜色放入搜索树中来进行优化。如果要比较颜色样本的红色,绿色和蓝色(RGB)值,则可以将颜色列表中的颜色放入三维搜索树中。搜索树可以创建一次,然后保存到(json,xml)文件或数据库中。如果速度很重要,例如有很多要比较的地方。