Skip to main content

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)?

Alternatives

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.

Comments

Popular posts from this blog

Determine Perspective Lines With Off-page Vanishing Point

In perspective drawing, a vanishing point represents a group of parallel lines, in other words, a direction. For any point on the paper, if we want a line towards the same direction (in the 3d space), we simply draw a line through it and the vanishing point. But sometimes the vanishing point is too far away, such that it is outside the paper/canvas. In this example, we have a point P and two perspective lines L1 and L2. The vanishing point VP is naturally the intersection of L1 and L2. The task is to draw a line through P and VP, without having VP on the paper. I am aware of a few traditional solutions: 1. Use extra pieces of paper such that we can extend L1 and L2 until we see VP. 2. Draw everything in a smaller scale, such that we can see both P and VP on the paper. Draw the line and scale everything back. 3. Draw a perspective grid using the Brewer Method. #1 and #2 might be quite practical. #3 may not guarantee a solution, unless we can measure distances/p...

Chasing an IO Phantom

My home server has been weird since months ago, it just becomes unresponsive occassionally. It is annoying but it happens only rarely, so normally I'd just wait or reboot it. But weeks ago I decided to get to the bottom of it. What's Wrong My system set up is: Root: SSD, LUKS + LVM + Ext4 Data: HDD, LUKS + ZFS 16GB RAM + 1GB swap Rootless dockerd The system may become unresponsive, when the IO on HDD  is persistantly high for a while. Also: Often kswapd0 has high CPU High IO on root fs (SSD) From dockerd and some containers RAM usage is high, swap usage is low It is very strange that IO on HDD can affect SSD. Note that when this happens, even stopping the IO on HDD does not always help. Usually restarting dockerd does not help, but rebooting helps. Investigation: Swap An obvious potential root cause is the swap. High CPU on kswapd0 usually means the free memory is low and the kernel is busy exchanging data between disk and swap. However, I tried the following steps, none of the...

Fix Google Security Code

Google Security Code (http://g.co/sc) is one type of 2-step verification. This is particularly useful when security keys and passkeys are not available. I have been using it in my LXC containers, until today I found out that it stopped working. It just kept saying "The code is invalid". It is easy to rule out some factors: The code works on other browsers on my laptop. The code works on other devices that are directly connected to the router. So it appears that Google also checks IP addresses besides the security code. Recently I have IPv6 enabled, so most devices that are directly connected to the router have both IPv4 and IPv6 addresses. But  I only enabled IPv4 for my LXC containers. So I guess when a code is generated by device A and used by device B, Google should be able to check that device A and device B are closely located. But in my case, IPv6 address appears on device A but not on device B, which may look suspicious. To fix the problem, I just needed to disable IPv...