Notes on Color #2: What's wrong with HSV / HSL ?

Palette and Color pickers

The word "palette" typically means a set of colors to choose from. In the digital world it means something similar, especially on older systems which support very small number of (e.g. 16, 256) colors.

The first "advanced" color picker I saw was propably the color picker in Microsoft software, e.g. Paint, Word etc. 

Color Picker in Microsoft Windows,
which has not changed much since Windows 3.1. 

At the time I was very excited by the colorful UI, and I had lots of fun exploring the colors. However, at that time I barely understood the numbers for red, green and blue, and by no means did I understood the other set of numbers: hue, sat and lum.

Later I came across this "ring + triangle" or "ring + rectangle" color pickers, mostly in digital painting software. 

HSV Color Picker in Krita

At that time I didn't fully understand the differences of V, B or L, neither did I understand the differences between the rectangle version and the triangle version. Anyways I found it an intuitive way of arranging colors. This UI also helped me understand the concepts of hue, staturation and brightness/value.

The Color Models

Mostly because we have 3 types of color receptors, all visible colors may be organized in a 3d space. It might not be obvious at first,  but we could get some hints when using digital colors, after all the colors are typically represented by three components: R, G and B.

The HSV and HSL models are simple conversions of the RGB model. It's supposed to be more intuitive, because hue, saturation and values are defined based on visual receptions. On the other hand, RGB is designed to be straightforword for display devices.

The HSL cylinder.
Source: Wikipedia CC BY-SA 3.0

The HSV cylinder.
Source: Wikipedia CC BY-SA 3.0

I had thought that the HSV model is the color model for digital painting. Yet over the years I did find some strange effects here and there, but I was so convinced that it was due to my immature understanding of color theories. Well, now I know that it was probably 90% true. This color model is not perfect itself, either.

The Value Makes No Sense

Here is the HSV disk at maximum value:
HSV disk with max value

In HSV the V component is defined as the max of 3 components. With this definition #ffffff and #ff0000 have the same value, which does not make any sense. 

We all know that the 3 components R, G and B loosely represents the luminous level of the 3 corresponding RGB LEDs, if we ignore the details like gamma correction, color profile etc. Therefore pure white #ffffff is the ONLY color that achieves the maximum value, which is the sum of values of #ff0000, #00ff00 and #0000ff, assuming linear value scale.

The CIELAB color space is known to have a good estimate of value. It's easier to see the unevenness, if we convert the HSV disk to grey using CIELAB (by setting a and b to 0). The center point is much brighter than other places.
L(CIELAB) channel of the HSV disk

In the HSL color model, the lightness component is defined as the mid-range of the 3 components. (I had thought it is the arithmetic mean, which is in fact the HSI model.) In this model #ffffff and #ff0000 no longer have the same value (lightness).

The HSL disk where lightness=0.5

Note that brightness/value/lightness in general reflects the overall luminous energy, while chroma in general reflects the bias of the 3 color receptors. Therefore both values cannot achieve max at the same time, which means the most "colorful" (i.e. max chroma) color cannot be the brightest.

The issue with HSL model is, the 3 primary colors, #ff0000, #00ff00 and #0000ff have the same lightness. This is not true because our eyes are not equally sensitive to light of different wavelengths.

Photopic relative brightness sensitivity of the human visual system as a function of wavelength.
Source: Wikipedia CC BY-SA 3.0

This can be verified by converting the HSL disk to grey:

L(CIELAB) channel of the HSL disk

Note that the green area appears brighter than other places. In fact it can also be observed in the grey version of the HSV disk.

Does It Matter?

So now we know that the value/brightness/lightness is off, it does not necessary represent our actual color reception. Does it matter? How?

In digital painting and image processing, it is very common to adjust images with the following operations:
  • Hue / Saturation correction
  • Color balance
  • Brightness/Contract adjustment
  • Levels adjustment
  • Curves adjustment
In fact all of them are different form of curves on different channels.

If we perform these operations based on HSV/HSL models, the lightness channel may often change unexpectedly. Some quick examples:

By offseting the hue channel, we may change #00ff00 (green) to #0000ff (blue). It appears that saturation and lightness/value are not changed, but green looks brighter than blue.

When we apply some level mapping or curves on brightness, #00ff00 and #0000ff will be considered to have same values. However since the preceived values are not the same, the mapping result would look wrong.

Other Issues

Out of all three channels, value is the most important. One evidence is that we are able to enjoy monochromatic images and videos.

Besides value, we may also observe issues on the other 2 channels:

- Uneven Hue. On the color wheels we can see some "bands" near the primary colors.
- Dependent Saturation. Saturation (instead of chroma) often depends on brightness, which could be sometimes ambiguous. For example, what is the satuarion of pure white, is it 0 or 1(max)?


It is clear now that HSV and HSL are quite flawed. The only advantage is probably that they are fast to compute. But I think they should not be used in practice.

CIELAB should perform better in many cases, but it has issues with hue, especially near blue.

CIELUV is somewhat simliar, but not commonly available in software.

Oklab is fairly new, it is claimed to perform better than CIELAB, which seems so according to some reviews.

HSY is similar to HSV and HSL. It achieves better perceptually relevant by assigning different weight on the RGB components. It is available in Krita, but I don't often see it in other software. While it is still far from perfect, I reckon it should perform good enough in digital painting and other common scenarios.

My plan is to explore more on CIELAB, Oklab and HSY.

No comments: