Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can I use HSLuv to make a "Rainbow" hue chart? #40

Open
chrisgervang opened this issue Oct 17, 2017 · 13 comments
Open

Can I use HSLuv to make a "Rainbow" hue chart? #40

chrisgervang opened this issue Oct 17, 2017 · 13 comments

Comments

@chrisgervang
Copy link
Contributor

chrisgervang commented Oct 17, 2017

What kind of approach is necessary to convert between HSLuv and HSV? is it a linear conversion?

I'd like to build a color wheel where the user can change hue, and always get the most saturated and vibrate version of that hue.

This is different than lightness, since the "most vibrant" color have different lightnesses depending on which hue we're talking about.

There are lots of attempts to convert between the two, but I'm not sure what the correct approach would be, and I was wondering if some people in this community could share some thoughts on the subject :)

@chrisgervang
Copy link
Contributor Author

chrisgervang commented Oct 17, 2017

After playing with the code I've linked to I think these two colors should be equivalent:
hsl(hue, 100, 50) and hsv(hue, 100, 100)

If others agree that this should be true, then I don't think I need to convert anything.


For some more context, I'm trying to wrap my head around these two rainbows I made:

screen shot 2017-10-17 at 4 24 44 pm

The top one is hsluv(hue, 100, 50) and the lower one is hsl(hue, 100, 50). The whole concept of converting colors with hsluv instead of the simpler conversion the browser provides with hsl is still new to me, so I'm not sure which one is more correct for my use case.

There is another RGB concept called the "rainbow" hue chart that the FastLED library talks about.

The 'rainbow' color map provides more evenly-spaced color bands, including a band of 'yellow' which is the same width as other colors, and which has an appropriately high inherent brightness. Traditional 'spectrum' HSV color maps have much narrower bands of yellow, and the yellow can also appear muddy. - FastLED

hsv-rainbow-with-desc

I like the look of the "Rainbow" spectrum the most because it attempts to evenly spread the hues, where as my second rainbow (the standard RGB rainbow) the green is a lot wider than the teal or purple. I'm not sure if the width of a hue HSLuv is even like it is in "Rainbow", but it appears "less vivid", so I'm inclined to not use it for my use case.

So my new question is, can I use HSLuv to make a "Rainbow" hue chart?

@chrisgervang chrisgervang changed the title HSLuv to HSV? Can I use HSLuv to make a "Rainbow" hue chart? Oct 17, 2017
@kasperkamperman
Copy link

I did some experiments with HSLuv to implement it for FastLED. I didn't continue with it, because brightness is much lower in some colours (notably yellow).
If you want more even colours you also might modify the saturation of the less bright colours. I generally use a lookup table for that (Arduino doesn't have much space, but if you use a Teensy that won't be any issue).

@boronine
Copy link
Member

boronine commented Oct 18, 2017

There are separate issues here.

  1. Hue uniformity. HSL's hue is not very uniform, some color bands being wider than others. That FastLED color map appears to provide a solution to this problem and so does HSLuv. HSLuv's solution is taken directly from CIELUV, a color space based on human experiments.

  2. The definition of "lightness". HSL's definition of lightness only makes sense for one color with a fixed hue and saturation. When you make an HSL rainbow with a fixed HSL lightness, the actual lightness of the colors will vary drastically - compare yellow or cyan with blue. HSLuv takes its lightness component from CIELUV, which is defined absolutely and can actually be fixed between different colors.

If you are finding yellow to not be saturated enough, you have to add lightness. A saturated yellow must by necessity be light and a dark yellow must by necessity be unsaturated. A dark saturated yellow is an impossible color.

@chrisgervang
Copy link
Contributor Author

Thank you for the responses!

So, if I understand this correctly,

  1. HSLuv does have equal width color bands
  2. In HSL, lightness is relative to a specific hue and saturation, so if I change the hue then I'll need to change the saturation and lightness to get the version of a color I'm expecting. HSLuv lightness is normalized, so that a changing hue will result in a similarly dark or bright version of a different hue.

I wonder then what I should use to design an evenly spaced, super pleasing rainbow with my LEDs?
HSLuv, HSL (spectra), or HSL (rainbow - from FastLED), sRGB?
I'm also curious about the language people use when describing the characteristics of each generated rainbow from above.. since the problem I'm having is more of a design one than a technical one.

If I have some time this weekend, I'll experiment a bit with some LED circuits I have and record cycling through different rainbows :)

