Hue range tester -doesn't work....

I’m trying to write a method that will return the range of hues in an image…so for a picture with lots of different colours it should return a high value, and for one with only one colour, for example, a low value.

This will run…but doesn’t work. An all blue jpeg returned a value of 1.6, whereas another photograph-type image returned a value of about 0.2…

  
float hrange::huerange(ofImage* img)  
{  
  float totalred=0;  
  float totalgreen=0;  
  float totalblue=0;  
  
  unsigned char* pixels;  
  pixels = img->getPixels();  
  int totalpixels = img->getWidth() * img->getHeight();  
  
  for(int i=0; i<totalpixels; i+=3)  
  {  
    totalred+= pixels[i];  
    totalgreen+= pixels[i+1];  
    totalblue+= pixels[i+2];  
  }  
    float avgred= totalred/totalpixels;  
    float avggreen= totalgreen/totalpixels;  
    float avgblue= totalblue/totalpixels;  
    float rdifference=0;  
    float gdifference=0;  
    float bdifference=0;  
  for(int i=0; i<totalpixels; i+=3)  
  {  
     rdifference+= abs(pixels[i]- avgred);  
     gdifference+= abs(pixels[i+1]- avggreen);  
     bdifference+= abs(pixels[i+2]- avgblue);  
  }  
    return (rdifference+gdifference+bdifference)/(50*totalpixels);  
  
}  

If anyone has any clues, let me know…thanks.

actually, all that your algorithm is doing is calculating how far away from ‘grey’ your image is.

you need to first convert rgb to hsv, then you can do something interesting with the hues… actually i think what you’re trying to do is to find the standard deviation of hue values, which should tell you how ‘hueful’ your image is.

but you might need to weight the hue values based on their saturation, depending on what you’re actually looking for. our eyes and brains process images in a very, very different way to the way they are represented in computers. be aware that most photographs are very desaturated, even when our brain thinks they’re colourful.

I’ve used this same algorithm in a Processing program and it returns sensible values for images based on the colour range… there’s something about how I’ve translated it into OF (incorrectly, it seems).

By my calculations for a picture of all r=0, g=0, b=255… this algorithm should return a value very close to zero, even though it is far from grey. Because average red = 0, so red difference =0. for every pixel… same with green. Average blue is 255, but blue difference is zero for every pixel…

So rdifference + bdifference + gdifference should be close to zero too…

The problem with using hue is that very high and very low hue angles are actually almost the same colour… so an image composed of these colours would return a very high standard deviation, but would actually appear to be all very similar colours.

hmm… well, if it works in processing…

on closer inspection: perhaps try using fabs() instead of abs()? abs() works on integers, fabs() works on floats.

I was actually using my own abs function:

float hrange::abs(float num)
{ return (num >= 0) ? num : -num;}

But I’ll try the one you suggested, thanks.