3

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

tshepang
  • 12,111
  • 21
  • 91
  • 136
c0dehunter
  • 6,412
  • 16
  • 77
  • 139
  • You want it to look like this? f you just want red just use `red = 255*value` – Serdalis Apr 07 '13 at 21:56
  • Doesn't need to be like the example above, I would just like to convert it to a color representation - but not just *one* color (e.g. red). – c0dehunter Apr 07 '13 at 22:00
  • 1
    you can do: `R = value*255, G = 255-R, B = 0` for red and yellow and green. – Serdalis Apr 07 '13 at 22:02
  • 2
    Create an array with e.g. 100 values - one for every `0.01` from your input value (e.g. 0.45 would become colors[45]) and then change pixels to colors from that array. – MarcinJuraszek Apr 07 '13 at 22:02

2 Answers2

7

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 :-)

DasKrümelmonster
  • 5,816
  • 1
  • 24
  • 45
1

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.

fvu
  • 32,488
  • 6
  • 61
  • 79