|
 |

RGB to HSV C
code
Image processing |
|
|
An RGB to HSV converter in C |
|
Author WebMaster
Last update 2002-04-20
English |
|
|
|
|
|
- struct Color_HSV RGBtoHSV(struct
Color_RGB RGB);
struct Color_RGB HSVtoRGB(struct Color_HSV HSV);
- struct Color_RGB {
double red,blue, green; //doubles used for best accuracy
};
struct Color_HSV {
double hue, sat, val;
};
struct Color_HSV RGBtoHSV(struct Color_RGB RGB){
struct Color_HSV HSV; //structure to return
double vals[3]; //thue = temporary var (linked to hue)
unsigned char maxc=0, minc=0; //red=0, green=1, blue=2
- vals[0]=RGB.red;
vals[1]=RGB.green;
vals[2]=RGB.blue;
- //red is set as maximum
and minimum
if(vals[1]>vals[maxc]) maxc=1; //if green is greater, make green the
max.
if(vals[2]>vals[maxc]) maxc=2; //if blue is greater, make blue the max
if(vals[1]<vals[minc]) minc=1; //if green is less, make green the min.
if(vals[2]<vals[minc]) minc=2; //if blue is less, make blue the min.
- HSV.val = vals[maxc];
//set the HSV.val to the maximum component value (this is a final value)
if(vals[maxc]==0) //if maximum component is 0, color must be black
HSV.sat = HSV.hue = 0; //so set values to 0 manually to avoid div by 0 errors
else
{ //otherwise, calculate the values
HSV.sat=255*(1-(vals[minc]/vals[maxc])); //compressed equation - original:
HSV.sat=((vals[maxc]-vals[minc])/vals[maxc])*255;
HSV.hue = 60 * ((maxc*2) + (vals[(maxc+1)%3] - vals[(maxc+2)%3])/(vals[maxc]
- vals[minc])); //this cannot be simplified - and i havn't got time to explain
it
}
if(HSV.hue < 0) HSV.hue += 360; //corrector for hues in -60 to 0 range
return HSV;
}
- struct Color_RGB HSVtoRGB(struct
Color_HSV HSV)
{
struct Color_RGB RGB; //structure to return
double min,thue,vals[3]; //thue = temporary var (linked to hue)
unsigned char maxc; //red=0, green=1, blue=2
- /* The biggest component
(r,g or b) of the colour can be detemined
* by where the hue lies.
* The maximum component is eaqul to the 'value' in HSV,
* so we can set the biggest component to HSV.val,
* and also set the marker for which is the biggest component(maxc)
*
* The maximum component can be determined by where the hue lies:
* it lies in one of three groups
*
* If the maximum component is red (0), it lies in the third of the
* spectrum around red, i.e. -60 to 60
* If the maximum component is green (120), it lies in the third of the
* spectrum around green, i.e. 60 to 180
* If the maximum component is blue (240), it lies in the third of the
* spectrum around blue, i.e. 180 to 300
*/
- /* since the spectrum
is circular, we can take the 300-360 section and
* fit it into -60 -> 0, to fit help the group seperation
*/
- if(HSV.hue>300)
HSV.hue-=360;
- /* we now determine
the maximum component (maxc) by the hue groups
*/
if(HSV.hue<60) //if it is below 60, then it is red (maxc 0)
maxc=0; //The range is -60 -> 60, and there is never anything below -60
else if(HSV.hue>=180) //if it is above 180, then it is blue (maxc 2)
maxc=2; //The range is 180 -> 300, and there is never anything above
300, or it would have been modified earlier
else //otherwise, it must be between 60 and 180, which is green (maxc 1)
maxc=1; //The range is 60 -> 180
- vals[maxc]=HSV.val;
//vals holds the r, g, and b values temporarialy, so set the maximum one
to HSV.val (the value of the maximim component is HSV.val)
- /* the first of these
formulae calculates the minimum
* value. it has been "shrink-wrapped", so dont try to make sense
of it
*
* I dont understand it anymore, and i'm not sure if i even did when i wrote
it
*/
min = (HSV.val*(255-HSV.sat)) / 255;
- /* the second of these
formulae calculates a value 'thue'.
* the formaula results in a value between -1 and 1, representing
* the position of the hue in it's group
* this may help: (green "hue group" used as an example.)
*
* lwr bound ## green ## upr bound
* 60 120 180 -----> Hue
* |-----|-----|-----------|
* hue= 90
*
* lwr bound ## green ## upr bound
* -1 0 1 -----> tHue
* |-----|-----|-----------|
* hue= -0.5
*
* this part is done in the first half of the equation ((HSV.hue/60)-(2*maxc))
*
* the second part multiplies it by the difference between
* the maximum and minimum to get a value that is
* the difference between the minimum component and the middle component.
* i dont really understand why, but it works. * (HSV.val-min)
*/
- thue=(((HSV.hue/60)-(2*maxc))
* (HSV.val-min));
- if(thue>0) //if the
hue is more like the color group above it,
{ //i.e. a green that is more 'bluey' than 'reddy'
vals[(maxc+2)%3] = min; //then the minimum component is the one it is less
like, the group below
vals[(maxc+1)%3] = min+thue; //and the middle component is the one it is
more like, the group above
}
else //otherwise, it must be more like the colour group below it
{ //i.e. a green that is more 'reddy' than 'bluey'
vals[(maxc+1)%3] = min; //then the minimum component is the one it is less
like, the group above
vals[(maxc+2)%3] = min+thue; //and the middle component is the one it is
more like, the group below
}
RGB.red=vals[0]; // now stuff the aray values into the return structure
RGB.green=vals[1];
RGB.blue=vals[2];
return RGB;
}
|
|