HSV/HSL Color Spaces
Intuitive color representations based on Hue, Saturation, and Value/Lightness.
Overview
HSV (Hue, Saturation, Value) and HSL (Hue, Saturation, Lightness) are cylindrical color models designed to be more intuitive than RGB for human color selection. They're commonly used in color pickers and image editing software.
Key Difference:
- HSV: Value represents brightness (pure colors at V=1)
- HSL: Lightness represents perceptual brightness (pure colors at L=0.5)
RGB to HSV Conversion
Algorithm
$$ V = \max(R, G, B) $$
$$ C = V - \min(R, G, B) $$
$$ S = \begin{cases} 0 & \text{if } V = 0 \ \frac{C}{V} & \text{otherwise} \end{cases} $$
$$ H' = \begin{cases} \text{undefined} & \text{if } C = 0 \ \frac{G - B}{C} \mod 6 & \text{if } V = R \ \frac{B - R}{C} + 2 & \text{if } V = G \ \frac{R - G}{C} + 4 & \text{if } V = B \end{cases} $$
$$ H = 60° \times H' $$
HSV to RGB Conversion
Algorithm
$$ C = V \times S $$
$$ H' = \frac{H}{60°} $$
$$ X = C \times (1 - |H' \mod 2 - 1|) $$
$$ (R_1, G_1, B_1) = \begin{cases} (C, X, 0) & \text{if } 0 \leq H' < 1 \ (X, C, 0) & \text{if } 1 \leq H' < 2 \ (0, C, X) & \text{if } 2 \leq H' < 3 \ (0, X, C) & \text{if } 3 \leq H' < 4 \ (X, 0, C) & \text{if } 4 \leq H' < 5 \ (C, 0, X) & \text{if } 5 \leq H' < 6 \end{cases} $$
$$ m = V - C $$
$$ (R, G, B) = (R_1 + m, G_1 + m, B_1 + m) $$
Practical Implementation
Python
1import numpy as np
2
3def rgb_to_hsv(r, g, b):
4 """
5 Convert RGB to HSV
6 Input: r, g, b in [0, 1]
7 Output: h in [0, 360), s, v in [0, 1]
8 """
9 v = max(r, g, b)
10 c = v - min(r, g, b)
11
12 if c == 0:
13 h = 0
14 elif v == r:
15 h = 60 * (((g - b) / c) % 6)
16 elif v == g:
17 h = 60 * ((b - r) / c + 2)
18 else: # v == b
19 h = 60 * ((r - g) / c + 4)
20
21 s = 0 if v == 0 else c / v
22
23 return h, s, v
24
25def hsv_to_rgb(h, s, v):
26 """
27 Convert HSV to RGB
28 Input: h in [0, 360), s, v in [0, 1]
29 Output: r, g, b in [0, 1]
30 """
31 c = v * s
32 h_prime = h / 60.0
33 x = c * (1 - abs(h_prime % 2 - 1))
34
35 if h_prime < 1:
36 r1, g1, b1 = c, x, 0
37 elif h_prime < 2:
38 r1, g1, b1 = x, c, 0
39 elif h_prime < 3:
40 r1, g1, b1 = 0, c, x
41 elif h_prime < 4:
42 r1, g1, b1 = 0, x, c
43 elif h_prime < 5:
44 r1, g1, b1 = x, 0, c
45 else:
46 r1, g1, b1 = c, 0, x
47
48 m = v - c
49 return r1 + m, g1 + m, b1 + m
Go
1package color
2
3import "math"
4
5type HSV struct {
6 H, S, V float64 // H in [0, 360), S, V in [0, 1]
7}
8
9func RGBToHSV(rgb RGB) HSV {
10 max := math.Max(math.Max(rgb.R, rgb.G), rgb.B)
11 min := math.Min(math.Min(rgb.R, rgb.G), rgb.B)
12 c := max - min
13
14 var h float64
15 if c == 0 {
16 h = 0
17 } else if max == rgb.R {
18 h = 60 * math.Mod((rgb.G-rgb.B)/c, 6)
19 } else if max == rgb.G {
20 h = 60 * ((rgb.B-rgb.R)/c + 2)
21 } else {
22 h = 60 * ((rgb.R-rgb.G)/c + 4)
23 }
24
25 if h < 0 {
26 h += 360
27 }
28
29 var s float64
30 if max == 0 {
31 s = 0
32 } else {
33 s = c / max
34 }
35
36 return HSV{H: h, S: s, V: max}
37}
38
39func HSVToRGB(hsv HSV) RGB {
40 c := hsv.V * hsv.S
41 hPrime := hsv.H / 60.0
42 x := c * (1 - math.Abs(math.Mod(hPrime, 2)-1))
43
44 var r1, g1, b1 float64
45 switch {
46 case hPrime < 1:
47 r1, g1, b1 = c, x, 0
48 case hPrime < 2:
49 r1, g1, b1 = x, c, 0
50 case hPrime < 3:
51 r1, g1, b1 = 0, c, x
52 case hPrime < 4:
53 r1, g1, b1 = 0, x, c
54 case hPrime < 5:
55 r1, g1, b1 = x, 0, c
56 default:
57 r1, g1, b1 = c, 0, x
58 }
59
60 m := hsv.V - c
61 return RGB{R: r1 + m, G: g1 + m, B: b1 + m}
62}
RGB to HSL Conversion
Algorithm
$$ L = \frac{\max(R, G, B) + \min(R, G, B)}{2} $$
$$ C = \max(R, G, B) - \min(R, G, B) $$
$$ S = \begin{cases} 0 & \text{if } C = 0 \ \frac{C}{1 - |2L - 1|} & \text{otherwise} \end{cases} $$
Hue $H$ is calculated the same way as in HSV.
HSL to RGB Conversion
$$ C = (1 - |2L - 1|) \times S $$
$$ X = C \times (1 - |H' \mod 2 - 1|) $$
$$ m = L - \frac{C}{2} $$
Then use the same $(R_1, G_1, B_1)$ table as HSV, and:
$$ (R, G, B) = (R_1 + m, G_1 + m, B_1 + m) $$
Common Use Cases
HSV
- Color pickers: Natural for users to select colors
- Image adjustments: Brightness and saturation controls
- Computer vision: Color-based segmentation
HSL
- Web design: CSS
hsl()function - Lightness adjustments: More perceptually uniform than HSV
- Color schemes: Easier to create harmonious palettes
Key Differences
| Aspect | HSV | HSL |
|---|---|---|
| Pure colors | V = 1, S = 1 | L = 0.5, S = 1 |
| White | V = 1, S = 0 | L = 1, any S |
| Black | V = 0, any S | L = 0, any S |
| Perceptual uniformity | Poor | Slightly better |
| Common use | Color pickers, graphics | Web, design |
Important Notes
- Not perceptually uniform: Equal changes in HSV/HSL don't correspond to equal perceived changes
- Hue is circular: 0° and 360° are the same (red)
- Undefined hue: When S = 0 (grayscale), hue is undefined
- Use LAB for color math: HSV/HSL are for UI, not color science
Hue Values Reference
- 0° / 360°: Red
- 60°: Yellow
- 120°: Green
- 180°: Cyan
- 240°: Blue
- 300°: Magenta
Further Reading
Related Snippets
- CIE LAB Color Space
Perceptually uniform color space for color difference calculations - CIE XYZ Color Space
Device-independent color representation based on human vision - Color Difference Formulas
Delta E and perceptual color distance calculations - Color Space Conversions - Quick Reference
Quick reference for all color space conversion formulas - RGB Color Space & Gamma Correction
sRGB color model and gamma encoding/decoding formulas - Standard Illuminants & Chromatic Adaptation
Reference white points, color temperature, and chromatic adaptation transforms