3
$\begingroup$

Red, Green and Blue apparently contribute differently to the luminosity perceived by humans:

https://en.wikipedia.org/wiki/Relative_luminance

I am trying to find an algorithm to map unsigned 16 bit integers into RGB values such that the relative luminance of the RGB values to which the integers map respects their order (with integer 0 being black, integer 2^16-1 white and all other integers mapped to some RGB color).

I don't really care about how the colors evolve as one walks up from 0 to 2^16-1 as long as luminosity always increases and a reasonably large swathe of the RGB space is used.

Apparently I am missing the right words to describe what I am trying to accomplish as I've failed to google anything pertinent. A couple of weeks ago I had stumbled upon a paper that described such an algorithm in the form of a helix that is arranged diagonally in the three dimensional RGB space such that when one starts at the base of the helix and works his way towards the other end, luminosity always increases and a large variety of color is used. Alas, I can't find it any more.

update

Found the algorithm I was looking for. It is known as the 'cubehelix' color scheme by Dave Green and is described here: http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/. The original paper is here: http://astron-soc.in/bulletin/11June/289392011.pdf

$\endgroup$
1
  • 1
    $\begingroup$ There are infinitely many solutions to your problem, you may want to impose extra constraints. $\endgroup$
    – lightxbulb
    Sep 5, 2019 at 15:01

1 Answer 1

3
$\begingroup$

Since you want monotonically increasing luminance, it's probably best to work in a color space that separates luma from chroma, such as a Y'UV space. You can assign values in Y'UV and then convert it to RGB using the matrix at that link.

Start by setting $Y' = N / (2^{16} - 1)$, where N is your input 16-bit integer. Now you just need to make up some function to use for the U and V components.

It wasn't clear to me if you want the chroma part of the color to vary continuously with the input N, or be pseudo-random. For a continuous curve, you could just have it be a circle in UV space: $$ U = 0.5 \cos(2\pi N/2^{16}) \\ V = 0.5 \sin(2\pi N/2^{16}) $$ or whatever other curve you feel like coming up with. For a pseudo-random chroma, you could use a hash function, or a Halton sequence or another low-discrepancy sequence.

$\endgroup$
1
  • 1
    $\begingroup$ The above, together with a modified version of the YUV to RGB formula found here: fourcc.org/fccyvrgb.php (which seems to assume that Y, U and V are in the 0-255 range so I had to scale the numbers your answer produces) produced an acceptable result. $\endgroup$ Sep 5, 2019 at 19:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.