非线性颜色插值?

时间:2010-06-10 17:47:57

标签: c++ c algorithm

如果我有一条从0到1的直线,那么我在线上的颜色为0(255,0,0),然后在0.3我有colorB(20,160,0)然后在线上的1我有colorC(0,0,0)。我怎么能找到0.7?

的颜色

由于

5 个答案:

答案 0 :(得分:30)

答案 1 :(得分:7)

尝试将其转换为另一种颜色表示,例如HSV(见http://en.wikipedia.org/wiki/HSL_and_HSV)。

  • 颜色A的色调为0,饱和度为1,值为1。
  • 颜色C的色相为?,饱和度为?和值0。

?意味着它实际上无关紧要(因为颜色C只是黑色)。

现在也将颜色B转换为HSV(不能忘记这样做,对不起),然后为颜色C的色调和饱和度选择漂亮的值,使色调,值和饱和度在一行上HSV空间。然后从中扣除0.7的颜色。

编辑:在http://www.csgnetwork.com/csgcolorsel4.html使用RGB-HSV计算器,我计算了以下内容:

  • 颜色A:H:0,V:100,S:100
  • 颜色B:H:113,V:100,S:63

现在我们像这样计算颜色C的H和V:

  • H:113 / 0.3 = 376.6
  • V:100(因为A和B都有V或100)

这使我们的颜色为0.7:

  • H = 376.66 * 0.7 = 263.66
  • V = 100
  • S =大约30

不幸的是,这并不完全适合饱和度,但如果你以这种方式进行插值,你会得到一些非常接近你想要的东西。

答案 2 :(得分:4)

在摘要中,假设f(0.0)=(255,0,0),f(0.3)=(20,160,0)和f(f),则要求f(0.7)的值1.0)=(0,0,0)。如上所述,这没有明确定义,因为f可以是无数个函数中的任何一个。

f的一些可能选择是:

  1. RGB空间中的一系列线段
  2. 映射到HSV或HSL空间后的一系列线段
  3. RGB空间中的三次样条曲线。
  4. HSV / L空间中的三次样条。
  5. 但是应该如何定义f的具体选择应该取决于你正在做什么,或者如何为你的应用定义颜色停止。

答案 3 :(得分:3)

插入RGB的正确方法是首先校正伽玛,使颜色分量呈线性,执行插值,然后转换回来。否则,由于值是非线性的,您将得到错误。有关详细信息,请参阅http://www.4p8.com/eric.brasseur/gamma.html(尽管文章是关于缩放的,但缩放通常通过插值像素值来完成)。

如果你有sRGB值,你可以使用下面的公式在线性和非线性之间进行转换:http://en.wikipedia.org/wiki/SRGB(使用Csrgb和Clinear公式)

另一方面,错误并不大,所以如果它们很重要,则取决于您的应用程序。

对于插值本身,简单的线性插值应该足够(正如其他人已经注意到的那样)。有关具体信息,请参阅http://en.wikipedia.org/wiki/Linear_interpolation

答案 4 :(得分:0)

看起来你正试图在错误的色彩空间中进行插值。首先转换为HSV,然后你的颜色变为

RGB -> HSV
255,0,0 -> 0, 255,255
20,160,0 -> 80,255,160
0,0,0 -> 0,255,0

因此它仍然令人困惑,但至少我们可以看到V值插值为零,H值令人困惑,但在意识到HSV被建模为圆柱体后,我们可以看到它确实是只需从0到256修改256 256,所以它只会回到零。

所以你的方程将是(在HSV中)

nH = frac*256 mod 256
nS = 255
nV =  (1-frac)*255

因此,如果你用0.7代替frac,你将获得HSV坐标的正确计算,如果你需要回到RGB,你应该看看你的库是否提供了这样的功能(我知道java的Color类支持这个),但是如果不是你可以从here获取代码。它显示了如何在C中进行色彩空间转换。

祝你好运