How to Generate False Color Palette

How to convert grayscale intensity input to something like the following image?

It seems that no response (0, black) is converted to dark blue, then it goes through other colors to red.

How are these colors derived? Is there any standard gray-to-RGB conversion function for these?

I have tried representing intensity as hue in CIE-LCH model and then converting to RGB through CIE-Lab. But the result weren't as nice as these MRI and PET scans.

Another approach may be a rainbow, i.e. going from high frequency (violet-blue) to lower frequencies (dark red). But is there a conversion formula for this?

• You shouldn't. :) There's a good reason why MRIs are usually displayed in grayscale: 1 2 3 4 – endolith Oct 16 '12 at 0:40
• @endolith Thanks for informative articles. Seems that grayscale is simple and better choice because of possible B/W print. Maybe increasing gray values exponentially instead of linearly would be more perceptually distinguishable as human vision perceives intensity this way. As for the color, I will stick wit CIE-Lab instead of rainbow color map. – Libor Oct 16 '12 at 10:55
• @Libor: I agree with endolith; it seems that grayscale is typically used for medical imagery. The color map that you showed is often used when visualizing two-dimensional spectral data, such as in a spectrogram. – Jason R Oct 16 '12 at 13:37
• @JasonR: jet is a diverging colormap, which are meant to show deviations positive and negative from a central value. Even when used for bipolar data, though, it's a bad choice because the brightest points in the colormap are arbitrary. Yellow and green regions look highlighted even though they're unimportant. There are lots of other colormaps that can be used for sequential data (spectrograms, medical images) or bipolar data (average rainfall relative to last year). The only reason people use jet is because it's the default. – endolith Oct 16 '12 at 16:04
• The medical image was just an example - I would like to use color map for showing differences between photographs and responses of some filters. – Libor Oct 16 '12 at 16:30

What you're looking for is a color map. As its name implies, this process maps an input (single-component, or grayscale) value within a predetermined range to some other color based upon some mapping. The implementations I've seen typically use linear RGB interpolation between a number of control points specified throughout the allowed input range. The color map used in the image you showed is a pretty common one, starting with dark blue, then through cyan, green, yellow, orange, and ending with red. It is referred to as the jet colormap in MATLAB.

So, as an example, for an input intensity on the range $[0,1]$, you might have an RGB lookup table of:

0.0  -> (0, 0, 128)    (dark blue)
0.25 -> (0, 255, 0)    (green)
0.5  -> (255, 255, 0)  (yellow)
0.75 -> (255, 128, 0)  (orange)
1.0  -> (255, 0, 0)    (red)


Then, if you wanted to map the value $0.2$ to a color, then you would linearly interpolate between the first two datapoints as follows:

color = 1 / 5 * (0, 0, 128) / 0.25 + 4 / 5 * (0, 255, 0)
= (0, 204, 26)


which would yield a greenish cyan, as it's close to the green control point.

• To allow further optimization, one might display these control points on a color chart, and allow the graphic designer or expert user to move them around to optimize the result of the color mapping. – hotpaw2 Oct 15 '12 at 19:35

http://blog.visual.ly/building-effective-color-scales/

lots of color palettes:

http://docs.idldev.com/mglib/vis/color/cptcity_catalog.html

A possibility is to map the grayscale range linearly to 0-360° (possibly with a shift), and transform from HLS to RGB, with maximum lightness and saturation.

• How does this work? Intensity 0 is color blue and intensity 1 is again blue (360 degree shift). – Deepak Sharma Jan 22 at 18:24

Class to translate the example shown between [0, 1 ]

//Color Gradient [0, 1] => Result (R, G, B) R, G, B [0, 1]
void GradientCor::set_value (double y, int y_min, int y_max)
{
/*
y = mx+b
x -> y
-0 -> -80
1 -> 120
m = dy/dx= 120 - (-80) = 200; b = y + mx = -80; x = (y-b)/m
*/
valor = (y-y_min)/(y_max - y_min);
}
/*
0.0  -> (0, 0, 128)    (dark blue)
0.25 -> (0, 255, 0)    (green)
0.5  -> (255, 255, 0)  (yellow)
0.75 -> (255, 128, 0)  (orange)
1.0  -> (255, 0, 0)    (red)
x -> y para (dark blue)
0 -> 128
0.25 -> 0
m = dy/dx= 1020; b = y + mx = 128; y = mx+b
result = y/255
*/
{
if (valor <= 0.25)
return 0;
else if (valor <= 0.5)
return(double)(1020*valor - 255)/255;
else return 1;
}

{
if (valor <= 0.25)
return(double)(1020*valor)/255;
else if (valor <= 0.5)
return 1;
else
return(double)(-510*valor + 510)/255;
}