Reputation: 31
I was wondering if anyone has any words of advice or could point me to any good resources regarding the creation of color lookup tables for image synthesis. In my application I have floating point values between -1.0 and 1.0 that need to be mapped onto RGB space. The problem is, I don't know beforehand what precision those floating point values will have, so I don't know how many entries to put in the lookup table or what they should be. Are there any commonly used techniques to deal with mapping data in this form to colors? It seems it would be too costly to create a new color table for each image based on the range of values in the domain of the image data.
I guess defining a range of values for the mapping would work, but give me your thoughts. Also if anyone knows of any existing tools (preferbly python based) for creating color lookup tables that would be helpful.
Upvotes: 3
Views: 2393
Reputation: 1935
If you need to use a lookup table and are dealing with floating point data, you'll have to quantise the float data into separate ranges, then lookup each range in your table.
However, using a lookup table seems inappropriate here; why not define a mapping function that takes your float value as input and returns the RGB value? I've used this for colouring fractals (see the 'Colouring' section in http://jk.ozlabs.org/projects/lca2008-hackfest/).
Basically, my approach is to do a simplified HSV to RSB conversion, using constant values for Saturation and Value, and the floating point input data for the Hue. This will give your values the following RGB outputs:
See http://jk.ozlabs.org/blog/post/65/hackfest08-solution-2/ for some fractals coloured using this mapping function.
I have some C code to do this, which could be easily converted to python. Note that this assumes that 0 <= i <= 1, whereas you probably want -1 <= i <= 1:
/* for a value x (which is between x_min and x_max), interpolate a y value
* (between y_min and y_max) of the same proportion.
*/
static float interpolate(float x, float x_min, float x_max,
float y_min, float y_max)
{
x = (x - x_min) / (x_max - x_min);
return x * (y_max - y_min) + y_min;
}
/*
* given a the i and i_max values from a point in our (x,y) coordinates,
* compute the colour of the pixel at that point.
*
* This function does a simplified Hue,Saturation,Value transformation to
* RGB. We take i/i_max as the Hue, and keep the saturation and value
* components fixed.
*/
void colour_map(struct pixel *pix, float i, float i_max)
{
const float saturation = 0.8;
const float value = 0.8;
float v_min, hue;
hue = i / (i_max + 1);
v_min = value * (1 - saturation);
/* create two linear curves, between value and v_min, of the
* proportion of a colour to include in the rgb output. One
* is ascending over the 60 degrees, the other descending
*/
if (hue < 0.25) {
pix->r = value * 255;
pix->g = interpolate(hue, 0.0, 0.25, v_min, value) * 255;
pix->b = v_min * 255;
} else if (hue < 0.5) {
pix->r = interpolate(hue, 0.25, 0.5, value, v_min) * 255;
pix->g = value * 255;
pix->b = v_min * 255;
} else if (hue < 0.75) {
pix->r = v_min * 255;
pix->g = value * 255;
pix->b = interpolate(hue, 0.5, 0.75, v_min, value) * 255;
} else {
pix->r = v_min * 255;
pix->g = interpolate(hue, 0.75, 1.0, value, v_min) * 255;
pix->b = value * 255;
}
pix->a = 255;
}
Upvotes: 1
Reputation: 96167
The term you are looking for is false color image.
How to pick the color bands depends on what you are trying to show. The simple way is to split the data into two halves, above and below the mid-range
For the low half you set red=0, then blue=(255 - your value), green=(your value). This will give you a color between most blue for the lowest value and green for the highest.
Then in the high range set blue=0, red=your value, green=255-(your value), this gives you a color which is red for the highest value and green for the lowest.
YOu can also change the shape of the curve to emphasize particular ranges
Upvotes: 1