Wavelet Noise Reduction filter for VirtualDub and AviSynth

Version 0.1
thejam

Introduction

This is a wavelet noise reduction filter.
It can remove single-frequency noise in three different frequency bands, independently for X- and Y-direction and for the Y, Cr and Cb color plane.
The picture is analysed for all frequencies present, and those about the given threshold are cut off.
In a video there normally is no single frequency present with an amplitude higher than the rest, almost always this is a kind of noise, making the filter quite robust against producing artifacts.

Sounds complicated? Let's give an example:
Suppose you have a picture with a interference pattern showing as wide vertical bars (e.g. when the cable between VCR and TV is badly mounted or an interference with the power grid).
Then the luminance is going up and down with a defined frequency, i.e. the horizontal distance between two bars is always equal. All the other ups and downs in luminance are the picture information which is quite likely to be random. So when plotting all frequencies against their amplitude there is a background and one peek coming from the interference. This peak is clipped by the filter.

Another example are macroblocks from a bad mpeg-conversion. There too you have blocks with 4, 8 or 16 pixels which represent distinct frequencies.

Requirements

A CPU with MMX and SSE
Height and width must be a multiple of 8 (else a blank clip is returned).


WNR parameters

Filter enable: switches the filter on and off

Show selected plane: Together with Mode = Normal or High only the selected color plane is displayed.

Mode:
- Normal = shows the filtered image
- High = shows the strongest frequencies, which are either contours (which shall be kept) and the noise (which you want to filter)
- Diff = shows the difference between the picture before and after filtering (Show selected plane is igored)

Threshold:
For each plane, each direction and three frequencies you can define the threshold above which the filter will clip the frequency.
0 is the highest frequency corresponding to a peak-to-peak distance of 8-16 pixels.
1 is the mid frequency, 16-32 pixel.
2 is the low frequency, 32-64 pixel.

There is a bug so you cannot enter the numbers directly but have to use the sliders.

How To set the threshold values

1. Show Preview
2. Switch to Mode = High
3. Now do the following for each slider on each color plan seperately, always reset all other sliders on the same plane to 0.
Move the slider to 1 (you can use the arrow keys). You see contours and (maybe) the noise. Now increase the value until the noise vanishes, but only minimal changes to the contours arise. If there are no visible changes as you move to 255 let that threshold at 0.
Remember that value and continue for all other sliders.
4. Set all remembered (or better written) values and switch back to Mode = Normal, Show selected plane not checked.

As the filter is quite mild you can put it more than once in the filter chain.


Using with AviSynth

Method 1 (quite non-standard - loading as native AviSynth plugin, but running in YUY2):

Save the processing settings from VirtualDub in a .VCF-file (e.g. my_settings.vcf). There must be two lines like:

VirtualDub.video.filters.Add("wavelet noise reduction (0.1)");
VirtualDub.video.filters.instance[0].Config(0,0,0,0,0,0,0,0,0);

Now make a script file like:

LoadPlugin("...path.../wnr.vdf")
...
WNR(".../my_settings.vcf")

The first settings which are found in the .VCF are used.
This way only YUY2-format is supported.

Method 2 (loading as VirtualDub plugin, RGB32-only but you can enter the thresholds directly):

Make a script file like:

LoadVirtualDubPlugin("...path.../wnr.vdf", "WNR", 0)
...
WNR(Y_X0*256+Y_Y0, Y_X1*256+Y_Y1, Y_X2*256+Y_Y2, Cb_X0*256+Cb_Y0, Cb_X1*256+Cb_Y1, Cb_X2*256+Cb_Y2, Cb_X0*256+Cr_Y0, Cr_X1*256+Cr_Y1, Cr_X2*256+Cr_Y2)
# here replacing the variables with your thresholds

# which is of course the same as copying the number from the .VCF-file

This way only RGB32-format is supported.


Interlaced video, processing speed:

For interlaced video Y0, Y1, Y2 must be set to 0 to avoid problems.
If there is noise in the Y-direction and you have to use non-ß-values you must use (in VitualDub):

deinterlace(mode: unfold)
WNR
deinterlace(mode: fold)

as with all other filters not designed to work with interlaced video natively.

In AviSynth you can use:

SeperateFields()
WNR(....)
Weave
()

All thresholds which are set to 0 take no processing time. But the filter is quite fast anyway.


This help-file is written by WarpEnterprises.

 

Hosted by uCoz