Log in

View Full Version : I need help eliminating some nasty aliasing on a PAL video


Chainmax
29th November 2006, 03:09
I'm currently creating a DVD out of some short films and the one I'm trying now has some VERY nasty aliasing. DGIndex reported the file as interlaced, but the footage seems to be progressive as there is no interlacing at all (which would also rule out the possibility of it being phase shifted or field swapped, right?).

What I need is someone to confirm me wether this is progressive or phase shifted/field swapped and how to get rid of the aliasing. You can download a short sample here (http://www.31012.com/~azulftp/PALSample.demuxed.m2v).


Here's the script I came up with so far:

MPEG2Source("X:\wherever\ashort.d2v")

TFM(d2v="X:\wherever\ashort.d2v",order=0,mode=6,pp=7,slow=2)

Deblock_QED()

a = last
b = a.DeGrainMedian().VagueDenoiser(threshold=0.8, method=1, nsteps=6, chromaT=0.8)
SeeSaw(a,b, NRlimit=6, NRlimit2=7, Sstr=1.5, Slimit=5, Spower=5, SdampLo=6, Szp=16)

AAA()

Crop(2,0,718,576,align=true)

EEDI2().TurnRight().EEDI2().TurnLeft()

Lanczos4Resize(672,544)

dull=last
sharp=dull.LimitedSharpenFaster(SMode=4,Strength=200)
Soothe(sharp,dull,25)

Tweak(sat=1.2)

AddBorders(24,16,24,16)

Levels(0,1,255,16,235)

ConvertToYUY2()

2Bdecided
29th November 2006, 12:33
It looks to me like it was shot interlaced, and then converted to progressive by dumping then duplicating+blurring ever second field. In other words, it's been very cheaply "filmised" (filmic effect).

Dumping every other line (i.e. field) and then using EEDI2 would be my first attempt...

mpeg2source("PALSample.demuxed.d2v")

separatefields()

selectodd()

EEDI2()

selectodd() keeps the "good" fields (i.e. the ones that were probably in the original interlaced video). selecteven() keeps the duplicated, blured fields - not good.

Even with selecteven(), this might look much worse than what you've done - I didn't have all the filters you used here to compare.

Cheers,
David.

Didée
29th November 2006, 13:11
Symptoms are like 2Bdecided said.

Quickly tried that "double-edi" thingy buried in MCBob:

AssumeTFF()
merge(SeparateFields().SelectEven().eedi2(field=1),SeparateFields().SelectOdd().EEDI2(field=0),0.5)

Too lazy right now to post a screenshot, but the result in front of me is smooth as silk. ;)
Could be followed, perhaps, by some "sharpen-up---but-dont-sharpen-more-than-previous-filter-did-blur" filtering.

2Bdecided
29th November 2006, 15:11
That's weird - you're using the "bad" field as well as the "good" one, but it does improve the result. At least, it's softer (because the bad field is soft) but also more stable. Looking at the switch on the microwave, it doesn't seem to wobble as much with your version.

Makes me wonder if EEDI2 can be made generally more stable by running it twice, once with a slightly softened image?! Probably much better ideas abound. I need to read and learn!

Cheers,
David.

Chainmax
29th November 2006, 15:18
Ok, I'll try these suggestions and compare them with my results. Thanks for the answers so far :).

Chainmax
1st December 2006, 01:10
Wow Didée, the suggestion you posted worked wonders :eek:. There might be some very slight remaining aliasing, but it's still much better than my attempt, which was slow as hell and blurred the picture too much because of AAA. It should be much faster as well :). What's the rationale behind it?


[edit]There's some noticeable artifacting on a scene but I guess it's an ok tradeoff.

Chainmax
6th December 2006, 17:03
Didée, you can download two 1s scenes where the artifacting occurs here:

http://rapidshare.com/files/6334520/Artifacting_sample_VOBs.rar.html

Didée
13th December 2006, 22:39
Didée, you can download two 1s scenes where the artifacting occurs here:
Okay, I downloaded. What next?

;)

Reduce 'maxd' to prevent those artefacts. Large search distances for EEDI2 aren't needed in this case. Default is 12, smaller ranges give less artefacts and run faster. '4' should be okay, I've even tried '2' and the anti-aliasing was still intact.


Aliased source:
http://img363.imageshack.us/img363/4835/aliasediy6.th.jpg (http://img363.imageshack.us/my.php?image=aliasediy6.jpg)

