I am looking for color space converter from RGB to HSV, specifically for the range 0 to 255 for both color spaces.
RGB = hsv2rgb( HSV ) converts the hue, saturation, and value (HSV) values of an HSV image to red, green, and blue values of an RGB image. rgbmap = hsv2rgb( hsvmap ) converts an HSV colormap to an RGB colormap.
To convert RGB color values to HSV color values in Python, import colorsys library, call rgb_to_hsv() function, and pass the Red, Green, and Blue values as arguments. rgb_to_hsv() function takes Red, Blue, and Green values as arguments, and returns a tuple containing Hue, Saturation, and Value.
Algorithm Steps In the HSV representation of color, hue determines the color you want, saturation determines how intense the color is and value determines the lightness of the image. As can be seen in the image below, 0 on the wheel would specify a mild red color and 240 would specify a blue color.
I've used these for a long time - no idea where they came from at this point... Note that the inputs and outputs, except for the angle in degrees, are in the range of 0 to 1.0.
NOTE: this code does no real sanity checking on inputs. Proceed with caution!
typedef struct {     double r;       // a fraction between 0 and 1     double g;       // a fraction between 0 and 1     double b;       // a fraction between 0 and 1 } rgb;  typedef struct {     double h;       // angle in degrees     double s;       // a fraction between 0 and 1     double v;       // a fraction between 0 and 1 } hsv;  static hsv   rgb2hsv(rgb in); static rgb   hsv2rgb(hsv in);  hsv rgb2hsv(rgb in) {     hsv         out;     double      min, max, delta;      min = in.r < in.g ? in.r : in.g;     min = min  < in.b ? min  : in.b;      max = in.r > in.g ? in.r : in.g;     max = max  > in.b ? max  : in.b;      out.v = max;                                // v     delta = max - min;     if (delta < 0.00001)     {         out.s = 0;         out.h = 0; // undefined, maybe nan?         return out;     }     if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash         out.s = (delta / max);                  // s     } else {         // if max is 0, then r = g = b = 0                       // s = 0, h is undefined         out.s = 0.0;         out.h = NAN;                            // its now undefined         return out;     }     if( in.r >= max )                           // > is bogus, just keeps compilor happy         out.h = ( in.g - in.b ) / delta;        // between yellow & magenta     else     if( in.g >= max )         out.h = 2.0 + ( in.b - in.r ) / delta;  // between cyan & yellow     else         out.h = 4.0 + ( in.r - in.g ) / delta;  // between magenta & cyan      out.h *= 60.0;                              // degrees      if( out.h < 0.0 )         out.h += 360.0;      return out; }   rgb hsv2rgb(hsv in) {     double      hh, p, q, t, ff;     long        i;     rgb         out;      if(in.s <= 0.0) {       // < is bogus, just shuts up warnings         out.r = in.v;         out.g = in.v;         out.b = in.v;         return out;     }     hh = in.h;     if(hh >= 360.0) hh = 0.0;     hh /= 60.0;     i = (long)hh;     ff = hh - i;     p = in.v * (1.0 - in.s);     q = in.v * (1.0 - (in.s * ff));     t = in.v * (1.0 - (in.s * (1.0 - ff)));      switch(i) {     case 0:         out.r = in.v;         out.g = t;         out.b = p;         break;     case 1:         out.r = q;         out.g = in.v;         out.b = p;         break;     case 2:         out.r = p;         out.g = in.v;         out.b = t;         break;      case 3:         out.r = p;         out.g = q;         out.b = in.v;         break;     case 4:         out.r = t;         out.g = p;         out.b = in.v;         break;     case 5:     default:         out.r = in.v;         out.g = p;         out.b = q;         break;     }     return out;      } You can also try this code without floats (faster but less accurate):
typedef struct RgbColor {     unsigned char r;     unsigned char g;     unsigned char b; } RgbColor;  typedef struct HsvColor {     unsigned char h;     unsigned char s;     unsigned char v; } HsvColor;  RgbColor HsvToRgb(HsvColor hsv) {     RgbColor rgb;     unsigned char region, remainder, p, q, t;      if (hsv.s == 0)     {         rgb.r = hsv.v;         rgb.g = hsv.v;         rgb.b = hsv.v;         return rgb;     }      region = hsv.h / 43;     remainder = (hsv.h - (region * 43)) * 6;       p = (hsv.v * (255 - hsv.s)) >> 8;     q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;     t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;      switch (region)     {         case 0:             rgb.r = hsv.v; rgb.g = t; rgb.b = p;             break;         case 1:             rgb.r = q; rgb.g = hsv.v; rgb.b = p;             break;         case 2:             rgb.r = p; rgb.g = hsv.v; rgb.b = t;             break;         case 3:             rgb.r = p; rgb.g = q; rgb.b = hsv.v;             break;         case 4:             rgb.r = t; rgb.g = p; rgb.b = hsv.v;             break;         default:             rgb.r = hsv.v; rgb.g = p; rgb.b = q;             break;     }      return rgb; }  HsvColor RgbToHsv(RgbColor rgb) {     HsvColor hsv;     unsigned char rgbMin, rgbMax;      rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);     rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);      hsv.v = rgbMax;     if (hsv.v == 0)     {         hsv.h = 0;         hsv.s = 0;         return hsv;     }      hsv.s = 255 * long(rgbMax - rgbMin) / hsv.v;     if (hsv.s == 0)     {         hsv.h = 0;         return hsv;     }      if (rgbMax == rgb.r)         hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);     else if (rgbMax == rgb.g)         hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);     else         hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);      return hsv; } Note that this algorithm uses 0-255 as it's range (not 0-360) as that was requested by the author of this question.
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