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:
- 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. - 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 gamma
correction, 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.
-
I asked recently here https://discourse.julialang.org/t/function-that-converts-rgb-color-to-cam02-ucs-coordinates/65822 if a conversion RGB->CAM02-UCS, and conversely, is available in some Julia package, but the answer was negative.
There is no direct transformation between the two color-spaces. The conversion is performed via a sequence of composed transformations. -
The non-linear lightness resulted after gamma-correction of RGB color coordinates can be uniformized in just a few lines of code
https://github.com/liamedeiros/ehtplot/blob/master/ehtplot/color/cmath.py#L84.
The result for the plasma example is posted below the first two previous images to compare the effect of uniformization. -
I don’t know if there is the posibility to call from Julia functions from
ehtplot
, as long as it can be installed only via setup.py.
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.