DoubleEdi'ed:
http://img221.imageshack.us/img221/2723/doubleedihk4.th.jpg (http://img221.imageshack.us/my.php?image=doubleedihk4.jpg)

DoubleEdi + ContraSharpen:
http://img288.imageshack.us/img288/8771/doubleedisharpxs3.th.jpg (http://img288.imageshack.us/my.php?image=doubleedisharpxs3.jpg)

o = last
AssumeTFF().SeparateFields()
dbl = mt_Average( SelectEven().EEDI2(field=1,maxd=4),
\ SelectOdd() .EEDI2(field=0,maxd=4), U=3,V=3 )
dblD = mt_MakeDiff(o,dbl,U=3,V=3)
shrpD = mt_MakeDiff(dbl,dbl.RemoveGrain(11),U=3,V=3)
DD = shrpD.Repair(dblD,13)

dbl.mt_AddDiff(DD,U=3,V=3)

Terranigma
14th December 2006, 00:56
That Code seems to work very well in conjunction with mcbob (it should be applied afterwards). Is this the sorta thing we can expect from the SoonToCome bobber Didée? :D

Didée
14th December 2006, 01:24
That Code seems to work very well in conjunction with mcbob (it should be applied afterwards).
No. It should be applied during MCBob, not afterwards. ;)

And surprise, basically it is already in v0.3: :p
EdiPost=2 does exactly this, just without the ContraSharpening. (Used is a slight pre-sharpening ... okay for EdiPost=1, but for 2 ^that^ kind of post-sharpening would be better.)

The trick is, when used after MCBob, then you'll change also the original fields. When used within, then the original fields remain unchanged.

Is this the sorta thing we can expect from the SoonToCome bobber
No. That's too cheap. ;)
For many types of realworld sources, this kind of processing is okay and can work out. But for really sharp + highly detailed sources, it takes too much away.

Terranigma
14th December 2006, 01:46
No. It should be applied during MCBob, not afterwards. ;)

And surprise, basically it is already in v0.3: :p
EdiPost=2 does exactly this, just without the ContraSharpening.
Thanks for the positive reply.

How would I go about editing mcbob, so that edipost2 would use ContraSharpening? :D

Chainmax
14th December 2006, 02:26
Thanks Didée :) http://smilies.vidahost.com/otn/wink/thumb.gif.

Didée
14th December 2006, 04:11
How would I go about editing mcbob,
Oh, you're going to make another famous mod? :scared: . . . :D

If result's like this (http://home.arcor.de/dhanselmann/_stuff/MCBob_v03c.avs), then it's OK.

Alain2
14th December 2006, 09:19
If result's like this (http://home.arcor.de/dhanselmann/_stuff/MCBob_v03c.avs), then it's OK.[...]
(EdiPost==2) ? edidouble : last

# ( post-sharpen for EdiPost = 2 )
# ------------------------------------------------------
edidoubleD = mt_makediff(last,edidouble,U=3,V=3)

if EdiPost==2, isn't the second last of the above quote already equal to edidouble ?

Didée
14th December 2006, 13:43
Oops, indeed. Well spot. And two more syntax issues on top of that.
It's corrected now, try again.

Terranigma
14th December 2006, 16:36
Thanks Didée & Alain2 :)


Edit:
I get an error when trying to load version c

wonkey_monkey
14th December 2006, 20:10
Me too:

Script error: '\' can only appear at the beginning or end of a line
(MCBob_v03c.avs, line 39, column 43)

Then after removing leading spaces, I get:

Script error: expected ':'
(MCBob_v03c.avs, line 186, column 0)

David

foxyshadis
15th December 2006, 09:45
line 39: avisynth does not like line-continuation+comments; it's one of the few bugs in the parser. Take the \ out and it'll work.

line 186: add a colon ( : ) to the end of line 184:

diff2prev12= (mtnmode==0) ? diff2prev2 :

wonkey_monkey
15th December 2006, 10:37
Thanks for that. Now I get:

RemoveGrain: invalid mode 20

:(

I also (previously) got an error that because of mt_lut, only YV12 and I420 are allowed. Are we losing out slightly on quality if we can't use YUY2?

David

foxyshadis
15th December 2006, 11:29
You have to update removegrain. Hmm, no wiki so I don't have the link handy, let's see if google does... Ah, http://home.arcor.de/kassandro/RemoveGrain/RemoveGrain.rar

Copy the files in there over your existing plugins. Obviously only copy up to the SSE level your system supports.

Since your source material is 99% probability of being YV12 converted to YUY2 by the decoder, it's very doubtful you'll lose any quality. But make sure you downconvert with interlaced=true! (mcbob should do this automatically, iirc mvbob does.)

wonkey_monkey
15th December 2006, 11:42
Since your source material is 99% probability of being YV12 converted to YUY2 by the decoder,

When I tell you I work at a TV station, you may have to revise your probability ;)

