HSL插值

3
如果我HSL颜色的色相分量是以度为单位的,那么如何在两个色相之间正确地进行插值?使用(h1 + h2)/ 2似乎不能在所有情况下产生理想的结果。以下是两个示例,说明为什么:
假设:
红色= 0° 黄色= 60° 蓝色= 240°
(红+黄)/ 2 = 30°(橙色) (黄+蓝)/ 2 = 150°(青绿色) (红+蓝)/ 2 = 120°(绿色)
正如您所看到的,平均红色和蓝色会产生绿色而不是紫色/洋红色!但是,如果我们假设:
红色= 360° 黄色= 60° 蓝色= 240°
(红+黄)/ 2 = 210°(青绿色) (黄+蓝)/ 2 = 150°(青绿色) (红+蓝)/ 2 = 300°(洋红色)
现在,红色和蓝色产生了预期的颜色,但是红色和黄色产生了一种蓝绿色!有什么方法可以插值颜色的色相分量,使结果与混合实际颜料时预期的结果相匹配?谢谢!
3个回答

3
您基本上正在正确地做到我所认为的,也就是获取您想要的颜色,这种颜色看起来介于您的两个输入之间,但您只需要处理这种计算是在一个环绕的圆上完成的事实。(我认为您不是真正想要“像油漆一样混合”,而只是想要中间调颜色 - 也就是说,您不希望红色和绿色混合成棕色,对吗?)
这是一个Python函数,它将选择圆上两个角度之间的角度。 它基本上只是尝试两个选项(添加360或不添加),并选择给出最接近原始角度的角度的那个选项:
pairs = [(0, 60), (60, 239), (60, 241), (0, 240), (350, 30)]

def circ_ave(a0, a1):
    r = (a0+a1)/2., ((a0+a1+360)/2.)%360 
    if min(abs(a1-r[0]), abs(a0-r[0])) < min(abs(a0-r[1]), abs(a1-r[1])):
        return r[0]
    else:
        return r[1]

for a0, a1 in pairs:
    print a0, a1, circ_ave(a0, a1)

生成:

0 60    30.0
60 239  149.5  # 60, 240 is ambiguous
60 241  330.5
0 240   300.0
350 30  10.0

我觉得应该有更简单的方法来进行这个计算,但是我没有想到。

2
这是正确的答案。原问题的问题在于,当原始值相差超过180度时,“平均值”实际上位于圆的错误一侧(或180度错误)。此处实现的解决方案是尝试avg和avg + 180d,并使用更接近的那个。 - RBarryYoung

1

对于每个颜色值 x,x < 360,它可以是 x 或者 x+360。然后你会得到4组颜色值。如果你找到最小距离的一组,那么就使用这组来插值颜色。这可能会给你正确的视觉效果。

例如:

红色 = 0° 或 360°
黄色 = 60° 或 420°
蓝色 = 240° 或 600°

红色和黄色的最小距离是60(红色0,黄色60),所以插值应该是30。
黄色和蓝色的最小距离是180(黄色60,蓝色240),所以插值应该是150。
红色和蓝色的最小距离是60(红色360,蓝色240),所以插值应该是300。


0

也许你不想听这个,但是需要将其转换为RGB,插值处理后再转回去。

编辑:刚看到“混合实际油漆的效果”

在这种情况下,你可能需要将其转换为CMY颜色空间而不是RGB。可以参考维基百科上的颜色混合


3
HLS 实际上是这种事情的 更好得多的 模型。 - RBarryYoung

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