View Single Post
Old 25th June 2014, 10:02   #9  |  Link
colours
Registered User
 
colours's Avatar
 
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.
colours is offline   Reply With Quote