You have to update removegrain.

Bah... I Googled, really, and even found what looked like the RemoveGrain homepage, but I guess it was out of date!

Thanks!

David

foxyshadis
15th December 2006, 13:04
Awesome. If you're willing to alpha-test avisynth 2.6, I could probably make versions of the tools for YV16 instead of YV12. Removegrain, masktools, and eedi2 should all work with a recompile, while mvtools will work now (it appears to not even bother excluding anything - I wonder what happens if you throw RGB at it...).

Terranigma
15th December 2006, 15:50
Huh? YV16 ? :confused:
I thought I new about all the colorspaces :D

MCbob V0.3c; Thanks goes to foxyshadis for having such a keen eyesight, (20/10) :D

# MCBob v0.3:
#
# Another approach to motion compensated bobbing, build by Didée.
#
# ( Between-all-chairs version with some quick hacks )
# ( v0.3c: as stated above, but worse ;-) )
#
# Features:
#
# - No residual combing, due to STT (Shape Transposition Technology)
# - Works without thresholds (with adaptive thresholds instead of fixed ones)
# - Motion Search between fields of same parity, for maximum flicker/bob reduction in motion areas
# - Motion Masking adaptive to local complexity, for maximum flicker/bob reduction in static areas
# - spatial Interpolation overweights spatio-temporal interpolation
# ( in areas where the information obtained from temporal neighbors in itself was only spatially
# interpolated, use a mix of spatial and spatio-temporal interpolation )
# - error correction for temporal interpolation is fully self adaptive
#
# Prerequisites:
#
# - MVTools, preferably v1.4.13 (or newer)
# - MaskTools v2.0
# - EEDI2
# - RemoveGrain/Repair package
# - ReduceFlicker (if temp-NR for ME is used)
# - MedianBlur by tsp

