Tone mapping and gamut compression articles

Hi,

I’ve found a bunch of interesting articles (I’m behind the times, so probably not new to most of you).
A simple gamut-compression algorithm: gamut-compress/docs/gamut-compress-algorithm.md at master · jedypod/gamut-compress · GitHub

And a bunch about tone mapping:

6 Likes

So, I’ve tried the Uchimura curve on a few images (it was applied per-channel). I loaded them into darktable, exported as 32-bit linear Rec2020 floating-point TIF, tone-mapped them, and then gamut-compressed them to the sRGB gamut (using gradual compression to bring out-of-gamut values inside the gamut).

DSC09445 from Comparing filmic color science v5/v6

The fire image from Comparing filmic color science v5/v6 - #72 by age. I brightened this a bit using linear exposure in dt.

c_payne_J001_C001_08178N_001.aces.exr from https://www.dropbox.com/scl/fo/dzjhto8kejh35vu0mcvdu/AKAuQyd8Qlr24qm8Gl9X08w/c_payne_J001_C001_08178N_001.aces.exr?rlkey=mhbf9l2qy8r8fav3ajn7t1a15&dl=0

5 Likes

OK. Some gamut compression charts.
We are rotating in 30-degree steps around the D65 white point xy coordinates, so each of these contains 12 groups of bands.
For each angle and Y luminance value:

  • we take the xy coordinates at the edge of the Rec2020 gamut (this is determined via a simple search), and note its distance from the white point (maxDistanceRec2020)
  • Then, we shorten that distance according to a fixed multiplier; each chart has its own, starting from 40% and going up to 100%, in steps of 10%. We treat this as a kind of ‘saturation’. distance = saturation * maxDistanceRec2020
  • Then we calculate the x and y of the unmapped pixel:
    x = cos(alpha) * distance + D65_WP_x
    y = sin(alpha) * distance + D65_WP_y
  • We convert this xyY into XYZ, then to Rec709RGB, and clamp the components to [0, 1], to demonstrate the naive approach. These values form the first line in the band.
  • Then we take maxDistanceRec709, the max. distance for the given angle for the Rec709 space (again, determined via a search).
  • We calculate ratioToMax709Distance = distance / maxDistanceRec709
  • We pass it through a curve that’s linear until 0.8, and smoothly converges to 1 above that. This gives us compressedRec709RatioFromMax.
  • We calculate compressedDistance = maxRec709Distance * compressedRec709RatioFromMax. If the original distance was less than 80% of the maximum, it remains unchanged; otherwise, it gets compressed more and more, but will never exceed the max. distance.
  • Then we calculate the x and y of the mapped pixel:
    x = cos(alpha) * compressedDistance + D65_WP_x
    y = sin(alpha) * compressedDistance + D65_WP_y
  • We convert this xyY into XYZ, then to Rec709RGB, and clamp the components to [0, 1]. These values form the second line in the band.
  • The third line in the band is simply Rec2020 at 30% saturation, as that saturation never needs compression. It’s included as a hue reference.
  • The fourth, monochromatic line indicates the extent of the compression, 1 - compressedDistance / distanceRec2020. Black means no compression.

Right. So, here are the charts (from 40%, as 30% needs no compression):

Rec2020 at 40% (only one of the greens needs some compression):

At 50%:

At 60%:

At 70%:

At 80%:

At 90%:

And at 100%:

If you have good wide-gamut (but not HDR, so Y should not exceed 1) input files, I’d appreciate them, to check how this behaves with real-world images. Flowers (maybe @ggbutcher ?), hummingbirds, whatever.

Thanks for reading, if you got here. :slight_smile:

4 Likes

And hue angle / saturation series, with increasing Y (from 0.1 to 0.9, in increments of 0.1), again mapping Rec 2020 to Rec 709 (saturation is meant as above, WP → pixel xy distance relative to the Rec2020 gamut boundary, then smoothly compressed into Rec 709 as described above):

Clamping, for comparison:

1 Like

What are you try to do?

