Anyone know of a good python algorithm for converting HSV color to RGB (and vice versa) that doesn't depend on any external modules? I'm working on some animation generation code and want to support the HSV colorspace, but it's running on a Raspberry Pi and I'm trying to avoid any floating point.
This site here takes you through the steps, including how to do it using integer division. Here is a python port of the RGB to HSV function described in there
def RGB_2_HSV(RGB):
''' Converts an integer RGB tuple (value range from 0 to 255) to an HSV tuple '''
# Unpack the tuple for readability
R, G, B = RGB
# Compute the H value by finding the maximum of the RGB values
RGB_Max = max(RGB)
RGB_Min = min(RGB)
# Compute the value
V = RGB_Max;
if V == 0:
H = S = 0
return (H,S,V)
# Compute the saturation value
S = 255 * (RGB_Max - RGB_Min) // V
if S == 0:
H = 0
return (H, S, V)
# Compute the Hue
if RGB_Max == R:
H = 0 + 43*(G - B)//(RGB_Max - RGB_Min)
elif RGB_Max == G:
H = 85 + 43*(B - R)//(RGB_Max - RGB_Min)
else: # RGB_MAX == B
H = 171 + 43*(R - G)//(RGB_Max - RGB_Min)
return (H, S, V)
Which gives correct results when compared to the colorsys functions
import colorsys
RGB = (127, 127, 127)
Converted_2_HSV = RGB_2_HSV(RGB)
Verify_RGB_2_HSV = colorsys.rgb_to_hsv(RGB[0], RGB[1], RGB[2])
print Converted_2_HSV
>>> (0, 0, 127)
print Verify_RGB_2_HSV # multiplied by 255 to bring it into the same scale
>>> (0.0, 0.0, 127.5)
And you can check that the output is still in fact an integer
type(Converted_2_HSV[0])
>>> <type 'int'>
Now for the reverse function. The original source can be found here, and here is the Python port.
def HSV_2_RGB(HSV):
''' Converts an integer HSV tuple (value range from 0 to 255) to an RGB tuple '''
# Unpack the HSV tuple for readability
H, S, V = HSV
# Check if the color is Grayscale
if S == 0:
R = V
G = V
B = V
return (R, G, B)
# Make hue 0-5
region = H // 43;
# Find remainder part, make it from 0-255
remainder = (H - (region * 43)) * 6;
# Calculate temp vars, doing integer multiplication
P = (V * (255 - S)) >> 8;
Q = (V * (255 - ((S * remainder) >> 8))) >> 8;
T = (V * (255 - ((S * (255 - remainder)) >> 8))) >> 8;
# Assign temp vars based on color cone region
if region == 0:
R = V
G = T
B = P
elif region == 1:
R = Q;
G = V;
B = P;
elif region == 2:
R = P;
G = V;
B = T;
elif region == 3:
R = P;
G = Q;
B = V;
elif region == 4:
R = T;
G = P;
B = V;
else:
R = V;
G = P;
B = Q;
return (R, G, B)
And we can verify the result in the same way as before
interger_HSV = (127, 127, 127)
Converted_2_RGB = HSV_2_RGB(interger_HSV)
Verify_HSV_2_RGB = colorsys.hsv_to_rgb(0.5, 0.5, 0.5)
print Converted_2_RGB
>>> (63, 127, 124)
print type(Converted_2_RGB[0])
>>> <type 'int'>
print Verify_HSV_2_RGB # multiplied these by 255 so they are on the same scale
>>> (63.75, 127.5, 127.5)
The integer arithmetic does introduce some errors, however depending on the application these might be ok.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With