After a long time and another investigation of a related issue connected with color lookup tables, I found the reason for the behavior and why for color lookup tables a scalar range different from 0 to 255 does not really produce meaningful output:
The reason is that the vtkImageMapToWindowLevelColors filter in vtkMRMLScalarVolumeDisplayNode always outputs unsigned char. This output from 0 to 255 is then mapped to the colors according to the lookup table.
This basically prevents using more than 256 colors for a volume. I ran into this limitation when I wanted to map fMRI images with some transparent colors in the area around 0 with a colormap containing 1024 colors. Due to the limited resolution of the pipeline, the one or two color entries in the map with 0 opacity were sometimes simply not used and everything was therefore displayed fully opaque.
IMHO for the future it would be great to think about using a filter with a higher resolution for the window/level calculation. This would enable a greater fidelity of displayed volumes.
Monitors generally only support 8-bit dynamic range for each channel. To get larger dynamic range, you would need a specialty monitor, special graphics card, and rendering pipeline that supports this; or use the luminance trick (create a carefully crafted RGB lookup table and a grayscale monitor). These are all out of Slicer’s scope: either happen at lower level in VTK; or rely on a workaround that can be implemented without changing anything in the application (luminance trick). See more information about this here.
It is worth noting that high dynamic range (HDR) wide color are available. My M1 MacBook Air reports 16 bits per sample for the internal Retina display. According to the documentation, some Apple devices use 10-bits per components, and others that report 16 bits per sample will dither the data to 8-bits.
However, in general I think the human eye has a hard time distinguishing more that 256 luminance levels. For scalar volumes, I am not convinced the 8-bit limit imposes much constrain (assuming you have chosen a good window level and window center). The need for more than 256 colors are more for non-scalar data like atlases.
I think that color information with 8 bits per channel is definitely enough for the vast majority of cases. My question was not going into the direction of expanding this. However, we cannot exploit the 16.7 million colors but are limited to 256 for a volume to be used.
Also here I think that this limitation is not problematic in general.
vtkImageMapToWindowLevelColors probably was designed primarily for display purposes. However, with a configurable output range, it would probably be usable more flexibly, on the one hand for higher-resolution lookup tables for display purposes or on the other hand also for use within data processing pipelines.
I also know that the filter is part of VTK and is not maintained within Slicer, so the post may have been better placed in there forum.
However, I wanted to post this as a follow-up to my initial question about the relationship between
- the scalar range of a lookup table that can be manipulated in the Colors module of Slicer
- the number of colors in the colormap
- the window/level and threshold controls in the Volumes module.
What I have to realize is a customizable fMRI display facility with two threshold/window/level ranges such that the volume can be transparent in the areas around 0 to be able to see the MRI that lies underneath.
I didn’t want to change Slicer’s internals here, so I initially used the built-in fMRI lookup table and set the middle values (e.g. 21 and 22) to fully transparent, according to the settings in my custom UI. As the table only has 42 colors, and 0 is supposed always to be in the center, I started to generate tables according to the desired settings, with customizable tables for each of the both ranges, at first with 256 colors, then with 1024, thinking I could increase the resolution to a ‘sufficient’ level. This is where I encountered the limitation.
Of course this is an improvised solution. The proper way of doing this would be having a pipeline that allows thresholding and extraction of window/level for two different ranges, and displaying them with two different lookup tables. In this case, the 256-color limitation of the filter mentioned above would again be no limitation.
Another option would be to duplicate the volume and handle each of them separately, but this would be harder to maintain and is not very intuitive for the user, who loads one file.