algorithm - 生成等亮度的纯色(用于 LED 显示)

标签 algorithm colors led

我有一些 RGB LED,我想让它们显示随机颜色。

我的第一个方法是从 0-360 中随机选择一个色调 h,创建一个 HSV 形式的颜色 (h, 1, 1),然后转换使用 the algorithm given on Wikipedia 从 HSV 到 RGB .这几乎可以满足我的要求,但不完全是。

问题是 LED 可能看起来更亮或更暗,具体取决于色调。我希望它始终显示相同的亮度,而不管色调如何。

因此,例如,蓝色在 RGB 空间中为 (0, 0, 1),而青色为 (0, 1, 1)。如果我们做出所有三个原色都同样亮的简化假设,那么青色的亮度是蓝色的两倍。

我想要的是在 RGB 空间中蓝色为 (0, 0, 1),青色为 (0, 0.5, 0.5),因此原色之和始终为 1.0。

我可以用这样的算法很容易地破解一些东西:

  • 选择一个介于 0 和 1 之间的值 x
  • 选择三个原色之一,并将其​​设置为x
  • 从剩下的两个原色中选择一个,并将其设置为 1 - x
  • 将第三个主要设置为 0。

我的问题是:有没有一种更有原则的方法来做到这一点?是否有一些颜色空间按照我想要的方式运行?

结论:@Vincent van der Weele 具有我需要规范化的重要洞察力。 @Stefan Haustein 的 luma 是表达同一事物的另一种方式,同时还为不同的初选添加了不同的权重。但是,那些特殊的权重在我的情况下不起作用。在实验上,我为 R、G 和 B 选择了 0.3、0.25 和 0.2 的权重。同样在实验上,我选择了 2.0 的 Gamma (与我最初使用的 2.8 相反)。这仍然不完美,但比以前好多了。我想这自然是乱七八糟的。

最佳答案

你是对的,黄色、青色和洋红色的组合颜色比红色、绿色和蓝色三原色更亮。您可以在 HSV 生成的色调的简单图中看到这一点(我相信 HSL 看起来是一样的):

HSV in sRGB

它们更亮,但不是两倍。那是因为眼睛对光有反应 power-law function .以强度the power of 0.43最接近您的眼睛所见;这意味着黄色、青色和品红色的亮度只有 1.35 倍。

还有一个因素需要考虑。 HSV 公式正在生成 sRGB 值,其具有 gamma correction factor大约 2.2 - 这些值与产生的光量不是线性关系。您的 LED 可能是线性的,因此它们看起来会有所不同:

HSV linearized

呸!显然,驱动 LED 的值需要在线性色彩空间中,而不是 sRGB。

为了保持恒定的亮度,幂律空间中所有颜色的总和需要保持恒定。您可以通过将幂律应用于线性 r、g、b 强度,然后在总和上缩放 r、g、b 来实现这一点。取幂律的倒数将值恢复为线性 RGB。

这是一些实际的 Python 代码和生成的图像。 r、g、b 值从线性转换为 sRGB 以生成图像文件,但为了清楚起见,我将其省略。 srgb2.from_sRGB函数是我自己根据standard sRGB linearity conversions写的.

r,g,b = colorsys.hsv_to_rgb(angle/360, 1.0, 1.0)
r,g,b = srgb2.from_sRGB([r*255,g*255,b*255])
gamma = .43
r,g,b = r**(1/gamma), g**(1/gamma), b**(1/gamma)
t = r + g + b
r = r / t
g = g / t
b = b / t
r,g,b = r**gamma, g**gamma, b**gamma

HSV normalized

没有亮点了!

关于algorithm - 生成等亮度的纯色(用于 LED 显示),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46695726/

相关文章:

algorithm - 用于差异比较的 Merkle 树,在 Cassandra 中

java - 某些 RGB 值似乎无法转换为颜色对象

javascript/jquery getImageData 图像颜色选择

raspberry-pi - 关闭树莓派的 LED

android - 没有用于通知 Android 的 LED 灯

c# - 'circular linked list builder' 的最快算法

algorithm - 自定义步长间隔的楼梯问题

algorithm - 主方法 - 分析

c# - 更改事件标签页上的字体颜色

c - 有没有办法在调用 MakeWS2811() 后修改 rpi-ws281x-go 库中 LED 的亮度?