ActiveState Code

Recipe 576554: Covert color space from HSV to RGB and RGB to HSV


Functions for converting bwtween RGB and HSV color space.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def hsvToRGB(h, s, v):
    """Convert HSV color space to RGB color space
    
    @param h: Hue
    @param s: Saturation
    @param v: Value
    return (r, g, b)  
    """
    import math
    hi = math.floor(h / 60.0) % 6
    f =  (h / 60.0) - math.floor(h / 60.0)
    p = v * (1.0 - s)
    q = v * (1.0 - (f*s))
    t = v * (1.0 - ((1.0 - f) * s))
    return {
        0: (v, t, p),
        1: (q, v, p),
        2: (p, v, t),
        3: (p, q, v),
        4: (t, p, v),
        5: (v, p, q),
    }[hi]

def rgbToHSV(r, g, b):
    """Convert RGB color space to HSV color space
    
    @param r: Red
    @param g: Green
    @param b: Blue
    return (h, s, v)  
    """
    maxc = max(r, g, b)
    minc = min(r, g, b)
    colorMap = {
        id(r): 'r',
        id(g): 'g',
        id(b): 'b'
    }
    if colorMap[id(maxc)] == colorMap[id(minc)]:
        h = 0
    elif colorMap[id(maxc)] == 'r':
        h = 60.0 * ((g - b) / (maxc - minc)) % 360.0
    elif colorMap[id(maxc)] == 'g':
        h = 60.0 * ((b - r) / (maxc - minc)) + 120.0
    elif colorMap[id(maxc)] == 'b':
        h = 60.0 * ((r - g) / (maxc - minc)) + 240.0
    v = maxc
    if maxc == 0.0:
        s = 0.0
    else:
        s = 1.0 - (minc / maxc)
    return (h, s, v)

Comments

  1. 1. At 2:13 a.m. on 4 nov 2008, Victor Lin (the author) said:

    I implement these functions by referencing to http://en.wikipedia.org/wiki/HSI_color_space

  2. 2. At 10:31 a.m. on 4 nov 2008, Daniel Lepage said:

    Do these differ from the functions in the colorsys module? http://www.python.org/doc/2.6/library/colorsys.html

    >>> import colorsys
    >>> colorsys.hsv_to_rgb(.5,1,1)
    (0.0, 1.0, 1)
    >>> colorsys.rgb_to_hsv(.5,.5,0)
    (0.16666666666666666, 1.0, 0.5)
    
  3. 3. At 8:34 p.m. on 9 mar 2009, Peter Law said:

    Useful scripts, especially if you're still using python 2.5..

    However the rgbToHSV conversion has a bug:

    The integer nature of the calculations of h inside the brackets mean that only multiples of 60 are shown for h. This problem also affects the calculation of s.

    This can be overcome by changing the divisions such that one of the numbers is already a float (you can then remove the decimals on the 120.0, 240.0 and 360.0 within h). One possible method, including the tidyup, would make the code read as below:

    if colorMap[id(maxc)] == colorMap[id(minc)]:
        h = 0
    elif colorMap[id(maxc)] == 'r':
        h = ((g - b) * 60.0 / (maxc - minc)) % 360
    elif colorMap[id(maxc)] == 'g':
        h = ((b - r) * 60.0 / (maxc - minc)) + 120
    elif colorMap[id(maxc)] == 'b':
        h = ((r - g) * 60.0 / (maxc - minc)) + 240
    v = maxc
    if maxc == 0.0:
        s = 0.0
    else:
        s = 1 - (minc * 1.0 / maxc)
    

Sign in to comment