Log in

View Full Version : variable blur 0.4: a gaussian/binomial/average variable radius blur


Pages : [1] 2

tsp
19th January 2005, 23:29
Get version 0.4 here: variableblur (http://www.tsp.person.dk/VariableBlur040.zip)


from the readme:

VariableBlur version 0.4


Variableblur is a gaussian, binomial or average blur filter with a variable radius(variance).
The binomial filter part is based on a paper by Frederick M. Waltz and John W. V. Miller. An efficient algorithm for Gaussian blur using finite-state machines. SPIE Conf. on Machine Vision Systems for Inspection and Metrology VII page 3521-37

The gaussian filter uses fftw version 3(http://www.fftw.org) available from ftp://ftp.fftw.org/pub/fftw/fftw3win32mingw.zip and wouldn't run without it. If you have fft3ffilter or defreq installed you already have it.

Also includes an unsharp mask filter based on the gaussian filter meaning it is fast for big variance.


usage:

binomialBlur(float varY,float varC,int Y,int U,int V,bool usemmx)

binomialBlur works by repeating a 5x5 or 3x3 kernel based on pascals triangle multiple times to blur the image. With a variance above 1 the result is very close to a true gaussian blur and much faster (for variance below ~30).


varY,varC: variance to use. Remember variance=sd^2. The variance is rounded down to the nearest half integer(0.5,1.0,1.5 etc). Radius 1 in version <=0.2 is equal to variance 0.5. Default 1.5

Y,U,V: Controls which planes the filter is applied to. If set to 3 the plane will be filtered, if 2 the plane will be copied from the source, if 1 the plane will be ignored and from 0 to -255 the plane will be assigned the absolute value. Default Y 3,U=2, V=2

useMMX: If true MMX instructions will be used. Default true for variance>1 else false.


averageblur(int radY,int radC,int Y,int U,int V)

averageblur works by taken the average value of the pixels inside the radius.

radY,radC: radius of the kernel. default 3.

Y,U,V: same as binomialblur



gaussianblur(float varY,float varC,int border,bool integrate,int Y,int U,int V)

Gaussianblur works by converting the image to the frequency domain using fftw and complex multiplying it with the gaussian kernel in the frequency domain before converting the result back to the spatial domain
giving the same result as doing a convolution in the spatial domain just faster for large kernelsizes.

varY,varC: Variance to use. This will not be rounded. default 1.5

border: Setup how the border of the image is threated. Posible values:
-255 - 0: the area outside the image is filled with the absolute value
1: Wrap around. The right border will be blured with the left border and the top border with the bottom border. This is the default behaivior when doing convolution in the frequency domain so this will be the fastest option. Default value
2: Don't process borders.
3: fill the area outside the border with the border value. Slowest but produces the nicest result.

integrate: if true the coefficient used will be a mean value of the area the pixel covers. Use this if you consider each pixel to be made of an infinite number of infinite small pixels or if you like the result :-). If integration is used the image will be softer. Default false.

Y,U,V: same as binomialblur



unsharp(float varY,float varC,float strength,int border,bool integrate,int Y,int U,int V)

Sharpens the image using unsharp filtering (http://homepages.inf.ed.ac.uk/rbf/HIPR2/unsharp.htm for an explanation).

strength: Strength of the sharpener best values is between 0(no sharpen) to 1(more sharpen). Values outside this will produce strange results.

Rest of the options is the same as for gaussianblur



Example:

binomialBlur(radY=0.5,RadC=0.5) #nearly the same as Blur(1)



#Unsharpen (it will sharpen the image)

function unsharpen(clip c,float variance,float k)
{
blr=gaussianblur(c,vary=variance,varc=2,Y=3,U=2,V=2,border=1)
return yv12lutxy(blr,c,"y x - "+string(k)+" * y +",y=3,u=2,v=2)
}

Changelog:

0.1 Initial release

0.2 optimization of the gaussian blur (now uses a 5x5 mask instead of 3x3) and the average blur(smarter algorithm resulting in a factor 20 to 100 speed increase)

0.3 GaussianBlur is included old gaussian is renamed to binomialblur.

0.4 Fixed bug with converting float to unsigned char without proper clamping. Also included an unsharp filter and optional integrated gaussian coefficients

License:
This filter is released under GPL se copying.txt

E-Male
19th January 2005, 23:59
good, my try was ran very slow...

Macanudo
20th January 2005, 06:24
tsp,

First of all thanks for the filter. I have been hoping someone would create a variable radius gaussian blur filter.

I am either applying it incorrectly or there is a bug, because when I use either of the following scripts my output is greyscale only.
LoadPlugin("C:\Program Files\AviSynth 2.5\Filters\variableblur.dll")
a=AviSource("C:\boats.avi")
b=a.VariableBlur(radY=6)
return b

or

LoadPlugin("C:\Program Files\AviSynth 2.5\Filters\variableblur.dll")
a=AviSource("C:\boats.avi")
b=a.VariableBlur(radY=6, RadC=6)
return b


I am using Avisynth 2.55.

Edit: I figured it out. I added ConverttoYV12() and it works great.


Thanks Again,
Macanudo

Mug Funky
20th January 2005, 10:19
yeah! i nearly missed this thread :)

glad to finally see a plugin to do this (though i'm not ready to ditch yv12convolution yet, as i can put in any impulse i like here).

will test as soon as possible.

[edit]

the radii for gaussian don't seem to be behaving properly. the blur seems much smaller than average blur.

tsp
20th January 2005, 12:31
it's because a gaussian blur is weaker than an average blur. Remember the weight for the centerpixel is much heigher in gaussian blur compaired to an average blur(where it has the same weight as all the other pixels)
you will see the same if you use yv12convolution with mask 1 1 1 compaired to 1 2 1

rfmmars
20th January 2005, 19:20
Can this filter be made to do the opposite, in other words sharping to correct non flat focus field of lenes use on many 8mm / Super 8mm Home movie cameras and projectors?

richard
photorecall.net

tsp
20th January 2005, 20:11
rfmmars:

You can use the supplied function unsharp (se the readme). But I think you will have to combine it with a circular gradient mask if you only wants to sharpen the periphery of the image(I don't know I I understand the problem correct?). se
this (http://forum.doom9.org/showthread.php?s=&threadid=87791&perpage=20&pagenumber=6) thread how to do that (although they try the reverse, just use a sharpening filter(not necessarily unsharp) instead of a blur.)

rfmmars
20th January 2005, 21:00
This is what I need . No or liitle shaping at center but increasing sharping moving out from the center to the edges both Horz. & Vert.

Maybe with your filter I can do this now.

richard

E-Male
20th January 2005, 21:04
i somehow daubt he'll use the gradient mask maker plug-in

tsp
20th January 2005, 21:48
be aware that this filter uses an iterativ (rad times) 3x3 mask to approximate the gaussian blur meaning some artifact can appear with high radius(although I haven't seen some yet) due to rounding error though not as severe as using blur multiple times.

rfmmars
21st January 2005, 00:02
Don't pay attention to the above poster, he knows nothing about me or what he speaks.

richard
photorecall.net

E-Male
21st January 2005, 00:28
i trust in tsp's and everyone else's judgement not to listen to that

Wilbert
21st January 2005, 00:48
@rfmmars and E-Male,

Could you stop with this nonsense?

E-Male
21st January 2005, 00:57
sorry, i shouldn't have taken this here

rfmmars
21st January 2005, 02:58
All will be quiet........Peace

..................................

tsp...........can the 3x3 matrix be setup for radial sharping in the sourse code?

richard

Didée
21st January 2005, 09:09
Originally posted by rfmmars
Can this filter be made to do the opposite, in other words sharping
Erh ... for that we have UnSharpMask() from the big WarpSharp package, singe ... ages, or so. Welcome back on earth, Richard ;)

rfmmars
21st January 2005, 17:16
Didee........had a good landing........will give WarpSharp package a try.

richard

tsp
24th January 2005, 20:38
rfmmars You can try this script and see if it gives the desired effect:

a=AVISource("G:\pf.avi").converttoyv12()
a.pointresize(440,400)
GraMaMa(1,4,last.width/2,last.height/2,330)
sharpmask=bilinearresize(a.width,a.height)
Overlay(a, a.unsharp(100), mask=sharpmask, mode="blend", opacity=1.0)


Function Unsharp(clip clip,int radius)
{
Blur=VariableBlur(clip,radY=radius,RadC=radius)
blurmask=subtract(Blur,clip)
return subtract(clip,blurmask)
}

you can change unsharp(100) to another sharpener (blur(-1) or WarpSharp)

rfmmars
24th January 2005, 21:06
Thanks for the script.will try as soon as possible.

richard

tsp
24th January 2005, 22:32
updated variableblur to version 0.2 Mainly optimization of the gaussian blur (now uses a 5x5 mask instead of 3x3) and the average blur(smarter algorithm resulting in a factor 20 to 100 speed increase). I'm thinking about renaming the gaussian blur to binomial blur because it works like that. With higher radius it aproaches the true gaussian blur more. With radius = 2 it's closest to a gaussian blur with SD=1 and with radius=7 it's closest to SD=2.

tsp
6th May 2005, 00:39
new version 0.3 . Now includes a "true" gaussian blur

Mug Funky
8th May 2005, 14:33
coolies. it looks pretty good, though the scaling (is that the right term) isn't what i'm used to.

for instance, gaussian blur of radius 16 is a huge blur in photoshop, but a modest one with your plugin.

of course, i can just use higher numbers :)

thanks heaps for the true gaussian blur. it's been a long time coming for the avisynth world, and works pretty good.

Didée
8th May 2005, 22:05
Originally posted by Mug Funky
though the scaling (is that the right term) isn't what i'm used to
for instance, gaussian blur of radius 16 is a huge blur in photoshop, but a modest one with your plugin.
of course, i can just use higher numbers
x' = x^2

, if I'm not fully mistaken.

tsp
8th May 2005, 23:54
Originally posted by Didée
x' = x^2

, if I'm not fully mistaken.

if the radius in photoshop is the standard deviation (sd) then it is correct. The reason I use variance instead of sd is because else the radius in binomial blur would be really odd (like squareroot 2.5) also I changed the old radius to this after the discussion in this (http://forum.doom9.org/showthread.php?s=&threadid=92130&perpage=20&pagenumber=1) thread.

Another thing currently I'm just using this formula to calculate the coefficient:
1/(2*pi*SD^2) * exp(-(x^2+y^2)/(2*SD^2))
but maybe it's more correct to use the mean value for the whole pixel. For instance when calculating the value for the center pixel I just set x=0 and y=0 but wouldn't it be more correct to use the area from x=-0.5 y=-0.5 to x=0.5 y=0.5?

tsp
24th May 2005, 22:50
updated the filter to version 0.4. I fixed a bug when convering to unsigned char from float the result wasn't properly converted if outside the 0-255 range. It includes an unsharp filter for sharpening based on the gassianblur code so you can safely use big variance without affecting speed. I also added an option to use integrated gaussian coefficients.

bartrobinson
12th December 2006, 07:29
You know what would be really cool? If you could adjust the radius based on the luminance of a secondary clip input.

tsp
12th December 2006, 11:39
bartrobinson: you mean the average luma of the second clip or local luma?

Mug Funky
13th December 2006, 05:48
hmm. so you could do fast DOF, huh? or special denoising...

Didée
13th December 2006, 13:45
You know what would be really cool? If you could adjust the radius based on the luminance of a secondary clip input.

bartrobinson: you mean the average luma of the second clip or local luma?

(If you ask me -) not local luma of 1st clip, not average luma of 2nd clip. Local luma of 2nd clip.
Idea is: don't use just one radius for blurring all pixels in a frame, but:
blur each pixel using the radius that is given by luma value of the corresponding pixel in the 2nd clip. I.e. the filter would have two arguments like "min.radius" & "max.radius", and for filtering the 1st clip it would use min.radius where 2nd clip is zero, max.radius where 2nd clip is 255, and inbetween radii for 0<2ndClip<255.

The idea is good (it ever was :D), but I could imagine some problems regarding implementation, or regarding the speed of that filter's performance ... :oh-oh:

krieger2005
13th December 2006, 15:45
Such a filter would be nice. But the main question is: Where to get this second clip with the luma-information? If the Idea is know where to get this second clip it could be implented directly in the plugin, so does not need a second clip...

tsp
13th December 2006, 18:26
It should be possible to modify the binomialblur code so that the radius is dependent on the local luma value. It will be somewhat slower than a normal binomialblur with max.radius. Also only integer values of radius will be supported (this will also apply to the interpolation).

Do you think it will be usefull?

bartrobinson
13th December 2006, 19:34
Luma from second clip. Basically a selective defocus or fake depth of field. Yes, it will likely be a little slow. Why only integer radius? Typically depth passes are in 32bit float (second clip). I'm guessing avisynth doesn't support that, so how about a mode to the filter that loads rgba channels separately and then stacks them for 4x256 levels of depth/luma info or some other similar hack.

tsp
13th December 2006, 20:03
because the binomial blur code works with integer radius (to avoid multiplication in the code). But how strong blur do you need?

Fizick
22nd December 2006, 19:52
One my russian friend (Drakon Rider) reports about some memory leakage with variableblur for big frame sizes 1920x1080, 100 frames eat 2 Gbytes.
img_src size is 4220х3294
I did not test it.


LoadPlugin("VariableBlur.dll")

Function GBlurRange (clip clin, int StartFrame, int EndFrame, float StartBlur, float EndBlur)
{
clip_before=Trim(clin, 0, StartFrame-1)
clip_after=Trim(clin, EndFrame+1, 0)
clip_proc=Trim(clin, StartFrame, EndFrame)

clip_proc=Animate(clip_proc, 0, EndFrame-StartFrame, "gaussianblur", StartBlur,StartBlur,3,false,3,3,3, EndBlur,EndBlur,3,false,3,3,3)

return(clip_before+clip_proc+clip_after)
}

fps=30

src=ImageReader("img_src.bmp",fps=fps)

src=ConvertToYV12(src)

cl01=Crop(src,0,0,1920,1080)

cl02=Trim(cl01,0,fps*4)

cl02=GBlurRange(cl02,0,fps*4,80.0,0.1)

cl03=Trim(cl01, 0, fps)

stt01=BlankClip(cl02,length=fps*5).Subtitle("My Text01", align=8, size=70, first_frame=0, last_frame=fps*5, text_color=$7FFF00, halo_color=$2F2F2F).Coloryuv(levels="tv->pc")
maskstt01=Tweak(stt01,cont=10.0)
stt02=BlankClip(cl02,length=fps*5).Subtitle("Other Text 02", align=2, size=80, first_frame=0, last_frame=fps*5, text_color=$7FFF00, halo_color=$2F2F2F).Coloryuv(levels="tv->pc")
maskstt02=Tweak(stt02,cont=10.0)

cl02=overlay(cl02,stt01,mode="blend",mask=maskstt01)
cl02=overlay(cl02,stt02,mode="blend",mask=maskstt02)

intro=Dissolve(cl02,cl03,fps)
return(intro)

sh0dan
23rd December 2006, 22:49
@tsp: "float *realout;" might need some freeing.

AlanHK
10th February 2007, 16:52
I've got the file:
variableblur_25_dll_20050524.zip

There are no installation instruction in the text file.
I guessed I should put variableblur.dll in Avisynth's plugins directory.
That didn't seem to make the functions active.

The text file mentioned an fftw file as being necessary.
Fetching that, again no installation instructions, or any text at all. So guessing again I get the fftw3.dll file from this and put it also in the Avisynth plugins directory.

Now I get a different error message when calling GaussianBlur

"LoadPlugin: Unable to load p:\Avisynth 2.5\plugins\VariableBlur.dll"

Which seems a step forward, at least the function seems to be known.

Can anyone advise how to install this?

wonkey_monkey
10th February 2007, 17:10
I've been confused by this plugin too; I put variableblur.dll (version 0.4) into the plugins folder, only to find that none of the functions described in the accompanying text file were available. There does seem to be a function called variableblur, but that isn't described in the text file!

David

*.mp4 guy
10th February 2007, 17:42
You need to put fftw.dll in your system rout foulder, for windows xp that would be "C:\WINDOWS\Sytem32\".

Didée
10th July 2008, 23:37
*bump*

Ah, only now I see that the memory leakage of VariableBlur already has been reported.

Any hope to fix that issue? In its current state, VariableBlur is more or less unusable because of the leakage.

(And GaussianBlur is too slow to be a serious replacement, try on 720p or 1080 HD footage...)

Guest
19th August 2008, 14:10
Ah, only now I see that the memory leakage of VariableBlur already has been reported.

Any hope to fix that issue? In its current state, VariableBlur is more or less unusable because of the leakage. I haven't seen tsp in a while, so I made the patch. Try this and let me know how it works.

http://neuron2.net/misc/VariableBlur.dll

Didée
20th August 2008, 12:13
I haven't seen tsp in a while, so I made the patch. Try this and let me know how it works.

http://neuron2.net/misc/VariableBlur.dll

Thanks for giving it a try! Alas, it seems the memory leak is not fixed.

Playing this script in Vdub & eyeballing memory usage in TaskManager:
SetMemoryMax(64)

# LoadPlugin(" ... \VariableBlur_v04.dll")
LoadPlugin(" ... \VariableBlur_memfix1.dll")

ColorBars(pixel_type="YV12")

b1 = BinomialBlur(vary=2.5,varc=2.5,Y=3,U=3,V=3)
b2 = BinomialBlur(vary=3.5,varc=3.5,Y=3,U=3,V=3)
b3 = BinomialBlur(vary=5.5,varc=5.5,Y=3,U=3,V=3)
b4 = BinomialBlur(vary=8.0,varc=8.0,Y=3,U=3,V=3)

merge( merge(b1,b2), merge(b3,b4) )

return( last )
After loading the script, VD occupies ~40.000 K virtual memory.

After ~2000 frames, it's ~200.000 K. After ~8000 frames, it's ~500.000 K, and keeps growing.


All I can guesstimate is that it's related to the "repeated" appliance of the 5x5 kernel filter: when using only small variances (all vary,varc = 1.0, which can be computed with one single instance of a 5x5 kernel), then memory usage consolidates at ~112.000 K after ~700 frames, and doesn't grow any more.

Guest
20th August 2008, 12:53
OK, I'm away on business. I'll fix it up when I return. I didn't test it, just found a new without a delete. I'll do some testing this time.

Guest
23rd August 2008, 06:54
OK, please try again with the same link as above. It climbs at first and then stabilizes.

Didée
30th August 2008, 12:45
Oops, time goes by so fast.

It seems your changes fixed the problem, memory usage is stable now. Thank you very much!

If you could up the changed sources, we could update the common places (Warpenterprises and tsp's page, if we get them).

Guest
30th August 2008, 13:19
If you could up the changed sources, we could update the common places (Warpenterprises and tsp's page, if we get them). See here:

http://neuron2.net/misc/VariableBlur.zip

Thank you for your test results.

45tripp
16th October 2008, 07:50
with variableblur, (both neuron2's last build and tritical's)
calling gaussianblur() and unsharp()
results in the error:
evaluate: system exception - access violation

anyone else get that?

edit:
avisource("blah")
gaussianblur()

Fizick
16th October 2008, 08:29
:script:

Didée
16th October 2008, 09:33
Works fine here. Do you get that error immediately upon loading the script, or at some point during processing?

Poke in the blue - perhaps it's related to fftw3.dll in /system32, resp. to the version of that dll? I vaguely remember that there had been updates of that dll, but then there had been discussions about some problems...
I've an (supposely) older version of it -- file date 2004-01-30, size 1589 kB (Dll does not show a version number in its properties).

45tripp
16th October 2008, 22:14
Works fine here. Do you get that error immediately upon loading the script, or at some point during processing?

immediate


Poke in the blue - perhaps it's related to fftw3.dll in /system32, resp. to the version of that dll?

good guess.
don't remember where i got the one i'd been working with.
it's got a 2008 date.
but the one hosted at warpenterprises works.


ty
tripp

PeaceAnt
29th November 2008, 22:11
You know what would be really cool? If you could adjust the radius based on the luminance of a secondary clip input.

does anybody work upon this filter?

pozdrawiam