是否有一种混色算法,就像混合真实颜色一样?

时间:2009-08-29 13:26:34

标签: algorithm colors language-agnostic blending color-space

RGB颜色的常见混合与绘画的混合颜色非常不同, 它是混合光而不是混合颜料。

例如:

Blue (0,0,255) + Yellow (255,255,0) = Grey (128,128,128)

(它应该是蓝色+黄色=绿色)

是否有任何已知的混色算法,就像混合真实颜色一样?


我的方法

我已经尝试过:

将两种颜色转换为HSV 并混合色调(乘以从饱和度计算的系数), 和饱和度和价值渠道的简单平均值。然后我计算了两者的平均亮度 颜色并调整结果颜色以匹配此亮度。 这很有效,但色调混合有时是错误的,例如。 G:

Red (Hue 0°) + Blue (Hue 240°) = Green (Hue 120°)

我发现有时候我需要将色调值移动360°(当两者之间存在差异时) 色调大于180°。

Red (Hue 360°) + Blue (Hue 240°) = Magenta/fuchsia (Hue 300°)

但这种转变也不是很好,例如:

Cyan (Hue 179°) + Red (Hue 0°) = Hue 89.5°
Cyan (Hue 181°) + Red (Hue 0°) --> shifting is performed (the difference is greater than 180°)
Cyan (Hue 181°) + Red (Hue 360°) = Hue 270.5°

(色调179 +红色)和(色调181 +红色)产生两种完全不同的颜色。


然后我尝试了CIE Lab色彩空间(如在Photoshop中),它旨在更接近人类感知色彩的方式。

我只对每个相应的两个频道使用了一个简单的平均值,但结果并不令人满意, 例如,我从蓝色(98,-16,93)和黄色(30,68,-112)得到粉红色(64,26,-9.5)。这些系数 取自Photoshop。

也许如果我使用一些不同于平均值的操作,它可以工作,但是 我不知道是什么。


CMYK也不起作用,结果就像RGB或LAB一样。


似乎在任何这些色彩空间中,无论是微不足道的添加剂还是减色的色彩混合都不会产生自然的效果。


工作实施

Krita - 绘画混音器

Raster图形编辑器Krita在某些方面实现了更逼真的色彩混合:http://commit-digest.org/issues/2007-08-12/(绘画混音器插件)

他们说这是第一个使用描述颜料行为的Kubelka和Munk方程实现特殊技术的公共应用程序。

以下是Krita混色的视频:https://www.youtube.com/watch?v=lyLPZDVdQiQ

FiftyThree的论文

article about color blending in the Paper app for iOS还开发了FiftyThree。他们描述了他们如何在该地区进行创新和实验,并提供混合蓝色和黄色的样品,从而产生绿色。但是,实际的过程或算法并没有在那里真正描述过。

引用:

  

“在寻找良好的混合算法时,我们最初尝试在各种颜色空间内插入:RGB,HSV和HSL,然后是CieLAB和CieLUV。结果令人失望,”Chen说。 “我们知道红色和黄色应该产生橙色,或者红色和蓝色应该产生紫色 - 但无论你使用什么颜色空间,都没有办法达到这些颜色。有一个工程公理:做最简单的事情是好吧,我们现在已经尝试了最简单的方法,他们甚至感觉不太正确。“

看起来像Krita一样,Paper实现了Kubelka-Munk模型:

  

[...] Kubelka-Munk模型每种颜色至少有六个值,包括每种RGB颜色的反射和吸收值。 “虽然屏幕上的颜色外观可以用三维描述,但颜色的混合实际上发生在六维空间中,”FiftyThree的联合创始人兼首席执行官Georg Petschnigg解释道。 Kubelka-Munk论文允许团队将美学问题转化为数学框架。 [...]

从所有这些信息来看,似乎基于Kubelka-Munk模型的实施可能是前进的方向,并提供更接近现实的结果。

即使它看起来像一个复杂的过程,我还没有看到很多关于如何实现这样的好信息。


相关问题

这些问题是在这一个问题发布之后发布的。

他们都没有真正的答案。


其他相关链接和资源

7 个答案:

答案 0 :(得分:24)

正确的答案是否定的,因为没有正确的 工作模型,“真实世界中的颜色混合”是如何运作的。这是FAR过于复杂和有条件而且根本不像我们在学校学到的简单的红蓝黄色东西(实际上需要所有的化学和大量的物理和生物学来解决)。

