darktable tone equalizer : help wanted


I’m preparing an in-depth video tutorial about the new darktable tone equalizer module, to avoid reproducing the errors made with filmic v1 (some people got it and enjoyed the time savings, some are still struggling with it and don’t save any time, mostly because they don’t get the problem it solves).

I want to collect here your questions, surprises and misunderstanding about darktable tone equalizer so I can made an extensive presentation of it. I already have a few in mind, but the more the merrier.

Also, please post images you had difficulties editing with tone equalizer so I can edit them live.

1 Like

I only have problems with the masking. If I follow the bar which indicates what to do, it doesn’t really work. Using the landscape preset works normally very well.

Sorry, just posted some questions there: A tone equalizer in darktable ?

Not sure this the same issue, but when I use “mask exposure compensation” the bar graph above does not always change in a smooth and continuous manner.

1 Like

I also have questions with masking.
When should it be more diffuse? What impacts do the mask settings have on a picture (from a non technical perspective)? Are there recommended groups of mask settings for each kind of images (hdr, ldr)? Are there recommended groups of mask settings for each kind of desired result (as @phweyland mentioned before, high contrast result, contrast compressed result)?

I see that the mask settings deeply affect the final result, but I’m not able to say something like this: “Humm, for this kind of picture, and for the result I want, I have to tweak this and that mask setting

EDIT: Also, it would be nice to keep showing the tie between tone equalizer and filmic rgb.

Smooth and continuous setting is asking a bit much here, but I will see what I can do.

I think there are some cache issues that make this feature fail. More bugs to hunt.

(Full story : the histogram stats are cached and computed only if the mask has changed, and that mask is cached too and computed only if the masking settings or the lower modules have changed, to stay energy-efficient and more responsive in GUI. However, synchronising caches is a nightmare).

Nothing else guys ?

I would also appreciate more explanation about the masking process.

I have been using tone equalizer a bit now and it’s a great tool. The only thing I struggle is to predict how to spread the histogram across all the nodes. The preview bar in the masking tab most of the time is not centered while the histogram in the advance is fine, and the other way around (a center bar does not equate a center and/spread histogram).

Also, maybe one question : say I want to work more on the highlights, does it make sense to spread the histogram just for the highlights? Meaning that most of the nodes in advanced tab will be used to control the highlights ? Is there any downside to do so?

I ask this cause on some pictures, I don’t find a way to pull down highlights enough while at the same time raising the mid tones. Hence the idea to have two instances of the tone equalizer : one for mid tones and shadows, the other for highlights.

Note I mainly use tone equalizer for landscape properly exposed with few over exposed areas.

Forget about highlights. Tone equalizer knows no highlights, it just splits the dynamic range you feed it in 9 zones, spaced by 1 EV. Highlights may fall into the 0, -1, -2 EV band, that doesn’t change anything. Always try to spread the histogram over all the available nodes, so you get maximum control over your whole dynamic range.

Preliminary answer here, for @Julien76, @gadolf, @asn and @phweyland, regarding the masking:

  1. The mask used in tone equalizer simply compresses an RGB image into a grey map representing the pixel lightness, using several norms, and is used internally to map the pixel lightness to the control nodes to apply the corresponding exposure correction.
  2. If you don’t use the details preservation option, the tone equalizer falls back to a simple tone curve with built-in chroma preservation. That’s good if you want to increase the contrast in a picture and don’t mind the over-sharpening (aka you want local and global contrast increase).
  3. If you are decreasing the contrast (in HDR situations) or want to increase the global contrast without affecting the local one (in studio portraits, to avoid making skin flaws pop out too much), you need to post-process the mask and use the details preservation mode.

To avoid affecting the local contrast along, we need to make sure that the same exposure correction is applied over contiguous areas of the picture (say : all the background gets -1 EV, and all the foreground gets +1 EV) and these areas are properly separated.

We therefore need to post-process the mask with a surface blur. We do that with a guided filter.

  1. chose the luminance estimator that gives you the most separation between the areas you want to dodge, and the ones you want to burn,
  2. chose the smoothing diameter depending on the size of the elements you want to isolate,
  3. adjust the edge feathering:
    1. if you get halos along sharp edges, increase it,
    2. if you get too much local contrast compression, decrease it.
    3. Note that a very high edge feathering (> 100) is equivalent to disabling the details preservation at all.
  4. if the trade-off beween smoothing diameter and edge feathering is still not enough to get a good edge-aware blurring:
    1. increase the mask diffusion (aka apply the guided filter iteratively on top of itself),
    2. increase the mask quantization (aka use a pseudo-boolean mask in the guided filter).


