I want to generate a rainbow of colors, with the same perceived brightness, and same perceived saturation.
In essence, I am looking for a formula that takes three parameters: getRgbColor(hue, perceived_brightness, perceived_saturation)
and returns the corresponding color, or some sort of error if no color with these constraints exists.
By "same perceived brightness" I mean: an average person seeing these colors on their average monitor would say that these colors appear to be about as bright as one particular shade of gray.
By "same perceived saturation" I mean: an average person seeing these colors on their average monitor would say that these colors appear to be equally colorful, when compared to that shade of gray.
Everyone will perceive colors a bit differently, so I am seeking an average consensus.
According to my understanding, to generate colors of the same "perceived brightness", I could use the CIELAB color space, and set the [L]uminosity. But then I do not know what values to use for a
and b
, and how to set the saturation, or the hue.
To generate colors of the same "perceived saturation", I think I could use the HSV or HSL color space, and set the [S]aturation. But in those color spaces, the "perceived brightness" does not seem to correspond to the [V]alue or [L]ightness. A shade of blue appears much darker than a shade of yellow with the same value, or the same lightness.
I am using opencv for the graphics output, and I am looking for either a way to calculate these colors in opencv, or a general formula.
Try HSLuv, a quasi-perceptually uniform model with a saturation correlate, essentially the polar coordinate version of CIELUV.
You asked:
...HSV or HSL color space, and set the [S]aturation. But in those color spaces, the "perceived brightness" does not seem to correspond to the [V]alue or [L]ightness...
HSV & HSL are not perceptually uniform color models, they are just very simplistic ways to make adjusting RGB values more intuitive. The HSL correlates of hue, saturation, and lightness are also not orthogonally independent.
Perceptual uniformity: A given change in a value creates a similar change in the associated perception.
Orthogonal independence: A given change in one axis of perception does not affect the other axes of perception.
As far as modeling the human vision system (HVS), achieving true independent uniformity is non-trivial, and essentially impossible as far as a common RGB display is concerned. Remember that color is a perception that is highly context sensitive and not an absolute measure.
A first valid question is, how perceptually uniform do you need to be? There are many models of human color perception—some are extremely complicated, as needed to fully encompass human vision characteristics.
Some models are much simpler, but then less accurate, yet still very useful for many applications. L*u*v* is an example. It's fairly simple, based around the 1976 UCS, and reasonably uniform for colors on a self illuminated display. However it does not calculate for perceptions such as the Helmholtz-Kohlrausch effect¹.
Both CIELUV and CIELAB extend past the gamut of an sRGB display, so one factor is determining the limits. HSLuv does this in a unique way, making it well suited for a color selection for web purposes.
Another color space that is gaining popularity, and is incorporated in the most recent CSS, is OKlab.
What is saturation or colorfulness or chroma? For simplicity we could say that chroma is the distance of a color from an achromatic center axis, and saturation is the chroma divided by the lightness. For the deeper dive on these terms, see this at Munsell.com
For our discussion, the correlates:
Because the HVS does not have a linear nor spectrally uniform perception of visible light, we cannot use linear math to describe a useful model of color perception.
But simply making each correlate linear to perception does not solve the problem of orthogonal independence—Even with HSLuv, if you vary hue, perceived intensity and colorfulness will change for the given lightness and saturation value. And you vary lightness, colorfulness is affected.
For HSLuv, only the saturation can be changed without affecting the lightness or hue... or can it? Hue essentially vanishes when saturation is low, and that "vanishing point" where it appears achromatic is dependent on the lightness, not to mention the spatial characteristics of the viewed stimulus².
The point I'm getting at is, even with models that are often referred to as perceptually uniform, there is still a significant amount of give and take. This has more to do with the incredibly complex human vision system.
The HVS processes achromatic luminance (lightness/darkness/brightness) separately from color (hue/chroma), and the luminance information serves different purposes versus color information.
For instance, fine details, edge detection, and higher spatial frequencies exist in the luminance channel. It is convenient to think of color as a low resolution layer overlaid on the luminance channel, and in fact this is a core tenet of image data compression as well as color appearance models.
So if luminance is lightness but not color, does that mean that luminance is not affected by hue? No, on the contrary, luminance is a measure (the luminous efficiency function) spectrally weighted per the HVS response to different wavelengths.
The vast majority of luminance is light that we would generally characterize as greenish, a much smaller percentage is what we would generally call red and a very small percentage, blue.
An implication is that a pure blue will have a much lower luminance (and therefore lower perceived lightness) than a pure green. So if you say you want something that is perceptually the same as you rotate hue, does that mean that you want the luminance to drop (or increase) the way it does in accordance with the luminous efficiency function? And do you want to consider Helmholtz-Kohlrausch and other perceptual effects?
A more complicated model is CAM16, and there are others. The amount of complexity you need depends very much on what your expected/intended final results are.
For the deeper dive, I would suggest Mark Fairchild's "Color Appearance Models", and Robert Hunt's "Reproduction of Color".
Notes
1: Helmholtz-Kohlrausch effect refers to how highly saturated colors such as red can appear brighter or more vivid than their measured luminance would predict.
2: At higher spatial frequencies, meaning smaller and thinner, the HVS has a substantially reduced sensitivity to hue and chroma.