然而,简单的答案是:是的,使用减法混合而不是添加混合。

我们在小学阶段学到的颜色混合是基于颜料组合,这是一种减色混合的形式(非常简单)。这就是我们加在一起的颜色越多,颜色越深,因为每种颜料都会减去更多的光。

另一方面,几乎所有的计算机配色方案都是添加,因为它们基于光波的组合(非常简单),因此它们变得更亮,因为每种颜色都会增加一点点光。

RGB +方案在某种程度上是我们在大多数美国小学(RBY-)学到的减法方案的补充补充。但是,它们并不完全匹配,很难在它们之间进行转换(现在研究......)


好的,如果您只想从RGB中的添加剂组合切换到减色组合,您可以使用以下反向贝叶斯类型公式来组合两种颜色:

NewColor.R = (Color1.R * Color2.R)/255
NewColor.G = (Color1.G * Color2.G)/255
NewColor.B = (Color1.B * Color2.B)/255

调整色差(G到Y,然后回到G)的差异要困难得多......


有人指出,这会产生黑色的示例问题,从技术上讲,这对于真正的减法系统是正确的,但是,如果你想要更多的稀释/减去系统,你可以试试这个:

NewColor.R = 255 - SQRT(((255-Color1.R)^2 + (255-Color2.R)^2)/2)
NewColor.G = 255 - SQRT(((255-Color1.G)^2 + (255-Color2.G)^2)/2)
NewColor.B = 255 - SQRT(((255-Color1.B)^2 + (255-Color2.B)^2)/2)

这会产生深灰色而不是黑色。但要获得黄色或任何接近,你仍然需要修复颜色方案的极对齐问题。

答案 1 :(得分:5)

组合颜色有两种不同的可能性:

  1. additive mixing(如RGB)

  2. subtractive mixing(如CMYK)

  3. 所以在减色混色中,结果是你所期望的,但是没有蓝色,而是有青色:

    黄色+青色=绿色

    一般来说,减色混合只是从白色“带走”(过滤),而加色混合是从黑色中加起来的。 (减法的基色与加法相反:红色 - >青色;绿色 - >品红色;蓝色 - >黄色)

    因此,如果您开始使用白屏应用过滤器:

    min(白色(255,255,255),黄色(255,255,0),青色(0,255,255))=绿色(0,255,0)

答案 2 :(得分:2)

有一些代码可以在krita中以逼真的方式混合颜色:https://projects.kde.org/projects/calligra/repository/revisions/master/show/krita/plugins/extensions/painterlyframework

请注意,包含光源文件的代码是GPLv2 +。它可以从RGB转换为波长,进行合成并转换回来。

答案 3 :(得分:1)

我认为你结合色调的问题在于你是通过将两个角度加在一起并除以2来实现的。正如您所注意到的,结果通常没有任何意义。我认为你最好将角度转换为单位圆上的笛卡尔坐标,对它们求平均值,并找到结果点的角度(忽略幅度)。

答案 4 :(得分:1)

RGB颜色的减色混合的一种方法是首先将RGB颜色转换为光谱反射率曲线。转换非常简单,一旦完成,您可以对反射曲线进行真正的减法混合,然后将结果转换回RGB。还有另一个类似的问题:stackoverflow.com/questions/10254022/,其中更详细地讨论了这个过程。

答案 5 :(得分:1)

想知道RGB值的反演计算是否有效。因为它是关于减去光的,所以从技术上讲,减法部分可以通过简单的数学计算。

例如青色+黄色

青色= 0x00ffff 黄色= 0xffff00

它们的反转是0xff0000和0x0000ff,这意味着它们完全吸收了红色和蓝色光。它们的1:1混合物应该吸收一半的红色和蓝色光(因为混合物的另一半仍然可以反射一些红色和蓝色光),这与(0xff0000 + 0x00ffff)/ 2 = 0x7f007f一致。现在我们减去0xffffff的值,我们有0x80ff80,这是绿色!

答案 6 :(得分:-1)

检查此implementation是否有添加剂,减色剂和其他混合物。

功能齐全(在java中写入),因此您可以测试混合所需的任何颜色,并查看它是否符合您的需求。

正如其他回复指出的那样,蓝色 + 黄色(完全青色 + 黄色绿色关于减去CMYK的alghoritm。自己看看