The core of the guided filter is actually a box average (also called box blur), which computes the local average in a square box around each pixel. As you increase the mask diffusion, the mask quantization, and decrease the edge feathering, the post-processed mask will tend to its average lightness. Thus the histogram will shrink around its average, and most nodes in the equalizer will consequently control nothing.

So the mask exposure and contrast compensations are just there to counter the averaging effect of the guided filter and force-spread the histogram over all available nodes.

That’s why we don’t care about highlights or shadows in this module, because what the -1EV band actually represents depends on the masking options, and doesn’t change anything since you have the interactive correspondance between image preview and EV band.

At any rate, preview the mask for each step, and read the tooltips labels I have put on each slider, that should help understanding what’s going on. Litterally every setting has a tooltip.


I still did not have time to watch your previous video about features in DT 3.0 so I do not know if my wish list is valid.
I would like to learn basics:

  • what is this new tool,
  • does it replace any previous tools or extends beyond old tool capability
  • what is can do in a very few obvious and straightforward examples,
  • when shall I use it
  • how it affect my old workflow which is based on:
    a) white balance, lens correction, tone curve, equalizer/local contrast + later local correction
  • when this module shall be avoided
  • is it good for portraits
  • is it good for global adjustments only

and later on the more advanced topics:

  • masking
  • tweaking the tool
  • doing wizardry

I would love to see a lot of examples. That would be the best of all.

I struggle to use filmic but more often I end up with several tone curve modules with local edits. Maybe the tone equalizer will be able to do in a single instance what I usually do with 2 or more instances of tone curve

Thank you for preparing such video!


Thanks for this fantastic new tool. It closes the gap to LR a fair bit more. I just like to share my experiences after having read earlier posts and having watched your video, which is not the shortest one but great anyway :wink:.

When I started with tone equalizer I first tried to use the “simple” tab. This tab left me completely confused. I simply could not understand the meaning of the slider´s names (+/-*EV). The second names (highlights, mid-tones, etc.) didn´t help either as they produced more ore less unexpected / unpredictable results.

I then used the “in-picture editing cursor”. Brilliant Idea, easy to understand and work with, made for lazy and dumb users like me => Absolutely cool!

At this stage my problem was, that sometime things happened as expected, and sometimes not. Tweaking the EV (Now I understood what it meant) at a specific location in the picture altered regions that wheren´t always predictable. By moving the editing cursor over the picture I noticed, that the histogram under the “advanced” tab didn´t match the tonecurve histogram.

I found the solution in the last tab “masking”. You have to set this mask first to get the results you expect as you explained here:

Whooops ! Now I get the results I expect. Using this workflow, tone equalizer is a powerful tool, far more versatile as any available commercial software. :sunglasses:

Just an idea: Perhaps you can change the order of the tabs along the workflow like in filmic:

  • Left tab: “masking”
  • Middle tab: “advanced”
  • Right tab: “simple”

Thanks a lot again,