function MCBob(clip clp, float "EdiPre", int "EdiPost", int "blocksize", int "MEdepth", float "sharpness", int "mtnmode", float "mtnth1", float "mtnth2", float "errth1", float "errth2", float "MEspatNR", float "MEtempNR")
{
EdiPre = default( EdiPre, 1.0 ) # What bob to start with: 0.0 = dumbbob, 1.0 = EEdiBob, inbetween = mix of both
EdiPost = default( EdiPost, 1 ) # 0 = no EEDI PP / 1 = Framesized EEdi PP / Average two Fieldbased EEdi PP's
bs = default( blocksize, 16 ) # Blocksize for motion search
me = default( MEdepth, 2 ) # Search effort of motion search
sharpness = (EdiPost==2)
\ ? default( sharpness, 0.7 )
\ : default( sharpness, 1.0 ) # use slight sharpening before STT routine

mtnmode = default( mtnmode, 0 ) # 0 = use only same-parity motion check, 1|2 use an additional
# inter-parity check: 1 = on vertical edges / 2 = not on horizontal edges
mtnth1 = default( mtnth1, 0.20 ) # below this %age of local min/max is static
mtnth2 = default( mtnth2, 0.40 ) # above this %age of local min/max is motion
errth1 = default( errth1, 0.40 ) # similar for error detection
errth2 = default( errth2, 0.60 ) # of motion interpolation errors
MEspatNR = default( MEspatNR, 0.00 ) # amount of spatial NR (for motion search only)
MEtempNR = default( MEtempNR, 0.00 ) # amount of temporal NR (for motion search only)

order = (clp.GetParity == True) ? 0 : 1
ORDR = (order==0) ? "TFF" : "BFF"

ox = clp.width()
oy = clp.height()
ERTH1 = string(errth1)
ERTH2 = string(errth2)
MNTH1 = string(mtnth1)
MNTH2 = string(mtnth2)
SSTR = string(sharpness)
idx_1 = 10
idx_2 = (MEspatNR==0.0 && MEtempNR==0.0) ? idx_1 : idx_1+2
idx_3 = idx_2 + 2


# Create basic operations that we will work with
# ==============================================

# Basic Field & Bob clips
# -----------------------
flatbob = clp.Bob(1,0)
normbob = clp.Bob(0.0,0.5)
ofields = clp.SeparateFields()
oweave = clp.DoubleWeave()
edibobbed = clp.EEDIbob()
bobbed = (EdiPre == 0.0) ? normbob
\ : (EdiPre == 1.0) ? edibobbed
\ : normbob.merge(edibobbed,EdiPre)


# Mask to check if motion compensation has delivered only the neighbor's spatial interpolated part
# ------------------------------------------------------------------------------------------------
black = Blankclip(ofields).mt_lut("0").Trim(1,1).Loop(Framecount(clp))
white = Blankclip(ofields).mt_lut("255").Trim(1,1).Loop(Framecount(clp))
interpol = Interleave(black,white,white,black).AssumeFieldbased().AssumeParity(ORDR).Weave()


# Vertical Edge mask, needed for more safe motion masking
# -------------------------------------------------------
Vedge = bobbed.mt_Edge("1 0 -1 2 0 -2 1 0 -1",0,255,0,255,U=1,V=1)
Vedge2 = Vedge.mt_Inpand(mode="vertical").mt_Inpand(mode="vertical").mt_Expand(mode="vertical").mt_Expand(mode="vertical")
Vedge = mt_Lutxy(Vedge,Vedge2,yexpr="y 2 - 2 * x > x y 2 - 2 * ?") #.mt_Expand()

Hedge = bobbed.mt_Edge("1 2 1 0 0 0 -1 -2 -1",0,255,0,255,U=1,V=1)
Hedge = Hedge.mt_logic(Hedge.temporalsoften(1,255,0,255,2),"max")


# If requested, do flicker reduction before searching motion vectors
# -------------------------------------------------------------------
(MEspatNR==0.0) ? bobbed : bobbed.Merge(bobbed.minblur(2,uv=3),MEspatNR)
(MEtempNR==0.0) ? last : last.Merge(reduceflicker(2),MEtempNR)
srch=last


# Perform Motion Search
# ---------------------
lmbda = 128
pnw = 40
bw_vec2 = srch.SelectEven().MVAnalyse(isb=true, truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1)
fw_vec2 = srch.SelectEven().MVAnalyse(isb=false,truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1)
bw_vec3 = srch.SelectOdd() .MVAnalyse(isb=true, truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1+1)
fw_vec3 = srch.SelectOdd() .MVAnalyse(isb=false,truemotion=false,delta=1,lambda=lmbda,pel=2,searchparam=me,sharp=2,blksize=bs,overlap=1*bs/2,pnew=pnw,idx=idx_1+1)


# Create RAW motion interpolation
# -------------------------------
alt_1 = bobbed.SelectEven().MVFlowInter(bw_vec2,fw_vec2,time=50.0,thSCD1=64*18,thSCD2=227,idx=idx_2)
alt_2 = bobbed.SelectOdd() .MVFlowInter(bw_vec3,fw_vec3,time=50.0,thSCD1=64*18,thSCD2=227,idx=idx_2+1).DuplicateFrame(0)
alt = Interleave(alt_2,alt_1)


# Create motion interpolation of "nothing new" mask
# -------------------------------------------------
interpol_1 = interpol.SelectEven().MVFlowInter(bw_vec2,fw_vec2,time=50.0,thSCD1=64*8,thSCD2=127,idx=idx_3)
interpol_2 = interpol.SelectOdd() .MVFlowInter(bw_vec3,fw_vec3,time=50.0,thSCD1=64*8,thSCD2=127,idx=idx_3+1).DuplicateFrame(0)
interpol_comp= Interleave(interpol_2,interpol_1)
nothing_new = mt_lutxy(interpol,interpol_comp,"x y * 255 / 255 / 1 2 / ^ 160 *")


# Error check of motion interpolation
# ===================================
# Errors that are neutralized by errors in direct vertical neighborhood are not considered, because bob-typical.
# Remaining error is checked against [min,max] of local error to decide if it's valid or not.
#
# Build error mask, neutralize vertical-only errors
# ---------------------------------------------------
altD = mt_Makediff(bobbed,alt,U=3,V=3)
altDmin = altD.mt_Inpand(mode="vertical",U=3,V=3)
altDmin = altDmin.mt_Deflate().mt_Merge(altDmin,Vedge,U=4,V=4)
altDmax = altD.mt_Expand(mode="vertical",U=3,V=3)
altDmax = altDmax.mt_Inflate().mt_Merge(altDmax,Vedge,U=4,V=4)
altDmm = mt_Lutxy(altDmax.mt_Expand(mode="horizontal",U=3,V=3),altDmin.mt_Inpand(mode="horizontal",U=3,V=3),"x y -",U=3,V=3)
altDmm = altDmm.mt_Inflate().mt_Merge(altDmm,Vedge,U=4,V=4)
altD1 = altD .mt_Lutxy(altDmin,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=3,V=3)
altD1 = altD1.mt_Lutxy(altDmax,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=3,V=3)
altD2 = altD.Repair(altD1,1)


# Build correction mask by combining: error mask + "nothing new" mask + a scenechange mask
# ---------------------------------------------------------------------------------------------
corrmask = mt_Lutxy(altD2,altDmm,"x 128 - abs 2 - y 2 + / "+ERTH1+" - "+ERTH2+" "+ERTH1+" - / 255 *",U=3,V=3).mt_Expand(U=3,V=3)
sc = corrmask.BilinearResize(64,64)
sc = mt_LutF(sc,sc,mode="average",expr="x 255 0.6 * > 255 0 ?").PointResize(ox,oy)
corrmask = corrmask.mt_Logic(nothing_new,"max",U=2,V=2)
corrmask = corrmask.mt_Logic(sc,"max",U=2,V=2)


# Create a first bob from motion interpolation, not yet error corrected ...
# -------------------------------------------------------------------------
# ***( temporarily changed ... yet unsure what works best )***

Interleave(bobbed,alt).AssumeParity(ORDR)
SeparateFields().SelectEvery(8,0,3,5,6).Weave()
naked= last
naked2 = last.vinverse(1.6) # flatbob #

naked_mm = naked.mt_Edge("min/max",0,255,0,255,U=1,V=1)
edibb_mm = edibobbed.mt_Edge("min/max",0,255,0,255,U=1,V=1).mt_Expand(mode="vertical")
check2 = mt_LutXY(naked_mm,edibb_mm,"x y / 3 - 5 3 - / 255 *")
corrmask = corrmask.mt_Logic(check2,"max",U=2,V=2)


# ... and build a motion mask from this one.
# ------------------------------------------
# ***( temporarily changed ... tickertapes might suffer. )***

stc = bobbed .removegrain(2)# oweave.removegrain(11)
mm = stc.mt_Edge("min/max",0,255,0,255,U=3,V=3)
# mm = mm .mt_Logic(mm.DuplicateFrame(0),"max",U=3,V=3).mt_Logic(mm.DeleteFrame(0),"max",U=3,V=3)
# max = stc.mt_expand(U=3,V=3)
# max = max.mt_logic(max.Duplicateframe(0),"max",U=3,V=3).mt_logic(max.Duplicateframe(0).Duplicateframe(0),"max",U=3,V=3)
# min = stc.mt_inpand(U=3,V=3)
# min = min.mt_logic(min.Duplicateframe(0),"min",U=3,V=3).mt_logic(min.Duplicateframe(0).Duplicateframe(0),"min",U=3,V=3)
# mm = mt_LutXY(max,min,"x y -",U=3,V=3)
diff2prev1 = mt_LutXY(stc,stc.DuplicateFrame(0),"x y - abs",U=3,V=3)
diff2prev2 = mt_LutXY(stc,stc.DuplicateFrame(0).DuplicateFrame(0),"x y - abs",U=3,V=3)

diff2prev12= (mtnmode==0) ? diff2prev2 :
\ (mtnmode==1) ? diff2prev2 .mt_Merge(diff2prev1,Vedge,U=2,V=2)
\ : diff2prev1 .mt_Merge(diff2prev2,Hedge,U=2,V=2)

motn = diff2prev12.mt_Logic(diff2prev12.DeleteFrame(0),"max",U=3,V=3).mt_Logic(diff2prev12.DeleteFrame(0).DeleteFrame(0),"max",U=3,V=3)
notstatic = mt_LutXY(motn,mm,"x 1 - y 1 + / "+MNTH1+" - "+MNTH2+" "+MNTH1+" - / 255 *",U=3,V=3).mt_Expand(U=3,V=3).mt_Inpand(U=3,V=3)
# notstatic = notstatic.mt_Logic(notstatic.RemoveGrain(4),"max",U=3,V=3).mt_Expand(U=3,V=3).mt_Inpand(U=3,V=3)


# Now do the error correction of the "naked" MC-bob
# -------------------------------------------------
naked .mt_Merge(edibobbed,corrmask,luma=false,U=3,V=3) .Vinverse(2.7-sharpness)
repaired = last


# If requested, sharpen the corrected MC-bob up a little
# ( pre-sharpen for EdiPost = 0 | 1 )
# ------------------------------------------------------
shrpbase = last#.MinBlur(1,1).Merge(RemoveGrain(12,-1),0.23)
shrp = mt_LutXY(shrpbase,shrpbase.RemoveGrain(11,-1),"x x y - abs 16 / 1 1 x y - abs 1 4 / ^ + / ^ 16 * "+SSTR+" * x y - x y - abs 1.3 + / * 1 x y - abs 16 / 1 4 / ^ + / +",U=2,V=2)
# \ .Repair(repaired,1,0)
shrpD = mt_Makediff(shrpbase,shrp)

(sharpness==0.0 || EdiPost==2) ? last : last .mt_Makediff(MergeLuma(shrpD.MinBlur(1,uv=1),shrpD.RemoveGrain(12,-1),0.24),U=2,V=2)


# If requested, do additional PP via EEDI2
# ----------------------------------------
oweave.mt_merge(last,notstatic,luma=false,U=3,V=3)
AssumeTFF()
edisingle = eedi2().LanczosResize(ox,oy,0,-0.5,ox,2*oy+0.001,taps=3)
edidouble = merge(SeparateFields().SelectEven().eedi2(field=1),SeparateFields().SelectOdd().EEDI2(field=0),0.5)
edidoubleD = mt_makediff(last,edidouble,U=3,V=3)
(EdiPost==1) ? edisingle : \
(EdiPost==2) ? edidouble : last

# ( post-sharpen for EdiPost = 2 )
# ------------------------------------------------------
edidoubleshrpD = mt_makediff(edidouble,sharpness==1.0?edidouble.removegrain(20):edidouble.removegrain(20).merge(edidouble,1.0-sharpness),U=3,V=3)
edidoubleshrpD = edidoubleshrpD.repair(edidoubleD,13)
(EdiPost==2) ? edidouble.mt_adddiff(edidoubleshrpD,U=3,V=3) : last


# STT (Shape Transposition Technology) Routine:
# =============================================
# Simply weaving the corrected output with the original fields is bad, because the risk of
# creating unwanted residual combing is too high.
# Instead, the vertical "shape" is taken off the corrected output, and transposed
# onto the fixed "poles" of the original fields' scanlines. Et Voila.
# ----------------------------------------------------------------------------------------
synthbob = last.AssumeParity(ORDR).SeparateFields().SelectEvery(4,0,3).Weave().Bob(1,0)
mapped_new = flatbob.mt_makediff(mt_makediff(synthbob,last,U=3,V=3),U=3,V=3)
newfields = mapped_new.AssumeParity(ORDR).SeparateFields().SelectEvery(4,1,2)
mappedbob = Interleave(ofields,newfields).SelectEvery(4,0,1,3,2).AssumeParity(ORDR).Weave()


# Finally, for static areas use just original fields
# --------------------------------------------------
mappedbob
#bobbed

oweave.mt_merge(last,notstatic.mt_inpand(Y=2,U=2,V=2),luma=false,U=3,V=3)


# Lastly, set correct parity for the bobbed clip
# ----------------------------------------------
(order==0) ? AssumeTFF() : AssumeBFF()

return(last)
}

