HiveBrain v1.2.0
Get Started
← Back to all entries
snippetMinor

Convert HSV to RGB colors

Submitted by: @import:stackexchange-cs··
0
Viewed 0 times
convertcolorsrgbhsv

Problem

HSV colors are composed of a triple of numbers: hue $\in [0, 360)$ (in degrees), saturation $\in [0, 1]$ and value or brightness $\in [0, 1]$. RGB colors instead are more well-known and are also composed of a triple of numbers all of them in the range $[0, 1]$ or in a byte $[0, 255]$.

I was trying to implement an algorithm that converts HSV colors to the corresponding RGB ones, and I managed to do it based on the following algorithm provided by Wikipedia. (I'm reporting the whole related text).


$C = V \times S$

\begin{align}
H^\prime &= \frac{H}{60^\circ} \\
X &= C (1 - |H^\prime \;\bmod 2 - 1|)
\end{align}



($R_1$, $G_1$, $B_1$) =
\begin{cases}
(0, 0, 0) &\mbox{if } H \mbox{ is undefined} \\
(C, X, 0) &\mbox{if } 0 \leq H^\prime

I'm asking this question here because I'm looking for a mathematical manipulation of one formula to arrive at another. I'm also asking this question because I think it could be interesting also for others. If you think this question should be moved to another stackexchange's website, feel free to migrate it or just tell me and I will post it where you indicate me.

Solution

This is my first post on StackExchange! I realize it's on a fairly old post but perhaps someone else will appreciate an explanation!

I will preface this by saying that I come from a background in software development and mathematics, but I'm going to try and lay it all out, step-by-step without using coding concepts, just math.

All of the formulae will be at the bottom, in case you are uninterested in the explanation behind each.

From here on, $H$ will represent Hue, $S$ will represent saturation, and $V$ will represent value. We will also need to represent Chroma, which is the difference between max and min values of the RGB model, which will be represented by $C$.

Also, red, green, and blue will be represented by $R$, $G$, and $B$ respectively.

First we will find some intermediary values that we will need in order to derive other values. We will start with finding the max, which in the HSV model is coincidentally the value attribute itself.

$$max = V$$

Now we will find the Chroma. I'll post the formula first then show how it is derived.

$$C = S * V$$

This comes from the formula to calculate the saturation in your RGB to HSV image above, in which

$$S = (Max(R,G,B) - Min(R,G,B)) / Max(R,G,B)$$

As we just discovered, $V$ is equal to $Max(R,G,B)$, so we can replace it in the previous formula, to arrive at

$$S = (V - Min(R,G,B)) / V$$

Therefore we can find $C$ by multiplying $S$ by $V$, thus eliminating $V$ from the denominator on the right hand side.

$$C = S V = (V - Min(R,G,B)) / V V$$

Knowing $C$, we can now find $min$.

$$min = max - C$$

This comes from the formula for $C$ itself. All we need to do is rearrange the variables. We can do this two ways, but I'll keep it to the one that just uses addition and subtraction operations.

First we need to get min to the other side, which will negate it's value implicitly. We do this by adding $min$ to both sides.

$$C + min = max - min + min$$

so

$$C + min = max$$

Then we need to move $C$ to the other side, this time we will subtract it from both sides.

$$C - C + min = max - C$$

The $C$ values on the left hand side cancel out and we are left with our formula for $min$ above.

Our last variable to calculate will be $H'$, but we have to prepare it first. This explanation will be a bit long and also a little "leap-of-faithy" which I was hoping to avoid, but hopefully I can give enough detail to make the reasoning behind a later step a little more understandable.

Recall that $H$ in the RGB to HSV conversion is calculated differently depending on the max value. There are $3$ ways to calculate it. We also know that the range for $H$ is $[0$ to $360)$.

Therefore each of the $3$ equations must result in a unique range of $120$ values each, as $360 / 3 = 120$

Let's first take a look at the calculation for $H$ when $R$ is the $max$,

$$H = 60 * (0 + (G - B) / (R - min))$$

Assuming that $G$ is larger than $B$, our result will always be positive. If $R = 1$, $G = 1$, and $B = 0$, $min$ would be equal to $B$, and our formula would look like

$$H = 60 * (0 + (1 - 0) / (1 - 0))$$

which resolves to

$$H = 60$$

On the opposite side, let's assume that $B$ is larger than $G$. Now our result will always be negative. Let's use the same values from the last example, but switch the $G$ and $B$ values, so now $G = 0$ and $B = 1$. The $min$ remains $0$ as $G$ is now the smallest of the RGB values. Our new formula looks like

$$H = 60 * (0 + (0 - 1) / (1 - 0))$$

resolving to

$$H = -60$$

Notice the range of the results from these two examples?

$$range = 60 - (-60) = 120$$

So we know that these are the minimum and maximum values for $H$ when $R$ is the largest of the RGB values. Now let's take a look at just one half of the formula for when $G$ is the largest.

Recall

$$H = 2 + (B - R) / (G - min)$$

Assuming that $R$ is greater than $B$, our result will again be negative. We'll let $G = 1$, $B = 0$, and $R = 1$ (For the sake of readability and ease-of-understanding, I'm allowing $R$ to equal 1. In reality, it could only approach $1$ but never equal it exactly, as that would force $H$ to take the first formula since it would consider $R$ as the $max$ value). The $min$ value is equal to 0. Our formula will look like

$$H = 60 * (2 + (0 - 1) / (1 - 0))$$

resolving to

$$H = 60$$

We already know that this must be the smallest value for $H$ when $G$ is the largest RGB value, and you can check for when $B$ is the largest if you like, but this means that the only negative values we can have for $H$ are in the range $[-60$ to $0)$. This also indicates that the range of values to multiply by $60$ when solving for $H$ must be in the range $[-1$ to $5)$. The range has $6$ values $5 - (-1) = 6$, so $60 * 6 = 360$.

Okay, that was a whole load of information just to say that we need to convert $H$ back into this "pre-scaled" range of $[-1$ to $5)$, that will be called $H'$. This is done simply enough by
$$H' = (H - 360) / 60$$ when $H >= 300$, and
$$H' = H / 60$$ wh

Context

StackExchange Computer Science Q#64549, answer score: 9

Revisions (0)

No revisions yet.