Log in

View Full Version : compute a "mean & variance" mask


leon1789
13th August 2011, 23:06
Hello

Let's have a look about this little code : it's compute a mask depanding of local means and variances of two clip v and w.

function mean (clip v)
{
st = "1 1 1 1 1 1 1"
v.mt_convolution(st,st,y=3,u=3,v=3)
}

function variance (clip v)
{
w = v.mean
mt_lutxy(v,w,"x y - 2 ^",y=3,u=3,v=3).mean
}

function mask (clip v, clip w)
{
vv = v.mean
ww = w.mean
mask_mean = mt_lutxy(vv,ww, "y x - 2 ^ 50 *", y=3,u=3,v=3)
vm = merge(v,w).variance
mv = merge(v.variance, w.variance)
mask_var = mt_lutxy(vm,mv, "y x - 2 ^ 50 *", y=3,u=3,v=3)
mt_lutxy(mask_mean, mask_var, "255 x - y -", y=3,u=3,v=3)
}

The problem : this code is quiet slow... Is there a tool to do similar calculus in "high speed way" ?

I will use this function mask in order to merge a source clip (v) with a denoised (w) in order to increase the compressibility of the video (v). For instance
w = v.deen()
m = mask(v, w)
mt_merge(v, w, m, y=3,u=3,v=3)
Any suggestion (about the code or other adea) is welcome.

Thanks!

jmac698
14th August 2011, 00:03
function mean (clip v)
{
v.averageluma
}

Might help. I wrote a correlation in 16bit which needed to compute x*y, (x-y)^2, x^2, y^2, etc., I put them all in global vars, which helps for some reason you'd have to ask someone like Gavino about.
I'm too lazy to analyze your code further right now :)

Didée
14th August 2011, 02:59
The slow part is the 7x7 average via mt_convolution.

Swap it with deen:
function mean (clip v)
{
v.Deen("a2d",3,255,255,min=1.0)
}

Should give roughly 50% more speed, I got 18 fps (mt_convolution) --> 30 fps (Deen) for just the averaging. Downside is that Deen cheats and doesn't filter the "radius" outmost pixels at the very borders, and is by +/- 1 less precise than mt_convolution.

I don't know of a plugin that can do "wide" spatial averages at fast speed. Computing the 7x7 average for every pixel is somewhat costly indeed.


@jmac698: averageluma is a runtime function to compute the average of the complete frame. This doesn't apply for the given case. (And it needs to be used inside ScriptClip /et al.)

cretindesalpes
14th August 2011, 08:58
I don't know of a plugin that can do "wide" spatial averages at fast speed. Computing the 7x7 average for every pixel is somewhat costly indeed.
Actually the average can be computed very quickly and the speed depends only on the perimeter length of the averaged area. To compute the average of the next pixel, add to the sum all the entering pixels and subtract the exiting ones.

This one is a bit faster (90 fps vs 20 fps) and gives the exact result:
Function mean (clip v)
{
v.Dither_convert_8_to_16 ()
Dither_box_filter16 (radius=4, y=3, u=2, v=2)
Dither_box_filter16 (radius=8, y=2, u=3, v=3) # for 4:2:0 chroma subsampling
DitherPost (mode=-1)
}
Could be way faster with a dedicated 8-bit function…

leon1789
14th August 2011, 10:03
Thanks to jmac698

Thanks to Didée : the test with deen("a2d"...) is fine.

cretindesalpes, intéressant ! Where can I found theses functions Dither ? in which dll please ?

cretindesalpes
14th August 2011, 10:29
http://forum.doom9.org/showthread.php?p=1386559#post1386559

leon1789
14th August 2011, 11:05
Thank you.

Yes, it's faster for radius > 2.
Well, I'm going to test it !

Motenai Yoda
14th August 2011, 12:02
mmm.. the average of averages is an average?
'cause removegrain(20) should do a 3x3 average, so 2 istance of rg(20) should do a 5x5 average, maybe...

edit: no it isn't.

Didée
14th August 2011, 20:19
@cretindesalpes -- Oops, I wasn't aware of the box filter in your dither package.:o - Good speed, indeed!