Question

I need to translate values from 0.0 to 1.0 to their color representations (each value is a pixel). I am making a spectrogram, so the higher the value the brightest the pixel should be (as in the below image).

How can I do this? I am working in C# but a universally applicable solution is fine too.

Example:

enter image description here

Was it helpful?

Solution

This answer should not only show you how to create a color from an single float value, but the output shall resemble the shown intensity scale pretty well.

private float LinearStep(float x, float start, float width = 0.2f)
{
    if (x < start)
        return 0f;
    else if (x > start+width)
        return 1;
    else
        return (x-start) / width;
}

private float GetRedValue(float intensity)
{
    return LinearStep(intensity, 0.2f);
}

private float GetGreenValue(float intensity)
{
    return LinearStep(intensity, 0.6f);
}

private float GetBlueValue(float intensity)
{
    return LinearStep(intensity, 0f)
    - LinearStep(intensity, 0.4f)
    + LinearStep(intensity, 0.8f);
}

private Color getColor(float intensity)
{
    return Color.FromArgb(255,
        (int)(255*GetRedValue(intensity)),
        (int)(255*GetGreenValue(intensity)),
        (int)(255*GetBlueValue(intensity))
    );
}

I did this in notepad++, so it's not tested. But you should get the idea ;-)

Of course you can use this to create a lookup table. That's entirely up to you ;-)


As I cannot put this image in the comments, here is the process how to get to this solution: figure 1

  1. Identify the "pure" colors. by this I mean the ones in the 8 colors palette where every component is either 255 or zero.
  2. Draw the dashed lines. You know the rgb values at these points.
  3. Interpolate linearly.

Step 3 is done by the LinearStep() function in the code, one call for each slope. Ascending slopes are added, descending slopes are subtracted. If you are unsure about this, try to do this with the original color map. I hope you can take it from here :-)

OTHER TIPS

What you see here is a use of pseudocolor or false color. Depending on the field of application different palettes tend to be used, the one you show looks a lot like one commonly used in thermography, but there are several others that might be more adapted to your field of use. And the construction of such a palette is a bit more sophisticated than just cycling through rgb components by the way.

Back when I worked with false color images we used lookup tables, because it was (and probably is) by far the fastest way of getting the color corresponding to an input value. The one you showed seems to have 256 different values (which is no surprise), so an array containing 256 color values would be all you need as a lookup table. Personally I'd suggest to write a small program that constructs some source code by reading pixels from a color scale you like and use that in your main program. There will probably also be ready to use source code or color scale information around, maybe the keywords thermography and pseudocolor/false color can help you in your search.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top