I have a given image img (16 bits gray-level image whose values range from 0 to 65535) and a colormap colormap_file which is a 8 bits RGB 256*256 pixels image.
Thus, thanks to such a colormap I am able, for all pixels in the valueImage, to assign a (R, G, B) triplet.
Currently, it is done in pure Python through this function:
def transcodeThroughColormap(img, colormap_file):
colormap = np.array(Image.open(colormap_file))
flat_colormap = colormap.flatten()
idx = img
i = np.floor(idx / 256)
j = idx - (i * 256)
R = flat_colormap[(3 * (i * 256 + j)).astype('int')]
G = flat_colormap[(3 * (i * 256 + j) + 1).astype('int')]
B = flat_colormap[(3 * (i * 256 + j) + 2).astype('int')]
rgbArray = np.zeros(shape=(img.shape[0], img.shape[1], 3))
rgbArray[..., 0] = R
rgbArray[..., 1] = G
rgbArray[..., 2] = B
return rgbArray
However, I would like to apply such a colormap but in my fragment shader.
Thus, I wonder I will have to use two sampler2D in my fragment shader but I do not how to achieve the same result as in Python.
I past the answer I got from the OpenGL forum: One option:
uniform usampler2D image_tex;
uniform sampler2D color_map;
in vec2 texcoord;
void main()
{
uint value = texture(image_tex, texcoords).x;
uvec2 uv = uvec2(value / 0x100, value % 0x100);
vec4 color = texelFetch(color_map, uv, 0);
gl_FragColor = color;
}
Note that the image texture needs to be of unsigned integer type, i.e. GL_R16UI. Magnification and minification filters need to be GL_NEAREST (linear interpolation isn't meaningful for integer values).
If the values in the image texture represent a continuous range and the colour map is continuous, then you could use a normalised format (i.e. GL_R16) for the image texture and use a 1-D texture for the colour map (however a size of 65536 isn't guaranteed to be supported, so you may need to down-sample the colour map). E.g.
uniform sampler2D image_tex;
uniform sampler1D color_map;
in vec2 texcoord;
void main()
{
float value = texture(image_tex, texcoords).x;
vec4 color = texture(color_map, value);
gl_FragColor = color;
}
Or you could use a buffer texture for the colour map (a size of 65536 is guaranteed to be supported), which avoids the need to split the value into row and column. E.g.
uniform sampler2D image_tex;
uniform samplerBuffer color_map;
in vec2 texcoord;
void main()
{
float value = texture(image_tex, texcoords).x;
int idx = int(round(value * 0xFFFF));
vec4 color = texelFetch(color_map, idx, 0);
gl_FragColor = color;
}