How it works...

The phenomenal color spaces have been introduced because they correspond to the way humans tend to organize colors naturally. Indeed, humans prefer to describe colors with intuitive attributes, such as tints, colorfulness, and brightness. These three attributes are the basis of most phenomenal color spaces. Hue designates the dominant color; the names that we give to colors (such as green, yellow, blue, and red) correspond to the different hue values. Saturation tells us how vivid the color is; pastel colors have low saturation, while the colors of the rainbow are highly saturated. Finally, brightness is a subjective attribute that refers to the luminosity of a color. Other phenomenal color spaces use the concept of color value or color lightness as a way to characterize the relative color intensity.

These color components try to mimic the intuitive human perception of colors. In consequence, there is no standard definition for them. In the literature, you will find several different definitions and formulas for hue, saturation, and brightness. OpenCV proposes two implementations of phenomenal color spaces: the HSV and the HLS color spaces. The conversion formulas are slightly different, but they give very similar results.

The value component is probably the easiest to interpret. In the OpenCV implementation of the HSV space, it is defined as the maximum value of the three BGR components. It is a very simplistic implementation of the brightness concept. For a definition that matches the human visual system better, you should use the L channel of the L*a*b* or L*u*v* color spaces.

To compute the saturation, OpenCV uses a formula based on the minimum and maximum values of the BGR components:

The idea is that a grayscale color in which the three R, G, and B components are all equal will correspond to a perfectly desaturated color; therefore, it will have a saturation value of 0. Saturation is then a value between 0 and 1.0. For 8-bit images, saturation is rescaled to a value between 0 and 255, and when displayed as a gray-level image, brighter areas correspond to the colors that have a higher saturation. For example, from the saturation image in the previous section, it can be seen that the blue of the water is more saturated than the light blue pastel color of the sky, as expected. The different shades of gray have, by definition, a saturation value equal to zero (because in this case, all the three BGR components are equal). This can be observed on the different roofs of the castle, which are made of dark gray stone. Finally, in the saturation image, you may have noticed some white spots located at areas that correspond to very dark regions of the original image. These are a consequence of the definition of saturation used. Indeed, because saturation only measures the relative difference between the maximum and minimum BGR values, a triplet such as (1,0,0) gives a perfect saturation of 1.0, even if this color would be seen as black. Consequently, the saturation values measured at dark regions are unreliable and should not be considered.

The hue of a color is generally represented by an angle value between 0 and 360, with the red color at 0 degrees. In the case of an 8-bit image, OpenCV divides this angle by 2, to fit within the single-byte range. Therefore, each hue value corresponds to a given color tint independent of its brightness and saturation. For example, both the sky and the water have the same hue value (approximately 200 degrees (intensity, 100)), which corresponds to the blue shade; the green color of the trees in the background has a hue of around 90 degrees. It is important to note that hue is less reliable when evaluated for colors that have very low saturation.

The HSB color space is often represented by a cone, where each point inside corresponds to a particular color. The angular position corresponds to the hue of the color, the saturation is the distance from the central axis, and the brightness is given by the height. The tip of the cone corresponds to the black color for which the hue and saturation are undefined:

Interesting effects can be created by playing with the HSV values. Several color effects that can be created using photo-editing software are accomplished by this color space. For example, you may decide to modify an image by assigning a constant brightness to all the pixels of an image without changing the hue and saturation. This can be done as follows:

  // convert into HSV space 
  cv::Mat hsv; 
  cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV); 
  // split the 3 channels into 3 images 
  std::vector<cv::Mat> channels; 
  cv::split(hsv,channels); 
  // Value channel will be 255 for all pixels 
  channels[2]= 255;   
  // merge back the channels 
  cv::merge(channels,hsv); 
  // reconvert to BGR 
  cv::Mat newImage; 
  cv::cvtColor(hsv,newImage,cv::COLOR_HSV2BGR); 

This gives the following screenshot, which now looks like a drawing (see the book's graphics bundle to view this image in color):

The next section will give a few more topics you can take a look at while working on this recipe.