@boronine
Copy link
Member

@chrisgervang

  1. Correct
  2. Correct

I wonder then what I should use to design an evenly spaced, super pleasing rainbow with my LEDs? HSLuv, HSL (spectra), or HSL (rainbow - from FastLED), sRGB?

Choosing HSLuv, HSL and FastLED HSL. Firstly, I don't see any advantage of plain HSL over FastLED HSL, so we can drop that one. For your purpose, the choice between HSLuv and FastLED HSL I think is a matter of aesthetics. The color bands in an actual, real-world rainbow do not appear to have the same lightness, and may indeed look closer to HSL than HSLuv. Where HSLuv's lightness is really useful is in generating contrasting colors, e.g. for foreground and background.

I would be interested to know how your experiments turn out :)

@kasperkamperman
Copy link

FastLED HSV is a bit different, see: https://plus.google.com/+KasperKamperman/posts/ceLmqbpxRUG
FastLED is heavenly optimised for 8bit Arduino with small memory.

In the end it's about the effect that you like. My advise is to generate a (rainbow) lookuptable of the HSLuv (you can easy print to an array in Processing and copy-paste it) and test it with FastLed on for example a Teensy.

@MathGeniusJodie
Copy link

@chrisgervang
I would recommend this very simple method, it makes the best rainbows hands-down in my opinion
https://www.shadertoy.com/view/4l2cDm

@JobLeonard
Copy link

@chrisgervang: you might be interested in this talk:

A Better Default Colormap for Matplotlib | SciPy 2015 | Nathaniel Smith and Stéfan van der Walt

It explains color theory in a way that makes the whole idea behind CIELuv thing easy to understand, and by extension HSLuv a lot easier too.

@RoyiAvital
Copy link

Is there a version of HSLUV for HSV instead of HSL?

@chrisgervang
Copy link
Contributor Author

I think HSL is convertible to HSV. I’d refer to the conversion formula on wiki https://en.m.wikipedia.org/wiki/HSL_and_HSV#Interconversion

@RoyiAvital
Copy link

@chrisgervang , It is known for regular HSL and HSV.
But Like HSVUV is improved HSL I'm after HSVUV which is improved HSV.

@SoftMoonWebWare
Copy link

I think HSL is convertible to HSV. I’d refer to the conversion formula on wiki https://en.m.wikipedia.org/wiki/HSL_and_HSV#Interconversion

I work with a color-space I call HCG (Hue, Chroma-proportional, Gray), where Chroma is a percent proportional to the maximum chroma that can be displayed for the given hue in the RGB (e.g. sRGB) color-space used by the computer. This seems to be what you are looking for, in a way. Maximum Chroma is: one RGB channel is maximum (255 in sRGB), one channel is minimum (0), the third varies. (minimum chroma is all gray-tones)
I started working with the new OK color spaces created by Björn Ottosson, and I wrote a formula to convert OKHSL to what I call OKHCG. It failed. WHY? BECAUSE LIGHTNESS IS "NORMALIZED" in OK color spaces, just like they are in CIE Luv* based color-spaces, i.e. HSLuv. The fully-Chromatic hue is NOT at OKHSL(h,100%,50%) as it is it with HSL - it ALWAYS VARIES depending on the hue (saturation is always 100%, but lightness varies). This fact applies to both OKHSL & HSLuv.
I wrote another conversion algorithm for OKHCG from OKHSV. Works perfectly, because the fully-Chromatic tone of the hue is always HSV(h,100%,100%). It would also work for HSVuv if only I could understand how to create HSVuv, or just how to calculate (not simply track down through brute-force loops) the maximum chroma for a hue, then I could easily convert back from HCGuv to HSVuv.

So the Wikipedia link will not help anyone here, because that formula will depend on HSL having a "stable" location for "maximum chroma", but good try. I might scoop up this formula for other uses, anyway...☺

In the mean time, I'm looking for HSVᵤᵥ also.....

@boronine
Copy link
Member

boronine commented May 5, 2024

@SoftMoonWebWare I think what you call "Chroma-proportional" is same as Saturation in HSLuv. To make this possible, we need to calculate the maximum chroma for a given hue and lightness. See: https://github.com/hsluv/hsluv-python/blob/b1bfc09fb3fbf8da9d4da3b13ebd3f9795055972/hsluv.py#L80

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants