Welcome, guest | Sign In | My Account | Store | Cart

Functions for converting bwtween RGB and HSV color space.

Python, 52 lines
 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)

3 comments

Victor Lin (author) 15 years, 6 months ago  # | flag

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

Daniel Lepage 15 years, 6 months ago  # | flag

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)
Peter Law 15 years, 1 month ago  # | flag

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)