Gamma correction for colormaps

Is there a way to have a gamma Node, which is linked to the gamma value of a colormap in Makie?
Colorbars can have limits, but no gamma yet as it seems. Is it possible to implement this into Makie or can one write a colormap function that supports this gamma parameters and use it instead of :grays?

No, there’s no transform function for color maps, but you can transform your array passed to the color attribute of course.

Oh. I thought about this, but transforming the data is not a great idea, as this would mess up all the other reporting and I also could then not use the standard features etc. It also would cause performance issues. Thus a gamma-modified colormap would really be preferable.

Here is some code which seems to do the trick:

using GLMakie
fig = Figure()
ax, im = heatmap(fig[1,1],rand(10,20))
cb = Colorbar(fig[1,2], im, label = "Brightness", alignmode = Outside())

using PerceptualColourMaps, ColorTypes
apply_gamma(rgba, gamma) = ColorTypes.RGBA(rgba.r^gamma,rgba.g^gamma,rgba.b^gamma,rgba.alpha)
m=cmap("L3", N=4096)
mg = apply_gamma.(m,0.3)
cb.colormap[] = mg

@jules which internal function are you using in Makie to convert a name to a colormap? I should presumable just hook into the same function and then submit the resulting colormap to cb.colormap, but it should have more than 256 values, as otherwise there may be too much blocking with low intensities for non-8-bit images and gamma values far from 1.0.

I think Makie.to_colormap

I was curious what influence has the gamma-correction on a perceptually uniform colormap in the space CAM02-UCS (i.e. the space where the colormaps viridis, plasma, inferno, magma, as well as cmocean colormaps, are perceptually uniform).
To illustrate this effect I used the ehtplot, a package developed for the EHT (Event Horizon Telescope) project, and released just before the publication of the first black-hole image, https://github.com/liamedeiros/ehtplot.

ehtplot converts r, g, b color-coordinates of a colormap to lightness, chroma and hue, as coordinates in the CAM02-UCS space. A colormap is perceptually uniform in this space if the lightness is a linear function of the normalized values.

In the panels posted below, the upper cell illustrates the representation of a colormap in this space. The lightness graph is colored by the colormap.

The second row can illustrate drawbacks of the colormap that can be fixed by ehtplot.
The conclusion is that gamma-correction breaks the linearity of lightness, and the new colormap is no more perceptually uniform. But the non-linear lightness can be uniformized by ehtplot:



That’s a great thought and thanks for the figures. To see, if I understood this right (please correct me!), I will try to summarize and comment:
I guess gamma corrections serve two major purposes:

  1. correcting for nonlinearities in the display device. This would mean, for an RGB display device the R,G and B channels each get a gamma correction applied such that it performs linear. I guess this use still means one should apply them to RGB as before.
  2. Enhancing the ability to perceive (or suppress) small data gradations for the low intensity region.

The latter is probably what it is mostly practically used for. Yet, as @empet has shown, in terms of perceived brightness a Gamma correction, equally applied to the RGB channels, does not really do what is is supposed to do for perceptual colormaps: The (perceived) brightness, i.e. lightness does not follow the naively expected gamma curve, but starts to get some bumps.

To me the conclusion is that one should create a modified gammacorrection, which serves to act on lightness and/or hue. I have little experience with perceptually uniform colorspaces in Julia. Are there an easy to use hsluvToRgb and RgbTohsluv fuctions in Julia? Then it would be very easy to implement the application of to above gamma to the appropriate channels in Julia.

Maybe comparing a couple of images with low details in the low intensity region, shown in naive gamma and perceptual gamma would be enough for a small paper, if nobody has done this already. It may also be worth to pull the transformation math through and give more gist to such a paper and a (faster) RGB version of the perceptual gamma function.

Thanks for the reply. Sorry, I somehow must have missed the uniformized result. Anyway, I think this is not what I mean. In the original colormap you can see the red tones whereas the final “uniformized” one is missing them. What we want is simple a gamma applied to the (monochrome) argument rather than the R,G,B values. If the colormap is RGB([red(gray_in),green(gray_in), blue(gray_in)]) then we now want RGB([red(apply_gamma(gray_in)),green(apply_gamma(gray_in)), blue(apply_gamma(gray_in))]) in which case red(gamma()) etc. define the new colormap.