PDA

View Full Version : deinterlace only moving areas -> intellibob


scharfis_brain
12th April 2004, 14:48
I want to present some new Ideas about comb-masking, deinterlacing and matching fields for this process.

At first, you should have a look to some samples:
http://home.arcor.de/scharfis_brain/intellibob/


the script can be found here:
http://home.arcor.de/scharfis_brain/intellibob/intellibob.avs

as you can see, a normal deinterlacer will also deinterlace parts of the image that are moving in the next or prev. field. this is completely avoided with my method.

additional, my deinterlacer doesn't deinterlace the whole image if a scenechange appears. a normal deinterlacer will always deinterlace the whole frame, when a scene chenge appears.

those dlls are required:

masktools.dll
mpeg2dec.dll
kerneldeint140.dll
undot.dll

if you have to use mpeg2dec3.dll (or a derivate) you have to load the plugins in the following order:

masktools.dll
mpeg2dec.dll
mpeg2dec3.dll
kerneldeint140.dll
undot.dll

the parameters:

bool showmask: true shows the combmask and prev/next matching,
false show deinterlaced image (default)

bool fast: false gives higher speed due to half mask size (default),
true gives higher precision

int masktype: 0 uses both, mpeg2dec-mask and my helper mask (default)
-1 only uses the mpeg2dec-mask (this is very fast)
1 only uses the helper mask

string fallback: "prev" gives weaving-dominancy to the previous field
(non moving areas are filled with the previous field)
"next" gives weaving-dominancy to the next field
"both" mixes "next" & "prev" to get some easy kind of noisereduction
in this mode, mixed areas are show grey, when showmask=true
"auto" does a matching, which of both neighboring fields has the bigger influence on
the current field. then it chooses between "next" "prev" and "both" automatically
"both" is choosen when the difference between both neighboring fields falls under
fallbackth*100 percent.

float fallbackth has a default value of 0.2 (20% percent)

bool old: this paramter is for comparing purposes.
if true, it 'simulates' a normal deinterlacer
default=false

int smtth: this defines the deinterlacing threshold of the mpeg2dec.dll mask.
default is 5. lower values are deinterlacing more, higher values are doing lesser
deinterlacing.


what do you think about this deinterlacing strategy?

I think it is close to the kassandro's sentence
"no motion no change"

scharfis_brain
12th April 2004, 16:17
f***, forgot to include the example-pics...

please scroll up.

Mug Funky
12th April 2004, 17:15
does this need the latest masktools? i've got version 1.4142, and motionmask seems to be asking for yuy2 data.

scharfis_brain
12th April 2004, 18:02
oh forgot to say that:
you have to apply

converttoyuy2(interlaced=true)

before calling intellibob()

this error of motionmask, you're receiving is coming from mpeg2dec.dll.
It is not from masktools!

Thats why I've asked in avisynth Dev. for the dllname_functionname syntax :)

Mug Funky
12th April 2004, 18:50
hmm... doesn't seem to like my video (PAL DV, interlaced of course.)

i get chunks left behind.

scharfis_brain
12th April 2004, 20:45
It is not really usable for now, because of its really crappy comb-mask. I haven't found a good one jet.

But try to set smtth to a value of 3.

did you use sequence like this?

avisource("dv.avi")
assumebff()
converttoyuv2(interlaced=true)
intellibob(smtth=3)


if it doesn't help, could you make an interlaced XVid out of your problematic sequence?
Quant 3.5, some secs, 480 pixels hor. res., vert. res untouched., nosound, some secs, not more than 6 MB filesize

Mug Funky
13th April 2004, 14:36
hmm. i'm off to canberra for a couple days, so i won't be playing too much. but i'll definitely play with the parameters some.

i'm going to post a thread challenging people to think up a usable comb mask.

what properties do you need out of a comb mask? simply isolating high vertical freqs that change over frames? i think i've got something lying around, but i'm not sure whether it's useful at all or not.

onesoul
16th April 2004, 03:25
Originally posted by scharfis_brain
as you can see, a normal deinterlacer will also deinterlace parts of the image that are moving in the next or prev. field. this is completely avoided with my method. Don't you mean a normal deinterlacer will also deinterlace parts that aren't moving...?

scharfis_brain
16th April 2004, 06:57
jep.

Audionut
15th September 2004, 02:17
Ok, I'm trying to get restore24 to work.

This is the script that I am using.

import("c:\x\avs-scripts\restore24.avs")
import("c:\x\avs-scripts\intellibob.avs")
LoadPlugin("C:\x\masktools.dll")
LoadPlugin("C:\x\tcombmask.dll")
LoadPlugin("C:\x\kerneldeint140.dll")
LoadPlugin("C:\x\tomsmocomp.dll")
LoadPlugin("C:\x\avisynth_c.dll")
loadcplugin("C:\x\c\smartdecimate.dll")
loadcplugin("C:\x\c\ibob.dll")
LoadPlugin("C:\x\DGDecode.dll")
LoadPlugin("C:\x\undot.dll")

