semmixcolor and perception

HSV and HSB color models

HSV and HSB are two names for the same model. It describes a color by hue, saturation and "value", the strength of its strongest component. It is the model behind the color picker in most graphics software.

Why two names

Alvy Ray Smith described the model in 1978 as HSV: hue, saturation, value. Adobe called the third component brightness in its software, hence HSB. The formulas are identical. It should not be confused with HSL, where the third component and saturation are computed differently.

Geometry: the hexcone

Picture the RGB cube viewed along its diagonal from black to white. The projection is a hexagon with six hues at its corners: red, yellow, green, cyan, blue and magenta. HSV stacks such hexagons from the black point (V = 0) up to the full hexagon with white in its center (V = 1). The result is an inverted pyramid, often simplified to a cone.

Formulas: RGB to HSV

max = max(R, G, B), min = min(R, G, B), d = max - min V = max S = 0 if max = 0 S = d / max otherwise H = 60° · ((G - B) / d mod 6) if max = R H = 60° · ((B - R) / d + 2) if max = G H = 60° · ((R - G) / d + 4) if max = B (for d = 0 the hue is undefined; 0° is the usual convention)

R, G, B in the 0..1 range. The hue is computed exactly as in HSL; only S and the third component differ.

Formulas: HSV to RGB

C = V · S (chroma) X = C · (1 - |(H / 60°) mod 2 - 1|) m = V - C 0° ≤ H < 60° → (C, X, 0) 60° ≤ H < 120° → (X, C, 0) 120° ≤ H < 180° → (0, C, X) 180° ≤ H < 240° → (0, X, C) 240° ≤ H < 300° → (X, 0, C) 300° ≤ H < 360° → (C, 0, X) (R, G, B) = table result + m

Worked example

The same color as on the HLS page: RGB (200, 80, 40), #c85028.

R = 0.7843 G = 0.3137 B = 0.1569 max = 0.7843 min = 0.1569 d = 0.6275 V = 0.7843 S = 0.6275 / 0.7843 = 0.8 H = 60° · (0.3137 - 0.1569) / 0.6275 = 15° HSV = (15°, 80%, 78.4%)

And back:

C = 0.7843 · 0.8 = 0.6275 H / 60° = 0.25 → X = 0.6275 · (1 - |0.25 - 1|) = 0.1569 m = 0.7843 - 0.6275 = 0.1569 H in 0°..60° → (C, X, 0) + m = (0.7843, 0.3137, 0.1569) RGB = (200, 80, 40)

HSV versus HSL

Hue is the same in both models. Saturation and brightness differ, and you can convert between them without going back to RGB:

L = V · (1 - S_v / 2) S_l = 0 if L = 0 or L = 1 S_l = (V - L) / min(L, 1 - L) otherwise

For our color: L = 0.7843 · (1 - 0.4) = 0.4706, and Sl = (0.7843 - 0.4706) / 0.4706 = 0.6667. The same 80% saturation in HSV is 66.7% in HSL.

The practical difference: in HSV a pure hue has V = 1 and S = 1, and white has V = 1 and S = 0. Lowering S at constant V "washes out" the color; lowering V darkens it. In HSL white sits at the very top (L = 1) and a pure hue halfway up (L = 0.5). That is why color pickers tend to use HSV, while CSS and palette generators more often use HSL.

Neither V nor L corresponds to perceived brightness. Yellow and blue at V = 1 look completely different. To pick colors of equal brightness to the eye, use L* from CIELAB.