Converting an RGBW color to a standard RGB/HSB rep

2019-02-10 03:13发布

问题:

I am building an interface for light management in a home automation system. I managed to control standard on/off and dimmable light for various providers with little problem, but now I am stuck with a problem related to RGB light.

The light I am currently using is an RGBW led strip - specifically, I am working with a low-cost RGBW light: the light is composed by four led and every led can be controlled individually.

To be more clear - I am working on some c# code that should retrieve the currently selected color and display it in the UI, and enable the user to specify a new color for the light. For setting the color and retrieving it I must use a command provider that enables me to send and receive commands via a web service.

The provider works with RGBW colors - the four component for Red, Green, Blue and White are used. To represent the current light color on my interface I would like to translate the RGBW color returned by the service to a more standard RGB/HSB scheme.

Searching the web, the only reference for color conversion that I found (excluding a c++ sample for rgb to rgbw conversion that, based on my understanding, must have some severe bug) is this article that shows a conversion from HSI to RGBW, which is the inverse of what I needed: link here

I am searching for some insight about how I can achieve this conversion (or a simple explanation of why it isn't possible). As far as I get the conversion from RGB to an RGBW is arbitrary - a single RGB value can be represented as multiple RGBW values, but the opposite conversion should be univocal. Also note that while I am using c#, feel free to refer to algorithms in other language too - language isn't the problem, the problem is that I don't know the math to do the color conversion.

回答1:

How to convert RGB to RGBW is described in item 2.1 of the following paper

http://www.mirlab.org/conference_papers/International_Conference/ICASSP%202014/papers/p1214-lee.pdf

Think of your leds as a huge pixel. Oliver's answer uses Wo = min(Ri,Gi,Bi), what is computationaly cheap and just works. This paper explains other alternatives to minimize power consumption, what is good for a home automation project. I'm also on a home automation project with OpenHAB, Arduino and RGBW leds and on the one hand paper proposed alternative would be good, on the other hand a huge LUT would just not work and convert all values on arduino eighter. I would suggest you to try correcting RGB values using not so energy eficient technics as cited in the paper:

Assuming Ri, Gi, Bi are color inputs, integers from 0 to 255, so Q = 255 and that your outputs are Wo, Ro, Go and Bo with values from 0 to 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 )

Exercise it in a spreadsheet before implementing, experiment on Wo = m, m^2 and -m^3+m^2+m, correct Wo value with the right Qw and you will be surprised that the simple solution without correction is not what one would expect and that other answers do not vary that much. Check the paper for color distortion results, I suppose that if you do not correct RGB values you will end up with some washed out colors.



回答2:

I know this is a fairly old question, but I'm looking at the RGB->RGBW algorithm and found this article which - whilst not the answer - may help?

http://web.archive.org/web/20101008153429/http://www.nouvoyance.com:80/files/pdf/Adding-a-White.pdf

In this, they suggest one conversion for RGB->RGBW is simply to create the W from min(R, G, B).

  • R -> R
  • G -> G
  • B -> B
  • W -> min(R, G, B)

The reverse of this (for your scenario) would simply be to throw away the W.

  • R -> R
  • G -> G
  • B -> B
  • W -> null