New local contrast tool

I have just committed a new implementation of the local contrast adjustment tool.
The new tool is based on the same incremental guided filter that is also used for the shadows/highlights tool, and was inspired by the discussions and examples from this thread.

As the name suggests, the tool allows to control the amount of local contrast in an image. It extracts the high-frequency parts using an edge-preserving guided blur, and then adds back the same high frequencies, either enhanced or suppressed.

The effect of the filter is reduced when the blurred image approaches black or white. This filter is therefore mostly acting on the mid-tones.

Here is an example of the filter in action, with default parameters. It is particularly effective in enhancing the texture of the fur and wings of the butterfly, without generating disturbing halos.

Original image:

Amount=100, radius=64, threshold=20:

The tool is available in the latest packages.



Nice! It has come a long way. One thing that I have noticed is that it kind of has an unnatural “baked” look to it. I don’t know how else to describe it. It isn’t like the extreme HDR look but is slightly reminiscent of it. Nothing to do with the local contrast. I am thinking it has to do with the gamut mapping part, which by the way is still much more robust than your previous methods.

PS I am interested in what you have done to improve the algorithm in this post.

This might be due to the underlying algorithm, which tends to favour and “over-enhance” bright details in dark areas.
The exact formula that is used is
L' = L \times (L / S)^{(\gamma * A)}
where L is the input luminance, S is the smoothed luminance, A is the “amount” of the local contrast adjustment, and \gamma is a correction factor that is used to further control the strength of the effect.

When S coincides with mid-gray, \gamma is set to 1. When S is darker than mid-gray and L > S, \gamma is set to a value > 1, or in other words the effect is “boosted”. If L < S then \gamma is set to a value < 1, so that the effect is limited. This avoids that dark details are pushed too far on the dark side.
A similar but opposite logic is applied to areas where the blurred images S is brighter than mid-gray.

For performance reasons, all calculations are done in log encoding, so that multiplications are replaced by sums, and powers are replaced by products.

You can find the actual code here. Do not hesitate to ask about the details, or propose improvements!

There is no gamut mapping in the local contrast module. Is this coming from an additional layer?

1 Like

So the only change is the power term? Does S = Lmean, or something else?

Hazarding a guess. You have answered my question just now.

S is an edge-preserving mean, obtained with an incremental guided filter…