Log in

View Full Version : New (sort of) version of lanczosplus (interpolator)


*.mp4 guy
7th April 2008, 07:11
I have reworked an old version of lanczosplus, It now gets very similar results to the best version I have (never posted, was way to slow), but is faster, probably even fast enough to be usable. ;)

I would also like to thank everyone that contributed to the last thread, your help was indispensable.

function Lanczosplusv3( clip c, int "dx", int "dy", int "thresh", int "thresh2", float "aa2s",
\ float "sharp1", float "sharp2", float "blur1", float "blur2",
\ int "mtaps1", int "mtaps2", int "ttaps", int "ltaps", float "cstr",
\ int "depth", float "wthresh", float "wblur", float "aa", float "aa2")
{

# Requires : Masktools 2; Frfun7; fft3dfilter; aWarpsharp

# Instructions : This function performs best when enlarging by a factor of 2,
# performance degrades steadily the when enlarging by significantly larger or smaller factors
# if you have extensive aliasing in the resized image, experiment with aa values of 1.01-2.01,
# and aa2 values of 8-16, cstr varies the strength of sharpening, halo reduction and ringing
# cuncurrently, higher values add more sharpening and halo reduction, etc.
# for more exact control use the sharp1/2 and blur1/2 values
# the other valuse defaults are genearlly optimal, but feel free to experiment and report results

# note that if your source is blurry, the line detection routines will not work, and the interpolated
# picture will be blurry aswell, there is no way around this, if blurry things are treated like lines
# then artifacts will be created on gradients, and out of focus areas

# example usage : lanczosplus(1280, 720, cstr=1.5, depth=3)

dx = default(dx, c.width*2)
dy = default(dy, c.height*2)
cstr = default(cstr, 1.33)
thresh = default(thresh, 0)
thresh2 = Default(thresh2, ((thresh+1)*(thresh+1))*64/(thresh+1))
sharp1 = default(sharp1, cstr*0.125)
sharp2 = default(sharp2, cstr*1.0)
blur1 = default(blur1, cstr*0.5)
blur2 = default(blur2, cstr*0.25)
mtaps1 = default(mtaps1, 1)
mtaps2 = default(mtaps2, 1)
ttaps = default(ttaps, 3)
ltaps = default(ltaps, 7)
depth = default(depth, 3)
wthresh = default(wthresh, 0.70)
wblur = default(wblur, 1)
aa = default(aa, 0)
aa2 = default(aa2, 0)
aa2s = default(aa2s, 0)


c
s = c

fd1 = lanczosresize(c, dx, dy, taps=mtaps1)
fre1 = fd1.lanczosresize( c.width, c.height, taps=mtaps1)
fre2 = fre1.lanczosresize( c.width/2, c.height/2, taps=mtaps1).lanczosresize( c.width, c.height, taps=mtaps1)
m1 = mt_lutxy(fre1, s, "x y - abs "+string(thresh)+" - "+string(thresh2)+" *", u=0, v=0)
m2 = lanczosresize(lanczosresize(frfun7(m1, 2.01, 256, 256), c.width/2, c.height/2, taps=ttaps), \
dx, dy, taps=ttaps)

d = c#mt_merge(c, fre2, m1, u=0, v=0)
d2 = d.lanczosresize(dx, dy, taps=ttaps)
d3 = lanczosresize(lanczosresize(d, (c.width)-(width/2), (c.height)-(height/2), taps=ttaps), \
d2.width, d2.height, taps=ttaps)
d4 = mt_merge( mt_lutxy(d2, d3 , "x y - "+string(sharp1)+" * x +" , u=0, v=0), \
mt_lutxy(d2, d3 , "y x - "+string(blur1)+" * x +" , u=0, v=0), m2, u=0, v=0)
d5 = d4.lanczosresize(d.width, d.height, taps=ttaps)

e = mt_merge(d5, c, m1).lanczosresize(dx, dy, taps=ltaps)
e = aa >= 0.1 ? e.frfun7(aa, 256, 256) : e
e = aa2 >= 0.1 ? e.fft3dfilter(bw=36, bh=36, ow=18, oh=18, bt=1, sigma=aa2, plane=0, sharpen=aa2s) : e
e = e.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e = e.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e = e.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e = e.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)


fd12 = lanczosresize(e, e.width*(dx/c.width), e.height*(dy/c.height), taps=mtaps2)
fre12 = fd12.lanczosresize( e.width, e.height, taps=mtaps2)
fre22 = fre12.lanczosresize( e.width/2, e.height/2, taps=mtaps2).lanczosresize( e.width, e.height, taps=mtaps2)
m12 = mt_lutxy(fre12, e, "x y - abs "+string(thresh)+" - "+string(thresh2*1)+" *", u=0, v=0)
m12 = m12.lanczosresize( e.width/2, e.height/2, taps=mtaps2).lanczosresize( e.width, e.height, taps=mtaps2)


e2 = lanczosresize(lanczosresize(e, (c.width)-(width/2), (c.height)-(height/2), taps=ltaps), \
e.width, e.height, taps=ltaps)
e2 = e2.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e2 = e2.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e2 = e2.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e2 = e2.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)

