Log in

View Full Version : Help me restoring this video


manusse
10th December 2008, 21:20
Hi,

I'd like to restore a home video from an old VHS tape (family camcorder). I'm especially interested in color correction and in removing the colored zebras that seem to be superimposed on the video. Any idea someone?

http://img211.imageshack.us/img211/8439/vhseg7.th.jpg (http://img211.imageshack.us/my.php?image=vhseg7.jpg)

A sample (recompressed to XVID, source is mpeg2) is available here (http://rapidshare.com/files/172171717/vhs.avi.html).

Thanks in advance
Manusse

AVIL
10th December 2008, 23:23
Hi,

Try this script (need version 2.3.0 of mvtools2):

setmemorymax(256)

Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\corrector.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\mvtools2.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\mt_masktools-25.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\ssetools.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\nnedi.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\removegrain.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\yadifmod.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\fft3dfilter.dll")
Loadplugin("D:\Mis documentos\MiSoft\MULTIMEDIA\Video\Proceso_edicion\Avisynth\plugins2\Average_24Oct05.dll")


x0=avisource("vhs.avi").assumetff()
y=x0.nnedi(field=3)
x=x0.Yadifmod(mode=1,edeint=y)
p=enhancebob(x,enlarge=1,blksize=16,degrain=0)
p.fft3dfilter(sigma=0,sigma2=0,sigma3=0,sigma4=128,bt=5,plane=1)

function enhancebob(clip x0, int "degrain",int "enlarge",bool "tm",int "dct",int "badsad",int "blksize",int "blksizev",int "overlap",int "searchparam",int "thsad",int "search"){

enlarge = default( enlarge , 0 )
degrain = default( degrain , 0 )
tm = default( tm , true )
dct = default( dct , 0 )
blksize = default( blksize , 8 )
badsad = default( badsad , 10000 )
blksizev = default( blksizev , blksize )
searchparam = default( searchparam, 2 )
search = default( search , 2 )
thsad = default( thsad , 350 )
overlap = default( overlap , blksize / 2 )
overlapv = overlap * blksizev / blksize
#overlap=0

xn=x0.nnedi(field=1,dh=true).assumeframebased().assumetff()

x=(enlarge==0.0) ? xn : xn.spline36resize(2 * xn.width(),xn.height())

ox = x.width()
oy = x.height()

#xp=x.interleaved2planar()

xs=x.separatefields().assumeframebased().assumetff().separatefields()
xp0=xs.selectevery(8,0,5).interleaved2planar()
xp1=xs.selectevery(8,2,7).interleaved2planar()
xp2=xs.selectevery(8,1,4).interleaved2planar()
xp3=xs.selectevery(8,3,6).interleaved2planar()

s=x.MSuper(pel=1)

vf1y=s.MAnalyse(delta=1,isb=false,truemotion=tm,blksize=blksize,blksizev=blksizev,overlap=overlap,overlapv=overlapv,search=search,searchparam=searchparam,badsad=badsad,dct=dct)
vb1y=s.MAnalyse(delta=1,isb= true,truemotion=tm,blksize=blksize,blksizev=blksizev,overlap=overlap,overlapv=overlapv,search=search,searchparam=searchparam,badsad=badsad,dct=dct)
vf2y=s.MAnalyse(delta=2,isb=false,truemotion=tm,blksize=blksize,blksizev=blksizev,overlap=overlap,overlapv=overlapv,search=search,searchparam=searchparam,badsad=badsad,dct=dct)
vb2y=s.MAnalyse(delta=2,isb= true,truemotion=tm,blksize=blksize,blksizev=blksizev,overlap=overlap,overlapv=overlapv,search=search,searchparam=searchparam,badsad=badsad,dct=dct)

xf1=x.mcompensate(s,vf1y,thSAD=thsad)
xf2=x.mcompensate(s,vf2y,thSAD=thsad)
xb1=x.mcompensate(s,vb1y,thSAD=thsad)
xb2=x.mcompensate(s,vb2y,thSAD=thsad)

xf1s=xf1.separatefields().assumeframebased().assumetff().separatefields()
xf2s=xf2.separatefields().assumeframebased().assumetff().separatefields()
xb1s=xb1.separatefields().assumeframebased().assumetff().separatefields()
xb2s=xb2.separatefields().assumeframebased().assumetff().separatefields()

xf10=xf1s.selectevery(8,0,5).interleaved2planar()
xf20=xf2s.selectevery(8,0,5).interleaved2planar()
xb10=xb1s.selectevery(8,0,5).interleaved2planar()
xb20=xb2s.selectevery(8,0,5).interleaved2planar()

xf11=xf1s.selectevery(8,2,7).interleaved2planar()
xf21=xf2s.selectevery(8,2,7).interleaved2planar()
xb11=xb1s.selectevery(8,2,7).interleaved2planar()
xb21=xb2s.selectevery(8,2,7).interleaved2planar()

xf12=xf1s.selectevery(8,1,4).interleaved2planar()
xf22=xf2s.selectevery(8,1,4).interleaved2planar()
xb12=xb1s.selectevery(8,1,4).interleaved2planar()
xb22=xb2s.selectevery(8,1,4).interleaved2planar()

xf13=xf1s.selectevery(8,3,6).interleaved2planar()
xf23=xf2s.selectevery(8,3,6).interleaved2planar()
xb13=xb1s.selectevery(8,3,6).interleaved2planar()
xb23=xb2s.selectevery(8,3,6).interleaved2planar()

mf1s=x.mmask(vf1y,kind=4).separatefields().assumeframebased().assumetff().separatefields()
mf2s=x.mmask(vf2y,kind=4).separatefields().assumeframebased().assumetff().separatefields()
mb1s=x.mmask(vb1y,kind=4).separatefields().assumeframebased().assumetff().separatefields()
mb2s=x.mmask(vb2y,kind=4).separatefields().assumeframebased().assumetff().separatefields()

if10=mf1s.selectevery(8,0,5).interleaved2planar().mt_lut(expr="x 4 % 2 == 32 8 ?",chroma="process")
ib10=mb1s.selectevery(8,0,5).interleaved2planar().mt_lut(expr="x 4 % 2 == 32 8 ?",chroma="process")
if20=mf2s.selectevery(8,0,5).interleaved2planar().mt_lut(expr="x 4 % 0 == 24 8 ?",chroma="process")
ib20=mb2s.selectevery(8,0,5).interleaved2planar().mt_lut(expr="x 4 % 0 == 24 8 ?",chroma="process")

if11=mf1s.selectevery(8,2,7).interleaved2planar().mt_lut(expr="x 4 % 1 == 64 x 4 % 3 == 24 8 ? ?",chroma="process")
ib11=mb1s.selectevery(8,2,7).interleaved2planar().mt_lut(expr="x 4 % 1 == 64 x 4 % 3 == 24 8 ? ?",chroma="process")
if21=mf2s.selectevery(8,2,7).interleaved2planar().mt_lut(expr="x 4 % 3 == 48 x 4 % 1 == 20 8 ? ?",chroma="process")
ib21=mb2s.selectevery(8,2,7).interleaved2planar().mt_lut(expr="x 4 % 3 == 48 x 4 % 1 == 20 8 ? ?",chroma="process")

if12=mf1s.selectevery(8,1,4).interleaved2planar().mt_lut(expr="x 4 % 0 == 64 x 4 % 2 == 24 8 ? ?",chroma="process")
ib12=mb1s.selectevery(8,1,4).interleaved2planar().mt_lut(expr="x 4 % 0 == 64 x 4 % 2 == 24 8 ? ?",chroma="process")
if22=mf2s.selectevery(8,1,4).interleaved2planar().mt_lut(expr="x 4 % 2 == 48 x 4 % 4 == 20 8 ? ?",chroma="process")
ib22=mb2s.selectevery(8,1,4).interleaved2planar().mt_lut(expr="x 4 % 2 == 48 x 4 % 4 == 20 8 ? ?",chroma="process")

if13=mf1s.selectevery(8,3,6).interleaved2planar().mt_lut(expr="x 4 % 3 == 64 x 4 % 1 == 24 8 ? ?",chroma="process")
ib13=mb1s.selectevery(8,3,6).interleaved2planar().mt_lut(expr="x 4 % 3 == 64 x 4 % 1 == 24 8 ? ?",chroma="process")
if23=mf2s.selectevery(8,3,6).interleaved2planar().mt_lut(expr="x 4 % 1 == 48 x 3 % 1 == 20 8 ? ?",chroma="process")
ib23=mb2s.selectevery(8,3,6).interleaved2planar().mt_lut(expr="x 4 % 1 == 48 x 3 % 1 == 20 8 ? ?",chroma="process")


ns0=if10.mt_lutxy(ib10,expr="x y +",chroma="process").mt_lutxy(if20,expr="x y +",chroma="process")
\.mt_lutxy(ib20,expr="x y +",chroma="process")

ns1=if11.mt_lutxy(ib11,expr="x y +",chroma="process").mt_lutxy(if21,expr="x y +",chroma="process").mt_lutxy(ib21,expr="x y +",chroma="process")

ns2=if12.mt_lutxy(ib12,expr="x y +",chroma="process").mt_lutxy(if22,expr="x y +",chroma="process").mt_lutxy(ib22,expr="x y +",chroma="process")

ns3=if13.mt_lutxy(ib13,expr="x y +",chroma="process").mt_lutxy(if23,expr="x y +",chroma="process").mt_lutxy(ib23,expr="x y +",chroma="process")

ff10=mt_lutxy(xf10,if10,expr="x y * 32 /",chroma="process")
fb10=mt_lutxy(xb10,ib10,expr="x y * 32 /",chroma="process")
ff20=mt_lutxy(xf20,if20,expr="x y * 24 /",chroma="process")
fb20=mt_lutxy(xb20,ib20,expr="x y * 24 /",chroma="process")

ff11=mt_lutxy(xf11,if11,expr="x y * 64 /",chroma="process")
fb11=mt_lutxy(xb11,ib11,expr="x y * 64 /",chroma="process")
ff21=mt_lutxy(xf21,if21,expr="x y * 48 /",chroma="process")
fb21=mt_lutxy(xb21,ib21,expr="x y * 48 /",chroma="process")

ff12=mt_lutxy(xf12,if12,expr="x y * 64 /",chroma="process")
fb12=mt_lutxy(xb12,ib12,expr="x y * 64 /",chroma="process")
ff22=mt_lutxy(xf22,if22,expr="x y * 48 /",chroma="process")
fb22=mt_lutxy(xb22,ib22,expr="x y * 48 /",chroma="process")

ff13=mt_lutxy(xf13,if13,expr="x y * 64 /",chroma="process")
fb13=mt_lutxy(xb13,ib13,expr="x y * 64 /",chroma="process")
ff23=mt_lutxy(xf23,if23,expr="x y * 48 /",chroma="process")
fb23=mt_lutxy(xb23,ib23,expr="x y * 48 /",chroma="process")

md0=average(xp0,0.53333,ff10,0.133333,fb10,0.133333,ff20,0.1,fb20,0.1)
md1=average(xp1,0.0345,ff11,0.2759,fb11,0.2759,ff21,0.2069,fb21,0.2069)
#md2=average(ff12,0.2857,fb12,0.2857,ff22,0.2143,fb22,0.2143)
md2=average(xp2,0.104,ff12,0.256,fb12,0.256,ff22,0.192,fb22,0.192)
md3=average(xp3,0.0345,ff13,0.2759,fb13,0.2759,ff23,0.2069,fb23,0.2069)

final=interleave(
\mt_lutxy(md0,ns0,expr="x 240 * y 128 + /",chroma="process").planar2interleaved(),
\mt_lutxy(md1,ns1,expr="x 232 * y 8 + /",chroma="process").planar2interleaved(),
\mt_lutxy(md2,ns2,expr="x 250 * y 26 + /",chroma="process").planar2interleaved(),
\mt_lutxy(md3,ns3,expr="x 232 * y 8 + /",chroma="process").planar2interleaved()
\).selectevery(8,0,2,1,3,6,4,7,5).assumefieldbased().assumetff().weave().assumefieldbased().assumetff().weave()

z=(degrain==0.0) ? final : corrector(final,final,x,xf1,xf2,xb1,xb2,x,xf1,xf2,xb1,xb2,mode=0,th=degrain)

z.spline36resize(x0.width() , x0.height,src_top=-0.5)

}


Framerate is doubled. First the clip is bobbed with yadifmod and then is denoised whith a function of my own (yadif is very prone to artifacts and needs post-processing). Finally U channel is brutally denoised at very low frequencies to smooth out big green rainbows. I use several conversions interleaved2planar and viceversa to maintain YUY2 compatibility. To gain some processing speed you can try enlarge=0