1

I've got a data set of 7 million float positive values going from 10^(-7) to 10^(0). I would like to convert the float values into RGB values in a "linear way". Until now i used [255-const*|log(float value)|]/255 and it worked, but i would like to know if is there a way to convert the values without using the logarithm and maybe (i hope so) if is there an OpenGL library that does this thing taking advance of the GPU.

EDIT1: values going from 10^(-7) to 10^(1). I would like to obtain the conversion in the fastest way because i need a quick program (that's why i would like to use the GPU).

EDIT2: isn't there an OpenGL function that scale your values by giving max and min? I've got a program with a user interface and i would like to change the "window of values" while the program is running. I would like to have something like this Computerized tomography

EDIT3: could this help me? http://glm.g-truc.net/0.9.3/api/a00157.html/

EDIT4: i would like to get something like the Jet colormap in Matlab http://blogs.mathworks.com/images/loren/73/colormapManip_14.png

nicogno
  • 47
  • 1
  • 10
  • Your values are in the interval [0.0, 1.0]. Is it enough to multiply them by 255 and round to integer? – Miguel Muñoz Jun 20 '16 at 14:53
  • Sorry, i edited my post. – nicogno Jun 20 '16 at 15:10
  • 1
    What do you mean by "linear way"? Your current formula has a log in it, do you want to get the same output with a different formula? – Karsten Koop Jun 20 '16 at 15:22
  • 1
    Your values are now in the range 0 to 10? So scale down by 10 to give values between 0 and 1 and multiply by 255 (as Miguel Muñoz states).No need to for any log/exp operation unless you are applying a gamut. – lfgtm Jun 20 '16 at 15:22
  • @KarstenKoop i mean without using the log, i would like to have the same result that you get using matlab – nicogno Jun 20 '16 at 15:25
  • @lfgtm no, my values are in the range 10^(-7) to 10^(1) – nicogno Jun 20 '16 at 15:26
  • 1
    10^(1) == 10, 10^(-7) == 0.0000001 ~= 0. – lfgtm Jun 20 '16 at 15:29
  • You're right, but the majority of my values is concentrated within the range [10^(-7), 10^(-1)] so i would like to have the maximum precision – nicogno Jun 20 '16 at 15:32
  • Also note that the eye would struggle to pick up slight variations at this precision. (True colour) 24-bit colour ( >16.7 million colours) can be represented by 3 ints, with each int value in the range (0 < colour < 255). So scaling down I would say is acceptable in this case. Unless you wanted to apply a false colour representation to emphasis these slight variations, in which case probably not best to do a straight conversion of the value into colour. – lfgtm Jun 20 '16 at 15:37
  • OpenGL is not likely to be the fastest way, you've got a round-trip through the graphics pipeline before you can get the results back. Even a modest CPU could do this quicker. – Andon M. Coleman Jun 20 '16 at 16:02

2 Answers2

2

I guess it depends on where you actually have the values. If you're generating them inside OpenGL, then you could perform the conversion in OpenGL, which would be fast, and then extract the data. If you're in CPU memory, moving the data to and from GPU memory will also take some time.

For this kind of loop, if you're compiling with optimization -O3 the compiler will normally vectorize optimize the code (see What is "vectorization"?). This should work with GCC, MSVC and other compilers. Check for the specific vectorization capabilities of your compiler.

Community
  • 1
  • 1
Miguel Muñoz
  • 326
  • 1
  • 6
1

As unsigned char is between 0 and 255 you could do:

int max = max_value_from_range;
int max = min_value_from_range;
if ( max == min ) return; // avoid to divide by 0
unsigned char out [RANGE_LEN]
for( int i = 0; i < RANGE_LEN; i++ )
    out[i] = 255 * ( FLOAT_INPUT[i] - min ) / ( max - min );
Leonardo Lanchas
  • 1,616
  • 1
  • 15
  • 37
  • Is RANGE_LEN different from dim? – nicogno Jun 20 '16 at 15:40
  • Sorry, my bad. I fix it. They are the same. – Leonardo Lanchas Jun 20 '16 at 15:42
  • Thanks a lot! So you suggest to use out[i] inside of glcolor3f, right? – nicogno Jun 20 '16 at 15:53
  • Yeah, you could do so if you want to have more control over the data. Nevertheless, if what you want to achieve is heavily based on opengl then you should see how to integrate this approach into it – Leonardo Lanchas Jun 20 '16 at 15:58
  • glColor3f takes floats in the range 0-1.0. not chars in the range 0-255. out[] is unsigned char? – lfgtm Jun 20 '16 at 16:14
  • Correct. out is unsigned char but you can set it to be float without any problem. I just set it to unsigned char thinking of the conversion. – Leonardo Lanchas Jun 20 '16 at 16:18
  • Nicolò Cogno mentioned using out[I] inside of glcolour3f, but the implicit cast would place the value above 1.0 in most cases (unless it was black, i.e the unsigned char value < 1) so anything not black will appear white? A scaling is required to get the correct colour. – lfgtm Jun 20 '16 at 16:24
  • In that case, we should only not to multiply by 255. – Leonardo Lanchas Jun 20 '16 at 16:36
  • @lfgtm your're right, i didn't write "*255" in my code. I've also edited my original post another time. – nicogno Jun 20 '16 at 16:43
  • @Leo it worked, thank you, i will accept the answer! The problem is that the values like 10^(-7) are really really small so i see that points black like the points corresponding to the 0 values and i would like to give them "more importance". It's a work of rescaling everything. Did you read my second edit? – nicogno Jun 20 '16 at 17:00
  • Thanks. Regarding the edit 2, I am afraid I do not completely understand it. What do you mean by the window of values? And when you say "scale your values by giving max and min?" you mean scaling them between max and min? – Leonardo Lanchas Jun 20 '16 at 17:07
  • This implements a linear mapping, where a value at `min_value_from_range` is mapped to `0` and `max_value_from_range` maps to `255`. Other values are mapped according to their linear relationship with the min and max range values. This is fast, but you probably want the logarithmic mapping, because differences between values will be represented in a way which is proportional to the values; so a small difference between two small values will be represented with a magnitude similar to that of a large difference between two large values. – Christopher Oicles Jun 20 '16 at 21:18
  • @Leo exactly! I mean scaling them between max and min – nicogno Jun 23 '16 at 13:31
  • @ChristopherOicles probably logarithmic mapping could be the best thing. I would like to obtain something like the graphs that you can get in Matlab – nicogno Jun 23 '16 at 13:32