e3 = mt_merge( mt_lutxy(e, e2 , "y x - "+string(blur2)+" * x +" , u=0, v=0), \
mt_lutxy(e, e2 , "x y - "+string(sharp2)+" * x +" , u=0, v=0), \
m12, u=0, v=0)
e3 = e3.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e3 = e3.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e3 = e3.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)
e3 = e3.awarpsharp(depth=depth, cm=0, blurlevel=wblur, thresh=wthresh)

#aux= c.bilinearresize(dx, dy)
#e = e3.vaguedenoiser(wiener=true, wavelet=1, nsteps=9, auxclip=aux, wratio=2, chromat=2, threshold=3)

mt_merge(d4, e3, m2, u=0, v=0)
mergechroma(spline36resize(c, dx, dy), 1)

return(last)
}

[edit] updated script description

*.mp4 guy
7th April 2008, 07:12
spot reserved.

Atak_Snajpera
7th April 2008, 19:00
Any examples? 1080->720

buzzqw
7th April 2008, 19:28
Any examples? 1080->720

look here

Instructions : This function performs best when enlarging by a factor of 2,

BHH

Dark Shikari
7th April 2008, 19:49
If its primarily made for resizing up by a factor of 2, what benefit does this give over NNEDIresize?

*.mp4 guy
7th April 2008, 23:35
If its primarily made for resizing up by a factor of 2, what benefit does this give over NNEDIresize?

Faster, sharper, more natural looking on film content, but it usually does alias more, lines are also thinner.

[edit]
lanczosplus: clown (http://img338.imageshack.us/img338/3476/clownlzp4xja8.png), Bricks (http://img214.imageshack.us/img214/5122/brickslzp2xac3.png)
nnedi: clown (http://img384.imageshack.us/img384/7483/clownnnedi4xlf5.png), Bricks (http://img384.imageshack.us/img384/2828/bricksnnedi2xmq2.png)

note that nnedi has a subpixel shift, which is why the images do not line up perfectly.

unskinnyboy
8th April 2008, 01:21
Faster, sharper, more natural looking on film content, but it usually does alias more, lines are also thinner.

[edit]
lanczosplus: clown (http://img338.imageshack.us/img338/3476/clownlzp4xja8.png), Bricks (http://img214.imageshack.us/img214/5122/brickslzp2xac3.png)
nnedi: clown (http://img384.imageshack.us/img384/7483/clownnnedi4xlf5.png), Bricks (http://img384.imageshack.us/img384/2828/bricksnnedi2xmq2.png)

note that nnedi has a subpixel shift, which is why the images do not line up perfectly.

Are both examples FiLM? I find nnedi much better in this comparison - lanczosplus has strong aliasing, resulting in an oil paint look. nnedi looks more natural. Can you tweak your aa, aa2, cstr values to match nnedi, or this is it?

Nagisa_chan
8th April 2008, 01:42
nnedi dont have aliasing... for me, is best than lanczosplus....

i am novice :D

MfA
8th April 2008, 04:16
Linear interpolators with negative taps throw in some (un)sharpening with their interpolation, NNEDI doesn't (it's intended to be used with non blurred pixels from fields after all). With this kind of use NNEDI will always give a less sharp result, but you can always sharpen it up.

*.mp4 guy
8th April 2008, 13:15
Linear interpolators with negative taps throw in some (un)sharpening with their interpolation, NNEDI doesn't (it's intended to be used with non blurred pixels from fields after all). With this kind of use NNEDI will always give a less sharp result, but you can always sharpen it up.

Well, no you can't actually, sharpening nnedi just emphasizes how thick the lines are, believe me, I've tried. Not to mention, that unfortunately nnedi is never completely free of aliasing, so sharpening will always reveal further artifacts, that are often hidden by the blur.

To address the other questions, the default settings were used on both images, iirc I might have lowered depth slightly for the clown image, because its a 4x upsize, with aa its possible to have less aliasing then nnedi, while maintaining thinner, lines, but detail gets destroyed (not that much wore then nnedi, on cartoons/cg, but pretty horrible for well defined texture, like the bricks image); its only really worth it on anime or cg, imo.

Anyway, I'm not here to convince you to use it, test it for yourself, no need to tweak anything, just lanczosplus() is fine.

WorBry
8th April 2008, 15:56
Nnediresize_YV12() and a light LimitedSharpen (with or without further internal resizing) looks cleaner and more natural to me, at least for upscaling my MCBobbed 50p and pseudo-progressive 25p (frame mode) DV sources. LanczosPLus shows more aliasing and ringing.

Incidentally, I wonder if any one has compared these upsizing routines with commercial applications, like Red Giant's Instant HD? Unfortunately, I dont have AfterEffects and so cant test myself.

Prettz
11th April 2008, 16:05
Lanczosplus definitely looks sharper, and I think slightly better overall, but it's too bad about that aliasing. Also, in the clown image, check out those ringing artifacts around the lightpost. It's not that noticeable, but could result in some very unfortunate side effects once it's time to encode.