Registered User
Join Date: Mar 2014
Posts: 308
|
Code:
function kuwahara(clip c, int "radius")
{
function shift(clip c, int x, int y)
{
halfx = int(x/2)
halfy = int(y/2)
c
pointresize(width(), height(), x, y).mergechroma(pointresize(width(), height(), 2*halfx, 2*halfy))
}
function copylumatochroma(clip c)
{
c
bilinearresize(width()/2, height()/2)
ytouv(last, last, c)
}
radius = default(radius, 2)
assert(radius%2 == 0, "kuwahara: radius must be even") # because I'm too lazy to make it work with odd values
r = radius/2
c
assert(isyv12(), "kuwahara: clip must be YV12")
blurred = averageblur(r, floor(r/2)) # r/2 because yv12 has halved chroma resolution
ba = shift(-r, -r)
bb = shift(r, -r)
bc = shift(-r, r)
bd = shift(r, r)
s = mt_luts(last, last, mode = "std", pixels = mt_square(r), expr = "y")
s_min = mt_logic(s.shift(0, r), s.shift(0, -r), "min")
s_min = mt_logic(s_min.shift(r, 0), s_min.shift(-r, 0), "min")
ma = mt_lutxy(s_min, s.shift(-r, -r), "x y == 255 0 ?")
mb = mt_lutxy(s_min, s.shift(r, -r), "x y == 255 0 ?")
mc = mt_lutxy(s_min, s.shift(-r, r), "x y == 255 0 ?")
md = mt_lutxy(s_min, s.shift(r, r), "x y == 255 0 ?")
mtotal = mt_average(mt_average(ma, mb), mt_average(mc, md))
ma = mt_lutxy(ma, mtotal, "x y 64 / /").copylumatochroma()
mb = mt_lutxy(mb, mtotal, "x y 64 / /").copylumatochroma()
mc = mt_lutxy(mc, mtotal, "x y 64 / /").copylumatochroma()
md = mt_lutxy(md, mtotal, "x y 64 / /").copylumatochroma()
raveragem(ba, ma, bb, mb, bc, mc, bd, md, u = 3, v = 3)
radius == 0 ? c : last
}
Disclaimer: just a normal Kuwahara filter (not the multi-scale anisotropic version as linked in the OP), only works on YV12, requires the radius to be even, and may produce incorrect results after the first frame because RAverageM is sort of buggy and unreliable.
Last edited by colours; 25th June 2014 at 10:05.
|