6
$\begingroup$

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 < 1 \\ (X, C, 0) &\mbox{if } 1 \leq H^\prime < 2 \\ (0, C, X) &\mbox{if } 2 \leq H^\prime < 3 \\ (0, X, C) &\mbox{if } 3 \leq H^\prime < 4 \\ (X, 0, C) &\mbox{if } 4 \leq H^\prime < 5 \\ (C, 0, X) &\mbox{if } 5 \leq H^\prime < 6 \end{cases}

Finally, we can find $R$, $G$, and $B$ by adding the same amount to each component, to match value

\begin{align} &m = V - C \\ &(R, G, B) = (R_1 + m, G_1 + m, B_1 + m) \end{align}

where $H$ is the hue, $V$ is the value, $S$ is the saturation, $C$ is what Wikipedia calls the chroma and $R, G, B$ are correspondingly the values of red, green and blue.

Before wanting to find a way to convert HSV colors to RGB Colors, I had already a formula to convert RGB colors to HSV, which I wanted to manipulate to obtain a inverse formula, but I didn't manage to do it.

Here's a picture:

enter image description here

I could show you my attempts, but they are not useful.

Question

  • How is the formula (provided by Wikipedia) to convert a HSV to RGB colors derived from the formula in the picture above to convert RGB to HSV colors?

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.

$\endgroup$
4
$\begingroup$

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$$ when $H < 300$

The variable $H'$ is equal to a value in the range

  • $[-1$ to $1)$ when the $max$ is $R$,
  • $[1$ to $3)$ when the $max$ is $G$,
  • $[3$ to $5)$ when the $max$ is $B$,

Okay, those are all of the intermediary variables we need in order to finally solve for our $R$, $G$, $B$ values.

First, we have to determine what range $H'$ is between in order to know which RGB components we are solving for in each subsequent step.

If $H'$ is in the range $[-1$ to $1)$, then we will be solving for $G$ and $B$. We know from your RGB to HSV conversion that our minimum and maximum values for $H$ are $[-60$ to $60)$ when $R$ is the largest. So, when we divide that range by $60$ to arrive at $H'$, we get the range $[-1$ to $1)$. This also means that

$$R = max$$

Recall that this range depends on the relationship between $G$ and $B$. If $G > B$, the resulting value was positive, and if $G < B$, then the resulting value was negative.

With that in mind, we need to find out the sign polarity of $H'$. There is a slight modification in the following formula that will become apparent when I explain what to do if $G$ or $B$ is the maximum value instead of $R$.

If $H' - 0 < 0$, then

$$G = min$$

and using our $H'$ formula for when $R$ is the maximum value, we can substitute in our values for $H'$, $R$, and now $G$, which will allow us to rearrange the formula and solve for $B$. We also already have a variable for $R - min$, which is the same as $max - min$, which in turn is equal to $C$.

$$H' = 0 + (G - B) / C$$

In theory we must first subtract $0$ to the other side, but since it doesn't affect anything at the moment, I'll ignore it. We first multiply out the denominator on the right hand side to get

$$H' * C = G - B$$

and then subtract $G$

$$H' * C - G = -B$$

finally we need to invert the entire equation. I will swap the right and left hand sides as well for readability

$$B = G - H' * C$$

Therefore, when $H'$ is in the range $[-1$ to $1)$ and $H' - 0 < 0$ $$R = max,$$ $$G = min,$$ $$B = G - H' * C$$


What if $H' - 0 >= 0$?

This just means that instead of $G$ being less than $B$, now it's greater than $B$.

There is a slight alteration to the formula for $G$, which isn't quite the same as it was for when $G$ was less than $B$.

Recall that

$$H' = 0 + (G - B) / C$$

But this time we know $H'$, $R$, and $B$, which means we must solve for $G$

Again, I'll ignore the 0, and multiply out the denominator from the right hand side

$$H' * C = G - B$$

and finally add $B$ to both sides to remove it from the right hand side,

$$H' * C + B = G$$