# ===============================================

############################
# Helper functions below #
############################


## Function EEDIbob, courtesty of scharfis_brain:

# slow, but accurate EEDI-bob, always dumb ;)
# altering maxd changes the search radius for connecting diagonal lines

Function EEDIbob(clip Input, int "maxd")
{
#GetParity(Input) ? Input.SeparateFields().EEDI2(Field = 3, maxd = maxd, pp = 0, estr = 0, dstr = 0, mthresh = 0, vthresh = 0, lthresh = 0) : Input.SeparateFields().EEDI2(Field = 2, maxd = maxd, pp = 0, estr = 0, dstr = 0, mthresh = 0, vthresh = 0, lthresh = 0)
GetParity(Input) ? Input.SeparateFields().EEDI2(Field = 3, maxd = maxd) : Input.SeparateFields().EEDI2(Field = 2, maxd = maxd)

AssumeFrameBased()
GetParity(Input) ? AssumeTFF() : AssumeBFF()
}


# Helper to simplify script
function AssumeParity(clip clp, string "order")
{
order == "TFF" ? clp.assumeTFF() : clp.assumeBFF()
return(last)
}

# Kill Combing Function
function Vinverse(clip clp, float "sstr", int "amnt", int "uv")
{
uv = default(uv,3)
sstr = default(sstr,2.7)
amnt = default(amnt,255)
uv2 = (uv==2) ? 1 : uv
STR = string(sstr)
AMN = string(amnt)
vblur = clp.mt_convolution("1","50 99 50",U=uv,V=uv)
vblurD = mt_makediff(clp,vblur,U=uv2,V=uv2)
Vshrp = mt_lutxy(vblur,vblur.mt_convolution("1","1 4 6 4 1",U=uv2,V=uv2),expr="x x y - "+STR+" * +",U=uv2,V=uv2)
VshrpD = mt_makediff(Vshrp,vblur,U=uv2,V=uv2)
VlimD = mt_lutxy(VshrpD,VblurD,expr="x 128 - y 128 - * 0 < x 128 - abs y 128 - abs < x y ? 128 - 0.25 * 128 + x 128 - abs y 128 - abs < x y ? ?",U=uv2,V=uv2)
mt_adddiff(Vblur,VlimD,U=uv,V=uv)
(amnt>254) ? last : (amnt==0) ? clp : mt_lutxy(clp,last,expr="x "+AMN+" + y < x "+AMN+" + x "+AMN+" - y > x "+AMN+" - y ? ?",U=uv,V=uv)
return(last)
}