Thanks for you new and awesome tool!
However I feel we’re not there yet…

  1. The first thing I noticed when fiddling with it is that the mask in reality doesn’t correspond the actual pixel luminance. Trying to adjust the mask I now and then see the black areas on the mask that are not there in the original picture. I notice that they are (almost) always on the bottom of the picture, usually in the corner (see https://yadi.sk/i/QF1j_wE8AD5P_A). I can make this effect more pronounced but cannot get rid of it if I want to use more nodes. As a result, only few nodes are usable, in spite of the histogram is shown as well spread.
  2. Minor adjustments in sliders make huge changes on the histogram. One wheel click over the slider sometimes makes the histogram bar jump from one side to another. Moreover, when I turn the wheel one click back, the histo-bar won’t get back to where it was before. It moves slightly in the new corner, then jumps. So we have something like a hysteresis effect.

In both cases it seems like some bugs are there.
Also, I’m thinking if there’s a reason to purposely spread a histo-bar beyond the edge to have more available nodes in narrower luminance range than the whole picture has (say, to fiddle with the clouds).
I also have to say that I experienced few segfaults when trying to use TE with the parametric masks. I’ve to collect more info before filing a bug, but it seems to interfere with mask feathering.
Thanks again!

Don’t forget your “luminance” (it’s not actual luminance) mask gets post-processed with exposure & contrast compensations, then with a guided filter. So what you see is not what you get. The mask is there only to split the image in areas based on lightness, it’s not supposed to be a 1:1 correspondance with the source luminance.

Because the ground is dark and the sky is bright, so that makes sense.

Later tests I have done show that trying to hard to spread the histogram over more nodes doesn’t necessarily give better results. In very difficult situations, using no exposure and no contrast compensation, and the 4-5 nodes overlapping the histogram is the safest path.

The histogram and luminance mask are cached in memory for better performance (so you don’t recompute them each time, only if parameters have changed), but I suspect an issue with cache synchronization/invalidation.

I thought so at first, but it seems now that it’s not always a good idea.

Yep, you are not the only one. With OpenCL, right ?

1 Like

I don’t. In my case it’s quite obvious. Moreover, I tried to fiddle with that to check if this is involved. Seemingly it doesn’t. Did you look at the screenshot I attached?

I wouldn’t be that sure. I saw this effect indoors, on a evenly lighted water surface, etc. I can provide you with the RAWs and XMPs to check if need be.

If the histogram is spread over only couple of nodes the module is quite useless, isn’t it?

…which doesn’t automatically mean it’s always bad, does it?

Right. Good you’re aware of that.

This discussion is starting to remind me our previous one, about color shift in filmic v2. (Which I think turns very fruitful eventually. The usability and color control of filmicrgb is way better). Please try to find sense in what i’m trying to point out. I’m not trying to neglect your efforts, on the contrary I very appreciate them and trying to make the result even better. Thank you!

I see the same behavior. The histobar sometimes jumps here and there unpredictably with one click of the mouse wheel, and it doesn’t go back where it was if you revert the change

tone equalizer is really very powerfull but also heavy to process. will there be opencl support at some point?

OpenCL is planned at some point, yes, but not before I ensure the caching mechanism is bug-free.

Try rotating and mirroring your image. If the mask moves accordingly, nothing wrong. That effect should also depend on the size of the guided filter, so you may want to play with it to see if it improves things.

No. My first intuition was to spread the histogram as much as possible (hence the contrast and exposure mask corrections), but, because of the guided filter properties, for applications like shadows/highlights compression, it seems having it spread over all the nodes might be more damaging and difficult to control. At any rate, don’t forget the tone equalizer is a fast-track to do exactly the same thing as several instances of exposure modules with masking, and whenever you have a clear background/foreground separation, a masked exposure might be easier to control.

Okay. Mirroring the image causes the mask mirroring, too. Yet I’m still quite sure there are bugs/errors in how the mask is built.
Here is the mask

And here comes the original file without any additional development (only mandatory modules plus Transformations to level the horizon)

As you can see, the darkest areas on the mask are definitely not the darkest ones in the picture. Far from it. Obviously the darkest areas are the rocks faced to the camera and therefore not lighted that are about 1/3 upward from the bottom. And those in corner are obviously lighter. (That how it ought to be, provided the light direction). However, the ТЕ picker shows -8.5EV on rocks in the lower right corner (original pic shows L=22 in LAB with DT’s picker), while only -4EV in the darkest area (L=5 in original DNG), which is obviously wrong.
The files to play (original DNG is not mine, but taken from the internet. Was curious how DT would process Pentax K1’s shots. And the landscape itself is nice)
Пересвет_01.DNG.xmp (12.2 KB) Пересвет.DNG (43.5 MB)
I can provide you with more samples that show the same behavior.
From my PoV, at the moment the TE module is very promising but definitely half-baked yet. The mask is obviously build in a wrong way, and the module is still quite unpredictable and counter-intuitive in many aspects (as the early versions of filmic were, with oscillating spline and all that. Now it’s nearly perfect, BTW). Unfortunately at the moment it’s not a “fast-track”, because if you’re lucky and one of presets fits in, it kinda works. If not, trying to tune it quickly becomes a headache. Hopefully you’ll find time to iron all that out.
Happy New Year!

1 Like

The mask does image spatial segmentation. You really need to stop trying to make sense out of it using a perceptual framework. What you see is not what you get anyway. Smooth surfaces in the mask will get the same exposure compensation, that’s all it tells you. The actual brightness of those areas doesn’t matter since you can rescale the mask exposure and contrast as you wish and there is no hardcoded threshold. If you sky falls under the -2 EV node, just control it with the the -2 EV node. You want it under the 0 EV node ? Add +2 EV in mask correction. Done ! But it will not change the actual result.

It’s really not important how dark the mask is vs. how dark the original image is. All that matters is the mask follows content edges. Also your measurements with colour pickers make no sense at all, since you are mixing display-referred metrics (the Lab global picker takes the output image at the end of the pipe, after display OETF), and scene-referred ones (the TE picker takes the input image after exposure module).

The behaviour you show is exactly what is expected.

The mask splits the image into contiguous spatial areas based on their lightness/luminance/intensity/whatever. The luminance is just a guide for the guided filter : we basically only care about where edges are located. Then, the values of the mask are mapped to the GUI nodes in a log scale. When you push the exposure of the -2 EV node by +1 EV what you do is tell the software “multiply RGB values by 2 wherever the mask == -2 EV”. But the mask is not used in the actual exposure correction, it’s just a spatial mapping between GUI parameters and areas of the picture, like a parameter lookup if you want.

I think you get hooked on this extra layer of abstraction here. And I get that it’s not easy. I spent almost a year on that thing…

1 Like

Well, let’s start over again.

It does not matter in absolute figures, I totally agree. It doesn’t matter to me which node to manipulate: 0EV or -2EV, indeed. But! What matters is how many nodes I may really use to distinguish between differently lighted areas (the whole thing is about it, isn’t it?). If it’s only 2 nodes available, the module becomes just an exposure module with unobvious interface. Also, it does matter in terms of relative luminance. If areas with quite different luminance fall into the same EV while evenly lighted area differ 4EV in the mask because one point is on the bottom corner of the picture and another is closer to the center, I’d say it only messes things up, because the results are totally unpredictable in this case.

Not exactly. Again, absolute figures don’t matter, in that sense I completely agree. What I was trying to show you is that relatively lighter areas become darker in the mask and visa versa, as if the conversion function wasn’t monotonic. (And yes, I understand that it may locally be as such, because it’s a smoothed 2D construct while pixel luminance single-dimensioned). I hover over the dark wall, for example, and see -3EV and when hovering over lighter area I see -5EV. Then I get confused and go check with DT picker. It is lighter, indeed. Either this means it works erroneously, or I’m not getting at all what TE is developed for and what it’s supposed to achieve. Do I understand correctly that darker picture areas shall generally get lesser EVs in the mask and visa versa? If so, that’s not what I see…

That’s not what I see. Practically it doesn’t work this way (at least, to me). That’s what I keep telling you. Your mask’s bottom corners are always much darker than its top. Even if the original luminance is spread in another way. So in fact they are based rather on something else (position?) but not “lightness/luminance/intensity”. No matter in this case if it’s scene-referred or display-referred. Conversion from linear space to a logarithmic one doesn’t change the relative lightness that is lighter areas still shall stay lighter, and darker shall stay darker. Which is obviously not the case.
Let’s look at this picture

Which I want to become something like this

That is, I want to emphasize the clouds and rays and lighten up the fort’s wall. But the TE picker shows -3EV on the fort wall and the same -3EV on the far yellow building! However it is lighter, it occupies the same node. Which means that when I start to lighten the fort wall, I’ll lighten all the background embankment and some area on the water – because they are all undistinguishable by the TE module – and that’s not what I want! And visa versa – the evenly lighted water gets about -4EV difference toward the corner. What for? Does it have any practical meaning?
Also, I can’t do anything with the clouds and rays – I simply short of nodes to do that. They’re too close in TE’s opinion. So I failed completely with the TE on this picture, and I had to solve this the old way, namely, to use two curves with masks – one for clouds, another for darker wall.
Look, you don’t owe me anything, and it’s up to you to listen to me or not. It’s FOSS eventually, nobody has obligations to fix issues or whatever, I fully accept that.
But if you so sure the TE works correctly, I offer you a Christmas challenge. Here is my RAW. Make it close to pic #2 in this post, that is, lighten the fort wall without lightening other areas, like distinct buildings, and emphasize the clouds. If you are able to so, I promise I won’t bother you anymore with that. And will consider myself deadly stupid from now on)))
20140522_0041.NEF (23.9 MB)
BTW, I’m not sure if you were able to see this and if this makes any sense or not, but JFYI: https://github.com/darktable-org/darktable/issues/3865#issuecomment-569894506
Happy holidays!

Challenge hijacked, if you don’t mind :pirate_flag:

EDIT: Did you mean New Year’s Eve challenge?

I started with local contrast, to pop up the clouds, then I went down to tone equalizer, selected the relight preset, and tweaked it a bit. Just those two modules.

20140522_0041_01.NEF.xmp (8.1 KB) (DT 3.1.0 git 239ff13b)