Compressing a wider gamut into a smaller one, without a perceptual profile.

2 Likes

What does this mean?

You take colours inside of this triangle:


And try to map them inside this one:

While not completely killing all the colour, and reducing / avoiding harsh transitions, colour shifts and similar artefacts.

1 Like

Is it abut moving numbers around?

Does not depebd on image?

Flowers etc may have vibrant colours we cannot display on a monitor, or represent in an sRGB JPG; that’s when this could be useful.

I have versions of this algorithm that tries to figure out the required amount of compression based on image content. This series was done with a fixed level, as it’s based on synthetic test images.

So a picture can’t display flower?

What?!!

Beginning to look like trolling to me …

1 Like

Quite correct. Pictures, even more on paper, but also on screen, may have problems rendering the colors of some flowers correctly.

This is an international forum where one need to take into consideration that not all participants master the English language very well.

1 Like

So, I’ve found a few shots. All of these were exported in Rec 2020 floating point, no contrast, curves, no tone mapping (filmic, sigmoid), and no saturation changes in darktable (I did leave color calibration’s default gamut compression at 1).

_DSC0488.NEF from Chrysanthemum flowers
This one had bright highlights. If I clip Y to 1, I get this:


Tone mapped using Uchimura, then gamut compressed:

_MG_0113.CR2 from Hummingbirds, highlights... help!
Had a tiny bit of over-exposure, but I just clipped Y, no tone mapping:



20190614_RAW_Blumen_0017.nef from Flower Power with Roses

My own 2024-07-03-16-08-39-P1030868.RW2, from Deep Purple - One More Rainy Day

5D3_0104.CR2, from Difficult orange flower

2 Likes

619A6812.CR3, from A hummingbird play raw
Has some clipping, as visible in the flower, which is not taken away by tone mapping, either.




7E4A0518.CR3, from [PlayRaw] Flower
The small bright flowers were out of focus.

DSC_0106.NEF, from Dublin Bay Rose, up close.


Tone mapped:

With some contrast (via brilliance controls) in color balance rgb:
Y-clipped:


Tone mapped:

DSC_0134.NEF, from Red flower monster
Maybe too bright.


Tone mapped:

Exposure reduced, no tone mapping:

DSC08363.ARW, from Deliberately difficult gamut colors in macro shot of hex nut
Y-clipped:


Tone mapped:

DSCF0259.RAF, from Roses are red, but my lens was not new

IMG_7089.CR2, from Red Rhododendron... why are some flowers so difficult?

3 Likes

Everything is :wink:

3 Likes

But images of flowers here?

What do the numbers mean? Should matter?

I honestly do not know if:

  • there is a language problem, and that causes the communication issue;

  • you are ‘artistic’;

  • you really want to know what those numbers mean;

  • you are a troll (sorry for my bluntness, I cannot rule out this possibility).

  • If there is a language barrier: please use an online translator service, or write in a language you know well and that can be translated online.

  • If you are ‘artistic’: yes, when working with computers, numbers are everything. You don’t need to always understand their meaning, in order to use software (I understand way less than I would like to). Only you can decide you are interested or not. If you aren’t, please do not take part in technical discussions, since the outcome does not really interest you, and you are wasting the time of others. If you are interested, please ask more concrete questions – if possible, please first check other sources online, there is a lot described about the basics of colour in different blogs, Wikipedia etc.

  • If you are a troll, then there’s nothing I can say. If you do not chose one of the options above, this is the only one remaining.

Thank you.

2 Likes

Ah, I remember the nut; hard to keep most “normal” processing from going cyan. This was one of troy_s’s major concerns about my SSF LUT work, and I never found time to dig into it.

Nice work; the color conversion part of raw processing is probably the least-understood, you give a nice step-thru of your approach that lays flat a lot of the generic stuff.

Now, you’ve got me re-interested in studying the overall march from camera response to rendition gamut. Unless one wants to go all-out on ACES, the ICC gonkulator is the context for that…

2 Likes

The what? :laughing:

1 Like