Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RGB values of visible spectrum

Tags:

algorithm

rgb

I need an algorithm or function to map each wavelength of visible range of spectrum to its equivalent RGB values. Is there any structural relation between the RGB System and wavelength of a light? like this image: alt text
(source: kms at www1.appstate.edu)

sorry if this was irrelevant :-]

like image 344
sorush-r Avatar asked Aug 04 '10 17:08

sorush-r


People also ask

What is the RGB color spectrum?

RGB is the color model for most computer monitors and video systems that use 24-bit color depth, which means that each pixel of each of the three colors is comprised of eight bits of data. This data is a numerical representation of the “brightness” of each color.

What is the value of visible spectrum?

Wavelengths of light range from about 400 nm at the violet end of the spectrum to 700 nm at the red end (see table). (The limits of the visible spectrum are not sharply defined but vary among individuals; there is some extended visibility for high-intensity light.)

Why do RGB values range from 0 to 255?

It really comes down to math and getting a value between 0-1. Since 255 is the maximum value, dividing by 255 expresses a 0-1 representation. Each channel (Red, Green, and Blue are each channels) is 8 bits, so they are each limited to 256, in this case 255 since 0 is included.


2 Answers

I recently found out that my spectral colors don't work properly because they were based on nonlinear and shifted data. So I did little research and data compilation and found out that most spectrum images out there are incorrect. Also, the color ranges do not match to each other, so I used from this point only linearized real spectroscopy data like this

Here is the rectified output of mine:

spectral colors

  • the first spectrum is the best rendered spectrum I found but still way off the real thing
  • the second one is linearized Spectrum of our Sun taken from Earth
  • the last one is my current color output

Below are the RGB graphs:

This is the merge of both graphs:

graph merge

Now the code:

void spectral_color(double &r,double &g,double &b,double l) // RGB <0,1> <- lambda l <400,700> [nm]     {     double t;  r=0.0; g=0.0; b=0.0;          if ((l>=400.0)&&(l<410.0)) { t=(l-400.0)/(410.0-400.0); r=    +(0.33*t)-(0.20*t*t); }     else if ((l>=410.0)&&(l<475.0)) { t=(l-410.0)/(475.0-410.0); r=0.14         -(0.13*t*t); }     else if ((l>=545.0)&&(l<595.0)) { t=(l-545.0)/(595.0-545.0); r=    +(1.98*t)-(     t*t); }     else if ((l>=595.0)&&(l<650.0)) { t=(l-595.0)/(650.0-595.0); r=0.98+(0.06*t)-(0.40*t*t); }     else if ((l>=650.0)&&(l<700.0)) { t=(l-650.0)/(700.0-650.0); r=0.65-(0.84*t)+(0.20*t*t); }          if ((l>=415.0)&&(l<475.0)) { t=(l-415.0)/(475.0-415.0); g=             +(0.80*t*t); }     else if ((l>=475.0)&&(l<590.0)) { t=(l-475.0)/(590.0-475.0); g=0.8 +(0.76*t)-(0.80*t*t); }     else if ((l>=585.0)&&(l<639.0)) { t=(l-585.0)/(639.0-585.0); g=0.84-(0.84*t)           ; }          if ((l>=400.0)&&(l<475.0)) { t=(l-400.0)/(475.0-400.0); b=    +(2.20*t)-(1.50*t*t); }     else if ((l>=475.0)&&(l<560.0)) { t=(l-475.0)/(560.0-475.0); b=0.7 -(     t)+(0.30*t*t); }     } //-------------------------------------------------------------------------- 

Where

  • l is the wavelength in [nm] usable valueas are l = < 400.0 , 700.0 >
  • r,g,b are returning color components in range < 0.0 , 1.0 >
like image 64
Spektre Avatar answered Sep 19 '22 21:09

Spektre


Partial "Approximate RGB values for Visible Wavelengths"

Credit: Dan Bruton - Color Science

Original FORTRAN code @ (http://www.physics.sfasu.edu/astro/color/spectra.html)

Will return smooth(continuous) spectrum, heavy on the red side.

w - wavelength, R, G and B - color components

Ignoring gamma and intensity simple leaves:

if w >= 380 and w < 440:     R = -(w - 440.) / (440. - 380.)     G = 0.0     B = 1.0 elif w >= 440 and w < 490:     R = 0.0     G = (w - 440.) / (490. - 440.)     B = 1.0 elif w >= 490 and w < 510:     R = 0.0     G = 1.0     B = -(w - 510.) / (510. - 490.) elif w >= 510 and w < 580:     R = (w - 510.) / (580. - 510.)     G = 1.0     B = 0.0 elif w >= 580 and w < 645:     R = 1.0     G = -(w - 645.) / (645. - 580.)     B = 0.0 elif w >= 645 and w <= 780:     R = 1.0     G = 0.0     B = 0.0 else:     R = 0.0     G = 0.0     B = 0.0 
like image 24
Andrey Avatar answered Sep 21 '22 21:09

Andrey