Therefore, when $H'$ is in the range $[-1$ to $1)$ and $H' - 0 >= 0$ $$R = max,$$ $$G = B + H' * C,$$ $$B = min$$


The other cases are derived in much the same way, with slight modifications.

  • if $H'$ is in the range $[1$ to $3)$, the $max$ value will be $G$
  • if $H'$ is in the range $[3$ to $5)$, the $max$ value will be $B$

Let's assume our max value is $G$. Our $H'$ equation is now

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

Since our max is now $G$, the expression $G - min$ is the same as $C$, so

$$H' = 2 + (B - R) / C$$

Remember when I said I'd make as small modification to a formula that might not make sense straight away but would come into play later? Well, it's back. To check for polarity here, we must subtract the value corresponding to which RGB value is greatest from $H'$.

So, we check for polarity by

  • $H' - 0$ when $max$ is $R$,
  • $H' - 2$ when $max$ is $G$, and
  • $H' - 4$ when $max$ is $B$

Now, we can't ignore the $2$ in our new $H'$ formula, so we'll first subtract it from both sides

$$H' - 2 = (B - R) / C$$

then multiply out the denominator

$$(H' - 2) * C = B - R$$

At this stage, if $(H' - 2) < 0$, we will be solving for $R$ since we know that in order for that sign to have been negative, $R$ must have been greater than $B$, meaning

$$B = min$$

and after subtracting $B$ to the other side and inverting the entire equation,

$$R = B - (H' - 2) * C$$

So, when $H'$ is in the range $[1$ to $3)$ and $H' - 2 < 0$ $$R = B - (H' - 2) * C,$$ $$G = max,$$ $$B = min$$

Similarly to our case from earlier, if $min$ was $R$ instead of $B$, then

$$B = R + (H' - 2) * C$$

So, when $H'$ is in the range $[1$ to $3)$ and $H' - 2 >= 0$ $$R = min,$$ $$G = max,$$ $$B = R + (H' - 2) * C$$


Similarly, with no more explanation, it should hopefully be apparent that

When $H'$ is in the range $[3$ to $5)$ and $H' - 4 < 0$ $$R = min,$$ $$G = R - (H' - 4) * C,$$ $$B = max$$

And when $H'$ is in the range $[3$ to $5)$ and $H' - 4 >= 0$ $$R = G + (H' - 4) * C,$$ $$G = min,$$ $$B = max$$


Hopefully that fully explains everything! I know it was quite a long read but I wanted to give as thorough an explanation as possible. I don't believe I missed anything, but if I did please let me know so I can amend it. Also, with a bit of rearranging, you can arrive at the formulae given on the Wikipedia page, but this post is already so long!

The formulae for everything are included below, thanks for reading!


$$max = V$$ $$C = S * V$$ $$min = max - C$$


If $H >= 300$ then $$H' = (H - 360) / 60$$ otherwise if $H < 300$ then $$H' = H / 60$$


If $H'$ is in the range $[-1$ to $1)$

  • If $H' - 0 < 0$
    • $R = max$
    • $G = min$
    • $B = G - H' * C$
  • Otherwise if $H' - 0 >= 0$
    • $R = max$
    • $G = B + H' * C$
    • $B = min$

If $H'$ is in the range $[1$ to $3)$

  • If $H' - 2 < 0$
    • $R = B - (H' - 2) * C$
    • $G = max$
    • $B = min$
  • Otherwise if $H' - 2 >= 0$
    • $R = min$
    • $G = max$
    • $B = R + (H' - 2) * C$

If $H'$ is in the range $[3$ to $5)$

  • If $H' - 4 < 0$
    • $R = min$
    • $G = R - (H' - 4) * C$
    • $B = max$
  • Otherwise if $H' - 4 >= 0$
    • $R = G + (H' - 4) * C$
    • $G = min$
    • $B = max$
$\endgroup$
1
  • $\begingroup$ Thank you for letting me know! I will try to convert it shortly $\endgroup$
    – MBearr1221
    Jul 2 '20 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy