Test the new and enhanced Shadows/Highlights tool

I’d love to have a pool of sample RAW images that are particularly suitable for testing shadows/highlights adjustment and dynamic range compression in general (actually, I believe the two things are the same). I am also doing some work with edge-aware blur filters and dynamic range compression, and it would be great to be able to directly compare results. I am mostly playing with the concepts and examples provided here.

What do you think?

Yes and the banding shifts if you change the tonal width. The raised shadows doesn’t quite reach the lowered highlights that is why there is a wider stripe.

What I find strange is what happens in the raised shadows:
Original picture was a jpg gradient, white on the left and black on the right.

See the black pixels they stay black for some reason when raising the shadows. The halo on the dark end comes from raising the radius. Which means he seems to detect an edge there?

These were the settings:

Hi,

I have no direct experience with the bilateral filter, but I’m a huge fan of the (fast) guided filter. It’s a simple, efficient, and yet extremely powerful tool. It can be implemented in a few lines of code, and has many interesting applications, not just dynamic range compression (e.g. also dehazing, denoising, feathering, detail enhancement… see the paper for examples). Here is a little demo of some of its possibilities (note, this is my “playground” version of RT, it’s not in the official repo):

1 Like

I’m also very much interested in this option, as I still have few “theoretical” difficulties with the bilateral filter and its proposed optimizations (in particular those that rely on image down-sampling).

Could you point me to the relevant file for the fast guided filter in RT?

Thanks!

P.S: could you remind me in which post I can find the picture your are using in your video? Thanks!

Hi,

Here. There are a few other interesting ones here as well.

1 Like

I LOVE the guided filter. I use it and link it whenever I have an excuse to do so. A lot of sophisticated applications and derivatives have been researched since. At its worst, it performs as well as the bilateral but is faster and simpler. … At least that is what I have read and experienced so far.

Just did a quick test with your settings, 100% view, RGB and Lab, I’m not seeing the halo or anything strange -

There’s some similar stuff here to my “Tone Enhance” filter in G’MIC (bilateral + tone masking), so perhaps it’s useful to show a breakdown of how the gamma adjustment part functions. It can possibly be simplified further.

Edit: I must point out the example here is from a quite heavily compressed “sample” image in G’MIC.

  1. Median then bilateral the image, convert to luma then split to 3 tones
    fruitsmask
  2. Create a “gamma mask” from that with the user supplied values (an exponent value per pixel)
    gammamask
  3. Apply it (raise to that exponent), example here uses gammas 2,0.8,0.5 for shadow, mid, highlight
    fruits_toned

G’MIC code stripped down to those parts:

gcd_tone_simple : skip ${1=1},${2=1},${3=1},${4=128}
  repeat $! l[$>]
    +n 0,255 median. 3 bilateral. 2%,30 gcd_srgb2luma.
    sub. $4 +abs. negate.
    +max.. 0 min... 0 abs...
    mul... {if(iM#-3>0,(1/$1-1)/iM#-3,1)}
    mul.. {if(iM#-2>0,(1/$2-1)/iM#-2,1)}
    mul. {if(iM#-1>0,(1/$3-1)/iM#-1,1)}
    add[-3--1] 1 mul[-3--1]
    m={0,iM} div[0] $m pow[0,-1] mul[0] $m
  endl done

The main thing I wanted to show is that G’MIC is very good for prototyping this sort of thing (there’s also a “guided” filter in G’MIC).

1 Like

Interesting. I like the look of the fruit in the second image. (The two colour images are presumably before and after?)
The process is above my head but where did the three gammas 2 .8 .5 come from / how derived?
Is it easy to apply this processing to my test image above, the TIF? - I’d be interested to see the results.

Completely arbitrary gamma values just to demonstrate (higher = brighter, untouched = 1). That’s all I wanted to do here - show that gmic makes testing extremely fast compared to writing in c and compiling. I wouldn’t suggest this as a drop in replacement; it’s working in sRGB “gamma” and doesn’t allow radius selection amongst other issues. Nonetheless, here’s an example of the test image with quite aggressive values 2,1,0.5:


As you can see, there is some halo. That could be reduced by changing radius.

Edit: yes the previous was before (top) and after (bottom).

I would like to understand the problem better. What would the gradient ramps look like ideally?

I’d suggest something like this -

  1. Before

  2. After

  3. After but with less tonal width

@garagecoder, thanks for posting your GMIC version.

1 Like

I did an experiment. I get that too when I really push the the edges of the ramps. See how @garagecoder’s ramps have dark and bright edges? When I try to smooth them out perceptually, the artifacts appear. I won’t share the G’MIC code or images because they didn’t output correctly and I don’t have the time to figure it out.

I looked for that build, but didn’t find it on 181025.

@agriggio could you please explain briefly the structure of the algorithm behind new shadows/highlights tool? I know what a guided filter is but I am having some trouble understanding the C code.

I may have some suggestion for modifying it to prevent gradient reversals like the above but I want to make sure I know what’s going on before spouting off.

Hi,

the idea is pretty simple (actually naive I’d say). The algorithm applies a “gamma” (i.e. power function) to highlights and shadows separately, with exponent > 1 for highlights, and < 1 for shadows (with the actual value dependent on the “amount” sliders). The “tonal width” sliders decide the thresholds (in percentage of the L* channel) for determining what to target. For example, the “highlight tonal width to 70” means that all the pixels with an L* value >= 0.7 in a range [0,1] will be considered highlights. A guided filter is used to blur the masks for smoother transitions. The “radius” parameter controls the smoothness essentially.

All suggestions are very welcome. However, IMHO the examples above show that the tool is “broken” in the same way as the following shows that the Tone Curve tool is “broken”:

(I.e., if you push the sliders too far, you are going to get artifacts…)

1 Like

I think the idea to use a guided filter is quite keen, actually! Some googling indicates that Adobe was using local laplacian filters, at least a few years ago (http://blogs.adobe.com/lightroomjournal/2012/02/magic-or-local-laplacian-filters.html), so I think it is great that we are using a better method than even the leading commercial software.

I was going to suggest building a one-to-one sigmoid-type curve from the given parameters and then using that to remap the L* channel. A larger highlight parameter would be more lifting in the highlights, and so on. This would prevent gradient reversals, but it seems impossible to do it without touching the midtones, so actually the current implementation is probably best.

Although I agree that all tools can be abused, my feeling is that the kind of tonal overlaps indicated upthread are responsible for the characteristic “bad HDR” look that heavy highlights/shadows adjustments sometimes produce. So it may be worth thinking about how to prevent them so we can recover even more detail without worry. This idea is explained more here:

Thanks again for your explanation and your contribution!

The problem is where you have the same pixel value appearing in both dark and light areas (a common occurrence), if you wish to adjust it for one of those areas only. Using a global curve/lut of any type will not work in that case, without some form of mask/map.
Sometimes using iterations of a smaller adjustment can avoid artifacts (equivalent to repeatedly applying a smaller tone change). Obviously at the expense of run time (here’s one done with iterative bilateral map):

1 Like

The S/H tool is not meant to do “heavy HDR”. Rather, it’s meant to be applied with a “light touch”, and used in conjunction with other tools that can deal with dynamic range compression (the “Dynamic Range Compression” one in particular – oddly enough ;-). See also:

1 Like

Good points, both of you. Thanks for the discussion!