Mpeg2Source("C:\DVD_VI~1\VIDEO_TS\test.d2v")

AssumeTFF()
converttoyuy2(interlaced=true)
a2=kernelbob()
b2=intellibob()
restore24(a2, b2)

This gives me an error message.

Motionmask does not have an argument "fast"
intellibob.avs, line 62.

Thanks in advance.

Audionut
15th September 2004, 02:21
I deleted fast=fast from lines 62 and 63.

Which produced the error message, motionmask needs yv12.

Added converttoyv12 in lines 62 and 63.

Lines 62,63 are now like this.

evn = b.converttoyv12.motionmask(3,smtth).converttoyv12
odd = b.doubleweave.selectodd.converttoyv12.motionmask(3,smtth).converttoyv12

is this ok?

edit: the script loads into vdub, holy crap it's slow.

scharfis_brain
15th September 2004, 05:46
audionut: this looks like old bobmatcher-code with mpeg2dec's motionmask-function.
this bobmatcher shouldn't be used anymore, also this function motionmask has nothin in common with masktools' motionmask.
so either use intellibob or tdeint.
I will not warm up that old bobmatcher

scharfis_brain
15th September 2004, 06:02
ah shit .
I forgt that I had also an intellibob with mpeg2dec.dll. shit.

function intellibob(clip b, bool "showmask", string "fallback", float "fallbackth", bool "old", int "mthl", int "mthc", int "athl", int "athc", int "preset", bool "edge", bool "hardmatch")
{
preset = default(preset,0)

# preset = 0 : settings for fieldblended video with a framerate-ratio higher than 2
# preset =! 0 : settings for normal interlaced video.

# framerate ratio:
# Fieldblended Film in PAL-Video has 24 fps blended into 50 fps
# ratio = 50/24 = 2.08 => choose preset 0
# Fieldblended NTSC-Video in PAL-Video has 60fps blended into 50fps
# ratio = 50/60 = 0.83 => choose preset 1
# fieldblended PAL-Film in NTSC-Video has 25fps blended into 60fps
# ratio = 60/25 = 2.40 => choose preset 0
# fieldblended PAL-Video in NTSC-Video has 50fps blended into 60fps
# ratio = 60/50 = 1.20 => choose preset 1
# normal interlaced Video has a ratio of 1 => choose preset 1

showmask =(preset==0) ? default(showmask, false) : default(showmask, false)
fallback =(preset==0) ? default(fallback,"auto") : default(fallback, "prev")
fallbackth =(preset==0) ? default(fallbackth, 0.3) : default(fallbackth, 0.0)
old =(preset==0) ? default(old,true) : default(old,true)
mthl =(preset==0) ? default(mthl,4) : default(mthl,4)
mthc =(preset==0) ? default(mthc,4) : default(mthc,4)
athl =(preset==0) ? default(athl,5) : default(athl,3)
athc =(preset==0) ? default(athc,5) : default(athc,3)
edge =(preset==0) ? default(edge,false) : default(edge,true)
hardmatch =(preset==0) ? default(hardmatch,true) : default(hardmatch,true)

global p=fallbackth


### create trictical-mask
tte=b.tcombmask(lcLinked=true,mthreshL=mthl,mthreshC=mthc,athreshL=athl,athreshC=athc)
tto=b.doubleweave().selectodd().tcombmask(lcLinked=true,mthreshL=mthl,mthreshC=mthc,athreshL=athl,athreshC=athc)
tt=interleave(tte,tto)
tt=tt.converttoyv12(interlaced=true).blur(1.58).blur(1.58).blur(1.58)
global mix=tt.binarize(5) #.greyscale()

### set some values for kerneldeinterlacing and visualization
c=24
kth=6

b = showmask ? b.greyscale : b

### building previous-field kernel-interpolated bobbed clip
bobx1 = edge ? b.tomsbobsoft1() : b.kernelbob(th=kth)
bobx1 = showmask ? bobx1.coloryuv(gain_u=c) : bobx1

### building next-field kernel-interpolated bobbed clip
bobx2 = edge ? b.tomsbobsoft1() : b.separatefields().reverse().weave().kernelbob(th=kth).reverse()
bobx2 = showmask ? bobx2.coloryuv(gain_u=c) : bobx2

### building doubleweaved clips
douw1 = showmask ? b.doubleweave().coloryuv(gain_v=c) : b.doubleweave()
douw2 = showmask ? b.doubleweave().duplicateframe(0).coloryuv(gain_v=-c) : douw1.duplicateframe(0)



### doing the deinterlacing:

# oneway method (old, like bobmatcher)
global deint1=overlay(bobx1,douw2,mask=mix.duplicateframe(0))
global deint3=overlay(bobx2,douw1,mask=mix)
global deint5=overlay(deint1,deint3,opacity=0.5) #.subtitle(" both")

# twoway method (new, pixelwise)
deint2a=overlay(bobx2,douw2,mask=mix.duplicateframe(0))
global deint2=overlay(deint2a,douw1,mask=mix) #.subtitle("prev")
deint4a=overlay(bobx1,douw1,mask=mix)
global deint4=overlay(deint4a,douw2,mask=mix.duplicateframe(0)) #.subtitle(" next")
global deint6=overlay(deint2,deint4,opacity=0.5) #.subtitle(" both")


### doing the per-frame matching like bobmatcher does, to avoid false deinterlacing

# twoway method
wn1 = ScriptClip(blankclip(douw1), "outx")
wn6 = FrameEvaluate(wn1,"global outx = ((AL1*(1+p) > AL2) && (AL2 > AL1*(1-p))) ? deint6 : (AL1 > AL2) ? deint2 : deint4")
wn9 = Frameevaluate(wn6,"global AL1 = 255-averageluma(mix.duplicateframe(0))")
outnewauto = Frameevaluate(wn9,"global AL2 = 255-averageluma(mix)")

# oneway method
wo1 = ScriptClip(blankclip(douw1), "outy")
wo6 = FrameEvaluate(wo1,"global outy = ((AL1*(1+p) > AL2) && (AL2 > AL1*(1-p))) ? deint5 : (AL1 > AL2) ? deint3 : deint1")
wo9 = Frameevaluate(wo6,"global AL1 = 255-averageluma(mix.duplicateframe(0))")
outoldauto = Frameevaluate(wo9,"global AL2 = 255-averageluma(mix)")


### modi-selection at the end of the script:
outnew = (fallback=="prev") ? deint2 : (fallback=="next") ? deint4 : (fallback=="both") ? deint6 : outnewauto
outold = (fallback=="prev") ? deint3 : (fallback=="next") ? deint1 : (fallback=="both") ? deint5 : outoldauto
out = (old==true) ? outold : outnew
# out = stackhorizontal(outold,outnew)
x = out.subtitle("green = prev. | red = next | blue = curr. | grey = prev. & next")
outbob = showmask ? overlay(out,x,opacity=0.2) : out
outtel = showmask ? b.doubletelecide().subtitle("fieldmatched") : b.doubletelecide()
outtel = outtel.duplicateframe(0)

out = hardmatch ? conditionalfilter(outtel.greyscale(),outtel,outbob,"iscombed(6)","==","false") : outbob

return out
}