# Nifty Gauss/Median combination
function MinBlur(clip clp, int r, int "uv")
{
uv = default(uv,3)
uv2 = (uv==2) ? 1 : uv
rg4 = (uv==3) ? 4 : -1
rg11 = (uv==3) ? 11 : -1
rg20 = (uv==3) ? 20 : -1
medf = (uv==3) ? 1 : -200

RG11D = (r==1) ? mt_makediff(clp,clp.removegrain(11,rg11),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20).removegrain(20,rg20),U=uv2,V=uv2)
RG4D = (r==1) ? mt_makediff(clp,clp.removegrain(4,rg4),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.medianblur(2,2*medf,2*medf),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.medianblur(3,3*medf,3*medf),U=uv2,V=uv2)
DD = mt_lutxy(RG11D,RG4D,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=uv2,V=uv2)
clp.mt_makediff(DD,U=uv,V=uv)
return(last)
}

Didée
15th December 2006, 22:26
Sorry for those errors ... I had corrected all of them and dropped the corrected script online, but obviously something went wrong. A mystery.

BTW, it is absolutly possible to tag [code] additionally with [size=1] ... ;)

Terranigma
15th December 2006, 23:53
BTW, it is absolutly possible to tag [code] additionally with [size=1] ... ;)
Thanks for the tip :)

