我正在为家庭自动化系统中的灯光管理构建一个界面。我设法控制各种供应商的标准开/关和可调光,几乎没有问题,但现在我遇到了与RGB灯有关的问题。
我目前使用的是RGBW LED灯条 - 具体来说,我正在使用低成本的RGBW灯:灯由四个LED组成,每个LED都可以单独控制。
更清楚 - 我正在研究一些c#代码,它们应该检索当前选择的颜色并在UI中显示它,并使用户能够指定灯光的新颜色。为了设置颜色并检索它,我必须使用命令提供程序,使我能够通过Web服务发送和接收命令。
提供商使用RGBW颜色 - 使用红色,绿色,蓝色和白色四个组件。为了在我的界面上表示当前的灯光颜色,我想将服务返回的RGBW颜色转换为更标准的RGB / HSB方案。
搜索网页,我找到的唯一颜色转换参考(根据我的理解,不包括用于rgb到rgbw转换的c ++示例,必须有一些严重错误)本文显示了从HSI到RGBW的转换,这与我需要的相反:link here
我正在寻找有关如何实现此转换的一些见解(或简单解释为什么不可能)。就我而言,从RGB到RGBW的转换是任意的 - 单个RGB值可以表示为多个RGBW值,但相反的转换应该是单义的。另请注意,虽然我使用c#,也可以随意引用其他语言的算法 - 语言不是问题,问题是我不知道进行颜色转换的数学。
答案 0 :(得分:5)
如何将RGB转换为RGBW,请参阅以下文章的第2.1项
http://www.mirlab.org/conference_papers/International_Conference/ICASSP%202014/papers/p1214-lee.pdf
将您的LED视为一个巨大的像素。奥利弗的回答使用了Wo = min(Ri,Gi,Bi),什么是计算上便宜而且正常工作。本文介绍了最小化功耗的其他替代方案,这对家庭自动化项目有利。我也参与了一个有OpenHAB,Arduino和RGBW LED的家庭自动化项目,一方面提出的替代方案也不错,另一方面,一个巨大的LUT将无法工作并转换arduino eighter上的所有值。 我建议你尝试使用文章中引用的不那么节能的技术来修正RGB值:
假设Ri,Gi,Bi是颜色输入,整数从0到255,所以Q = 255,输出为Wo,Ro,Go和Bo,值为0到255:
M = max(Ri,Gi,Bi)
m = min(Ri,Gi,Bi)
Wo = if (m/M < 0.5) use ( (m*M) / (M-m) ) else M
Q = 255
K = (Wo + M) / m
Ro = floor( [ ( K * Ri ) - Wo ] / Q )
Go = floor( [ ( K * Gi ) - Wo ] / Q )
Bo = floor( [ ( K * Bi ) - Wo ] / Q )
在实施之前在电子表格中练习,在Wo = m,m ^ 2和-m ^ 3 + m ^ 2 + m上进行实验,用正确的Qw校正Wo值,你会惊讶于没有校正的简单解决方案不是人们所期望的,其他答案也没有那么大的变化。检查纸张的颜色失真结果,我想如果你不校正RGB值,你最终会得到一些褪色的颜色。
答案 1 :(得分:1)
我一直在审查罗伯托(Roberto)提出的答案,但是在许多情况下,颜色显得暗淡和不饱和。以RGB =(255,255,2)为例,得出RGBW =(128,128,1,2)。
进一步挖掘,似乎Chul Lee的论文的K方程式有误。该方程式来自Lili Wang的论文(“手机RGBW显示器的亮度和色彩之间的权衡”用法”)实际上是:
K = (Wo + M)/M
请注意,它是大写字母M,而不是小写字母m。有了此更改,您也不需要Q,因为它可以自然缩放。在相同的RGB =(255,255,2)的示例上使用新的K会导致更合理的RGBW =(255,255,0,2)。
将它们放在一起:
M = max(Ri,Gi,Bi)
m = min(Ri,Gi,Bi)
Wo = if (m/M < 0.5) use ( (m*M) / (M-m) ) else M
K = (Wo + M) / M
Ro = floor[ ( K * Ri ) - Wo ]
Go = floor[ ( K * Gi ) - Wo ]
Bo = floor[ ( K * Bi ) - Wo ]
答案 2 :(得分:0)
我知道这是一个相当古老的问题,但我正在研究RGB-&gt; RGBW算法并发现这篇文章 - 虽然不是答案 - 可能会有所帮助?
http://web.archive.org/web/20101008153429/http://www.nouvoyance.com:80/files/pdf/Adding-a-White.pdf
在这里,他们建议RGB-> RGBW的一次转换只是从min(R,G,B)创建W。
相反(对于你的场景)只是扔掉W。