function tmcbob(clip a)
{
f=a.tomsmocomp(-1,5,0)
e=a.doubleweave().selectodd().tomsmocomp(-1,5,0)
interleave(f,e).assumeframebased
}


function kernelbob(clip a, int "th",bool "mask")
{ mask=default(mask,false)
th=default(th,5)
ord = getparity(a) ? 1 : 0
f=a.kerneldeint(order=ord, sharp=true, twoway=false, threshold=th,map=mask)
e=a.separatefields.trim(1,0).weave.kerneldeint(order=1-ord, sharp=true, twoway=false, threshold=th,map=mask)
interleave(f,e).assumeframebased
}


### Analyse bobbers for Restore24

function r24kernelbob(clip a, int "th",bool "mask")
{ mask=default(mask,false)
th=default(th,0)
ord = getparity(a) ? 1 : 0
f=a.kerneldeint(order=ord, sharp=false, twoway=true, threshold=th,map=mask)
e=a.separatefields.trim(1,0).weave.kerneldeint(order=1-ord, sharp=false, twoway=true, threshold=th,map=mask)
interleave(f,e).assumeframebased
}

function Tomsbobsoft(clip c)
{ input=c.separatefields.tomsmocomp(1,-1,1)
a = getparity(input) ? input.selectodd : input.selecteven
b = getparity(input) ? input.selecteven : input.selectodd
a=stackvertical(a.crop(0,0,0,1-a.height),a.crop(0,0,0,-1))
output = getparity(input) ? interleave(b,a) : interleave(a,b)
output.assumeframebased
}

function Tomsbobsoft1(clip c)
{ input=c.separatefields.tomsmocomp(1,-1,0)
a = getparity(input) ? input.selectodd : input.selecteven
b = getparity(input) ? input.selecteven : input.selectodd
a=stackvertical(a.crop(0,0,0,1-a.height),a.crop(0,0,0,-1))
output = getparity(input) ? interleave(b,a) : interleave(a,b)
output.assumeframebased
}

function DoubleTelecide(clip c)
{ order = (c.getparity==true)? 1 : 0
odd = c.doubleweave().selectodd().telecide(order=1-order,guide=1,post=0)
even = c.telecide(order=order,guide=1,post=0)
interleave(even,odd)
}