How best to use a wavelet decomposition to sharpen?

In software such as GIMP or Krita one can obtain a wavelet decomposition of an image. What is the best way to use this decomposition to sharpen the image? I did a search of Google scholar for wavelet sharpening, but I could not find a good reference.

Some methods I have seen:

  1. Duplicating the high frequency layers and editing opacity of the duplicate to taste.

  2. Applying unsharp mask to each layer individually.

  3. There’s a wavelet sharpen plug-in:

I can’t really tell what it is doing. I guess it is applying some variable weight on each level, essentially a more refined version of (1)?

Which one of these should give the best results? I suppose (3)? At best (2) is just crude edge detection, and if you just wanted to use USM on edges there are probably easier ways to do that.

1 Like

Have you seen this?

Yes. The method described in one of those posts with variable weights for the individual detail layers is basically (3).

I recently finished teasing the wavelet_denoise() function from dcraw for my internal image library. I haven’t had the chance to study its specific behavior, but it appears to take a specific threshold value, modify it by a “noise constant” specified by level, and adding or subtracting it from each value. Here’s a link to it:

Yeah, probably a bit more than what you wanted, but the threshold thing might give you some clues about what to do in your workflow.

1 Like

I’d assume 1 or 2 should give you the most pleasing results, since you’d have very fine control over the sharpening. However, the wavlet sharpen works well in my opinion, and is much less work.

If you have GMIC installed, there is Octave Sharpen, which is similar to wavelet sharpen, that I find works well. There is also Richardson Lucy sharpening which is also quite nice.

Thanks. I did not know about Octave sharpening. I searched for a reference and I found this page which has a link to a .pdf describing it and some other sharpening methods:

Also while researching this I came across a nonlinear version of wavelet sharpening called “multiscale median transform.” As a simple example, one usually creates a high pass filter (finest detail in the corresponding wavelet transform) by subtracting a gaussian blurred background layer from the image. If instead you use median blur and do the same thing, you can sharpen without halos/“ringing” artifacts. I found this page which gives a detailed description and examples:

Unfortunately that software is not open source. However the algorithm is dead simple and could be easily implemented in GIMP. Here is a link to an excerpt from the book “Image Processing and Data Analysis: The Multiscale Approach” by Stark, Murtagh, and Bijaoui which describes it.

Thanks. So if I am understanding the code correctly, if we let neutral gray (128) be our “zero point,” the effect of the threshold is to crush everything below the threshold value in absolute value to zero, and then values with absolute value greater than the threshold value are brought closer to zero by exactly the threshold value. I suppose the goal with this is to remove ringing/haloing.

Does anyone know if this is similar to what happens in RawTherapee? Obviously a different wavelet is used, and there is a greater variety of options for adjusting how the mask on each detail level is weighted (in fact an entire tone curve is available), but otherwise it seems fundamentally like the wavelet sharpen plug-in (3) plus this thresholding trick. Is this right?

Look up wavelet shrinkage (basically, denoising using wavelets[1]; when you subtract the denoised from the original, you get sharpening). There are many implementations, derivatives and applications of this. I am sure that many apps inc. RT and dt already use it in some form in several of their modules. I will list a few for now. Please confirm if I am right about these and feel free to add to this list.



  • Smooth [Wavelets] (plugin), or denoise_haar (CLI).


  • Wavelet Denoise that @ggbutcher mentioned, which is what your #3 is based on.

[1] The thing to note is that the denoising, thresholding and weighting is done in wavelet space.


Thank you, that is wonderfully informative. I leave here a nice exposition I found of wavelet denoising in case anyone else is interested:

The paper linked in the post you reference is also quite helpful:


I’m a little rusty, but in the specific case of the GIMP/Krita rudimentary wavelet decompose using multiple Gaussian blurred layers as low pass filters, can’t we threshold equally well in the space domain? This is because the Fourier transform of a Gaussian is still a Gaussian, I think.

I will let the more versed comment on wavelets and their implementations in FLOSS. What I would say is that the wavelet domain is different from the spatial and Fourier ones. Algorithms mix and match techniques, so I cannot comment on GIMP’s or Krita’s. Its devs and users might be able to help with that.

The plot thickens. According to the wiki, the method I described above is actually implement by the contrast by detail level sliders:

So then what is wavelet sharpening doing? Is it just redundant and finer control over the smallest detail layers in a more powerful (Daubechnies) wavelet decomposition?

Sharpening, generally speaking, is the increase in magnitude between the peaks and valleys of the data and so you could say that the contrast between adjacent pixels is being increased. Strictly speaking, contrast and sharpening are different things but they are related. Also, it might just be the name of the module that you are struggling with. Feel free to correct me if I am wrong; I don’t exactly have my thinking cap on today.

Yes, @afre is oh so right.
Personally I sometimes find it difficult to say whether an image is not sharp or it lacks in contrast :frowning: I remember having seen a nice comparison somewhere – if I find it I’ll add the link.

Have fun!
Claes in Lund, Sweden

PS: Not the source I thought of, but still informative

I think you are probably right but I am having a hard time understanding. Generally I think of “sharpening” as increasing accutance or local contrast (e.g. what unsharp mask does), as you said. It seems that both modules attempt to do this. So I am confused about why you think there is a distinction.

For anyone interested, I found a good discussion of the available FLOSS sharpening methods in these slides:


Often method 1 is the best as it’s very easy to make it selective. Just go to a layer where some object is to be sharpened at a particular detail level and paint out the parts that do not want or need it. It can also be worth remembering that detail can also be blurred selectively at the same time by brushing blur selectively.

One advantage of both is that it can be very subtle or extreme as needed,


1 Like