Adub
16th December 2006, 04:34
Thanks for the new script Didee!

foxyshadis
16th December 2006, 07:02
Huh? YV16 ? :confused:
I thought I new about all the colorspaces :D

Did you know Avisynth supports I420? It's a clone of YV12, with swapped chroma, but no one uses it. :p It only means anything while outputting from avisynth anyway.

The new 2.6 version supports some new formats:
Y8: 4:0:0 (greyscale, good for masks, makes Didée happy)
YV16: 4:2:2 (planar YUY2, makes plugin writers happy)
YV24: 4:4:4 (ie, no downsampled chroma, maybe makes someone happy?)
as well as their I422 and I444 cousins.

You can always hack avisynth to add your own format definitions (like YCoCg or Lab) but that's not very easy. ;_;

Sadly, no higher depth formats yet. (@10, @12, @16) I guess it's too painful to rewrite everything for that. Soon!

danielkun
18th October 2007, 21:53
I tried Dideé's antialiasing code with nnedi and the results seem great (although slower):

double nnedi:
AssumeTFF()
SeparateFields()
merge(SelectEven().nnEDI(dh=true,field=1),SelectOdd().nnEDI(dh=true,field=0),0.5)


with contrasharpening:
o = last
AssumeTFF().SeparateFields()
dbl = mt_Average( SelectEven().nnEDI(dh=true,field=1),
\ SelectOdd() .nnEDI(dh=true,field=0), U=3,V=3 )
dblD = mt_MakeDiff(o,dbl,U=3,V=3)
shrpD = mt_MakeDiff(dbl,dbl.RemoveGrain(11),U=3,V=3)
DD = shrpD.Repair(dblD,13)
dbl.mt_AddDiff(DD,U=3,V=3)

I noticed a couple things:

-When encoding with x264, just the double eedi gives me a much smaller filesize with the same CRF (about 36%), seeing stills of both encodes, the double eedi has a softer picture, because it lost some sharpening, so it's more compressible. It also has better SSIM and PSNR.

-Double eedi (or nnedi) with contrasharpening has more detail, but needs more bitrate, on high motion sources, contrasharpening may not be necessary.

-Using the maxd=4 as suggested with eedi2, didn't give me good results as the defaults, maybe 'cause the jaggies had steppier lines.


Also, with or without contrasharpen, looks pretty smooth, thanks to the field blending.

This worked much better than sangnom, eedi2.turnleft().eedi2().turnright(), mcbob and other methods I tried, and it's not that slow. I'm tempted to use the contrasharp method as my defacto deinterlaced on aliased sources. I wonder if there are cases when this script shouldn't be used.

I have a problem though, I love bobbing, since 60 fps looks silky smooth, and this method blends both fields so it can't be used for bobbing I guess. Mcbob gave me good results but certainly not as good as with the 30fps result (and as dideé pointed, this is done within mcbob)

I wonder what can be done to achieve similar results as double eedi when bobbing, if anyone knows of a good method, I'd be glad to hear it. :)

:thanks: Dideé for this wonderful script, a function or something should be made out of it :)

Terranigma
19th October 2007, 00:43
o = last
AssumeTFF().SeparateFields()
dbl = mt_Average( SelectEven().nnEDI(dh=true,field=1),
\ SelectOdd() .nnEDI(dh=true,field=0), U=3,V=3 )
dblD = mt_MakeDiff(o,dbl,U=3,V=3)
shrpD = mt_MakeDiff(dbl,dbl.RemoveGrain(11),U=3,V=3)
DD = shrpD.Repair(dblD,13)
dbl.mt_AddDiff(DD,U=3,V=3)


Hey, use the nnedi method like this.
c=last
dbl = mt_average(c.nnedi(field=1),c.nnedi(field=0),U=3,V=3)
dblD = mt_makediff(c,dbl,U=3,V=3)
shrpD = mt_makediff(dbl,dbl.removegrain(11),U=3,V=3)
DD = shrpD.repair(dblD,13)
dbl.mt_adddiff(DD,U=3,V=3)

2Bdecided
19th October 2007, 11:10
I have a problem though, I love bobbing, since 60 fps looks silky smooth, and this method blends both fields so it can't be used for bobbing I guess.IIRC the method was originally posted for some "filmised" video which had been created by dropping alternate fields, and duplicate/interpolating the remaining ones. Hence there was no smooth motion - it was 25p with nasty aliasing (due to the missing information from the missing original field).

If you're running it on genuine interlaced video, you're doing a kind of blend. If you want that look, but at double frame rate, maybe a doubleweave in there somewhere can help?

Cheers,
David.

Terranigma
19th October 2007, 14:16
If you're running it on genuine interlaced video, you're doing a kind of blend.
Yes, a blend that first interpolates each field.

danielkun
19th October 2007, 15:02
@terranigma: I forgot tritical suggested that shorter version on its thread, the script seems shorter and cleaner now, thanks.
So, just the double nnedi could be simplified to this?:

merge(nnEDI(field=1),nnEDI(field=0),0.5)



IIRC the method was originally posted for some "filmised" video which had been created by dropping alternate fields, and duplicate/interpolating the remaining ones. Hence there was no smooth motion - it was 25p with nasty aliasing (due to the missing information from the missing original field).

If you're running it on genuine interlaced video, you're doing a kind of blend. If you want that look, but at double frame rate, maybe a doubleweave in there somewhere can help?

Cheers,
David.
Actually I'm using it on hybrid sources and those that seems that were (badly) deinterlaced, then interlaced again at 30fps. I tried lots of methods, including tomsmocomp, yadif, tdeint+eedi, etc. I still saw lots of jaggies, specially on diagonals. This script, since it had field blending and double eedi, solved most of the problems and it had the added effect of making the video seem smoother.

When bobbing (and the bobbed video looked really smooth, definitely real 60fps), even mcbob showed some aliasing (not its fault, but the source's), so I really don't care about the blending-look, but I want to eliminate most of the aliasing when bobbing, I tried sangnom (and sangbob) and it didn't work out.

edit: I have a link of a segment that shows the problem, in case you wanna play with it :)
http://www.sendspace.com/file/nb1yl8

Undead Sega
17th November 2007, 02:41
hi, im really dumb at these things, but can someone tell me what do i need to use this?

like what tools i have to download and what is the actual current script to use to use this wonderful magic wand?

thanks.

Adub
18th November 2007, 06:34
What you need to do what? OH, do you mean do what the title of this thread says? It helps if you read it first. The information is in here, you just have to look.