PDA

View Full Version : Old holiday videos


zilog jones
4th February 2006, 15:49
I have some old videos my uncle took and I'm trying to convert them DVD and hopefully try and make them look as good as possible. The oldest stuff is from 1990, and I'm half suspecting the copy I have is a third generation as it's quite wobbly (I have no TBC -_-), the colour's equally wobbly and there's very little detail in it. Here's (http://www.skynet.ie/~zilog/pics/video/1-20819.jpg) a screenshot.

I've tried this script so far (PicVideo MJPEG @ 18 quality; PAL, caputred with a SAA7134-based card):

avisource("H:\cap2\blah.avi")
converttoYUY2
BorderControl(XRS=3, YBS=11,XLB=8 )

JDL_UnfoldFieldsVertical(true)
CNRT(ln=25,un=25,vn=25)
JDL_FoldFieldsVertical(true)

FFT3DFilter(Sigma=3,wintype=1, interlaced=true, sharpen=0.3)


And here's (http://www.skynet.ie/~zilog/pics/video/1a-20819.jpg) the result - unfortunately it doesn't seem to be doing much.

I think FFT3DFilter might just be removing more of what little detail there is - is there something more suitable for a video like this? There's a lot of panning and stuff so I don't want to filter too much. Is there much point in trying to sharpen the video?

I'd love to try out CNRS or CNRF but I'd have to do a lot of *organising* to get sufficient HDD space to make blurred versions of the video - are they significantly more effective at reducing chroma noise?

Any other suggestions?

I can put up a clip of the video if anyone wants.

scharfis_brain
4th February 2006, 15:54
post an unprocessed sample clip.
the longer, the better.

zilog jones
4th February 2006, 17:10
http://www.skynet.ie/~zilog/a1.avi (23MB)

I hope XviD's ok (it's about 4.4Mb/s). It was either 40 seconds of that or about 12 seconds of MJPEG. Doesn't seem to look *too* much worse...

Boulder
4th February 2006, 18:00
I would use FFT3DFilter for the chroma as well. I've noticed that CNR2 causes weird things, you can see it yourself by interleaving a non-CNR2 clip with a CNR2-filtered one and then using UtoY and VtoY. Also keeping the original colorspace as long as possible would be optimal (is it YV12 as you convert to YUY2?)

zilog jones
5th February 2006, 17:12
Yeah it seems it's YV12 (I always thought MJPEG was YUY2 and was wondering why it was coming out that way - must have been mixing it up with Huffyuv), so I should try and keep it that.

Anyway, what settings for FFT3DFilter would you recommend for chroma filtering?

Boulder
5th February 2006, 17:29
Try the same settings you've already got, that is, add the parameter plane=4 and all the planes will be handled by the filter. I usually use sigmas around 2-5 for chroma denoising, for my DV stuff I need to go much higher though.

If you have the time, motion compensated denoising might come in handy.

scharfis_brain
5th February 2006, 17:58
@zilog jones:
force the MJPEG-decoder to yuy2 by
avisource("blah.vai",pixel_type="YUY2")

thi picvideo3 mjpeg codec doesn't output the native YUY2 if the application (here AVS) demands for YV12 per default.

zilog jones
5th February 2006, 18:43
Ah, thanks - I thought YV12 was wrong, especially when I looked at the PicVideo settings and saw 4:2:2 colour sampling selected O_o

@Boulder:
What kind of motion compensated denoising? I really haven't been keeping up with AviSynth filters recently...

Boulder
5th February 2006, 18:45
See Didée's MCNR_simple2 for example. Be warned, it's slow but the results are very good :)

zilog jones
5th February 2006, 21:33
I *eventually* got it to work, and results look very good! It's pretty damn slow (I'm stuck in Pentium III land here ^_^) but it might be worth it.

My script now is:
Import("E:\Video Programs\AviSynth 2.5\MCNR_simple\MCNR_simple2.avsi")

Avisource("H:\blah.avi",pixel_type="YUY2")
BorderControl(XRS=3, YBS=11,XLB=8 )
ConvertToYV12(interlaced=true)

JDL_UnfoldFieldsVertical(true)
MCNR_simple2( frames=3,thY2=20,thC2=12,thY=3,thC=2,blocksize=16,chroME=false,repairME=true,removdirt=true,LPrad=2.5, LPlosens=2,LPhisens=6 )
JDL_FoldFieldsVertical(true)

I just used the example parameters for MCNR_simple 2 from the readme file, which unfortunately is all in German -_-
Also, though it is removing a good deal of noise, it seems to be getting rid of some detail too - what could I do to slightly lessen this effect?

Chainmax
6th February 2006, 00:13
How about using the latest unofficial LimitedSharpen with SMode=4, LMode=3 along with Soothe?

Boulder
6th February 2006, 06:32
I *eventually* got it to work, and results look very good! It's pretty damn slow (I'm stuck in Pentium III land here ^_^) but it might be worth it.

You can make it faster by using frames=2. You could also use a version which works on MaskTools v2 alpha. Try searching for my post regarding cleaning a captured video, it's buried there. Using thY2 and thC2=-1 will make the function use TemporalSoften instead of TTempSmooth which should also make it faster IIRC.

What comes to strength, lowering the thY and thC thresholds will lower the effect. Try the function with the default settings first, they are quite efficient already.

frednerk
25th February 2006, 02:03
Sorry Boulder, I searched with "captured video" and user "boulder" and only it only came back with this thread. May I please ask for further info on where to find it ?

Edit: Whoops, found it at : http://forum.doom9.org/showthread.php?p=766898#post766898 however the preamble to the script said "Here's the whole lot of it (Didée's and your fixes not yet there)" ... read the thread a didn't spot an updated script...

Boulder
25th February 2006, 09:12
It's this one, use it to replace the LPprotect part :

function LPprotect( clip NR, clip orig, float rad, int low, int high )
{
ox = NR.width()
oy = NR.height()
HI = string(256.0/high)
LO = string(256.0/high*low)
ML = string(float(high)/(float(high)-low))
diff = mt_lutxy(orig,NR,yexpr="x y - 128 +",uexpr="y",vexpr="y",Y=3,U=3,V=3)
diffLP = repair(diff,diff.removegrain(4,-1).bicubicresize(m4(ox/rad),m4(oy/rad)).bicubicresize(ox,oy,1,0),1,0)
diff = mt_lutxy(diff,diffLP,yexpr="x 128 - y 128 - * 0 < 128 x y 128 - - ?",uexpr="x",vexpr="x",Y=3,U=2,V=2)
MyMoMask = mt_logic( mt_lutxy(NR,NR.deleteframe(0), "x y - abs "+HI+" * "+LO+" - "+ML+" *"),
\ mt_lutxy(NR,NR.duplicateframe(0),"x y - abs "+HI+" * "+LO+" - "+ML+" *"), "max",Y=3,U=1,V=1)
mt_merge(NR,mt_lutxy(orig,diff,yexpr="x y 128 - -",uexpr="y",vexpr="y",Y=3,U=3,V=3),MyMoMask.fity2uv(),Y=3,U=3,V=3)
#MyMoMask.greyscale
return( last )
}

Unfortunately the script hasn't been updated yet. AFAIK Didée's still working on the whole MCNR concept.

frednerk
25th February 2006, 10:36
Thankyou Boulder, :goodpost: been following the usage forum for a while; let's say that you feature prominently along with a number of other very clever and helpful people :)

Just out of interest, given RemoveDirt no longer appears to be a supported DLL... the author seems to have made it a script per http://www.removedirt.de.tf/ and http://forum.doom9.org/showthread.php?p=761036#post761036 . However the new RemoveDirt script function appears to still need the old DLL for the SCSelect call (unless there's another way to do it). Hence would it be a valid thing to do, to replace in MCNR_simple2 the call to the old DLL
removdirt ? RemoveDirt() : last
with a call to the a scipt function
removdirt ? fRemoveDirt() : last
and include in the bottom of MCNR_simple2, the slightly renamed function as written by the author

function fRemoveDirt(clip input, bool "_grey", int "repmode")
{
# fRemoveDirt requires RemoveDirtSSE2 (if you have SSE2, otherwise the slower one) for SCSelect as at 25-Feb-2006
# http://www.removedirt.de.tf/
# http://forum.doom9.org/showthread.php?p=761036#post761036
_grey=default(_grey, false)
repmode=default(repmode, 16)
clmode=17
clensed=Clense(input, grey=_grey, cache=4)
sbegin = ForwardClense(input, grey=_grey, cache=-1)
send = BackwardClense(input, grey=_grey, cache=-1)
alt=Repair(SCSelect(input, sbegin, send, clensed, debug=true), input, mode=repmode, modeU = _grey ? -1 : repmode )
restore=Repair(clensed, input, mode=repmode, modeU = _grey ? -1 : repmode)
corrected=RestoreMotionBlocks(clensed, restore, neighbour=input, alternative=alt, gmthreshold=70, dist=1, dmode=2,
\ debug=false, noise=10, noisy=12, grey=_grey)
return RemoveGrain(corrected, mode=clmode, modeU = _grey ? -1 : clmode )
}

(remembering to still include the old DLL to so it can access SCSelect). Would that be right ? In the interests of viewing a complete script, does the MCNR_simple2 include file then become this ? (apologies to the original authors if it's incorrect, I'll edit it out if someone says so)

global idx_counter = 10

function MCNR_simple2( clip clp, int "frames", int "thY", int "thC", int "thY2", int "thC2",
\ int "blocksize", bool "chroME", bool "repairME", bool "removdirt",
\ float "LPrad", int "LPlosens", int "LPhisens")
{
frames = default( frames, 2 ) # number of temporal neighbors to use for motion compensation & temporal filtering
thY = default( thY, 8 ) # upper thresh for pixel differences to include into temporal filtering
thC = default( thC, 6 ) # ditto, for chroma
thY2 = default( thY2, -1 ) # lower diff. thresh, for TTempSmooth (= -1 --> use TemporalSoften, not TTempSmooth)
thC2 = default( thC2, -1 ) # ditto, for chroma
blocksize = default( blocksize, 16 ) # blocksize for motion search & compensation
removdirt = default( removdirt,false) # additionally use RemoveDirt? (tip: for strong noise - true, else false. Requires frames>1)
chroME = default( chroME, false) # include chroma planes into motion search?
repairME = default( repairME, true ) # simple repairing of MC/ME errors (good when using bigger thresh's).
LPrad = default( LPrad, 0.0 ) # Lowpass protection: radius for gaussian blur
LPlosens = default( LPlosens, 1 ) # LP protection: lower thresh for motion recognition
LPhisens = default( LPhisens, 5 ) # LP protection: upper thresh for motion recognition

frames = (frames<1) ? 1 : (frames>4) ? 4 : frames
removdirt = (frames==1) ? false : removdirt
LPhisens = (LPhisens>LPlosens) ? LPhisens : LPlosens+1

dummy = blankclip(clp,width=64,height=32)

global idx_counter = idx_counter + 1

bw4 = (frames<4) ? dummy : clp.SrchCmpRp(blocksize,true, 4,chroME,repairME)
bw3 = (frames<3) ? dummy : clp.SrchCmpRp(blocksize,true, 3,chroME,repairME)
bw2 = (frames<2) ? dummy : clp.SrchCmpRp(blocksize,true, 2,chroME,repairME)
bw1 = clp.SrchCmpRp(blocksize,true, 1,chroME,repairME)
fw1 = clp.SrchCmpRp(blocksize,false,1,chroME,repairME)
fw2 = (frames<2) ? dummy : clp.SrchCmpRp(blocksize,false,2,chroME,repairME)
fw3 = (frames<3) ? dummy : clp.SrchCmpRp(blocksize,false,3,chroME,repairME)
fw4 = (frames<4) ? dummy : clp.SrchCmpRp(blocksize,false,4,chroME,repairME)

frames == 1 ? interleave( bw1,clp,fw1 ) : \
frames == 2 ? interleave( bw2,bw1,clp,fw1,fw2 ) : \
frames == 3 ? interleave( bw3,bw2,bw1,clp,fw1,fw2,fw3 ) : \
interleave( bw4,bw3,bw2,bw1,clp,fw1,fw2,fw3,fw4 )

removdirt ? fRemoveDirt() : last # dcw - changed RemoveDirt() to fRemoveDirt()

(thY2 < 0) || (thC2 < 0) ? temporalsoften(frames,thY,thC,32,2)
\ : ttempsmooth(frames,thY,thC,thY2,thC2,5,24)

selectevery(frames*2+1,frames)

LPrad < 1.01 ? last : LPprotect(last,clp,LPrad,LPlosens,LPhisens)

return( last )
}

# --------------------------------

function SrchCmpRp( clip clp, int _blksize, bool _isb, int _delta, bool _chroME, bool _repair)
{
vec = clp.mvanalyse(truemotion=true,pel=2,blksize=_blksize,chroma=_chroME,isb=_isb,delta=_delta,idx=idx_counter)
comp = clp.mvflow(vec,idx=idx_counter)
# vec = clp.mvanalyse(pel=2,blksize=_blksize,chroma=_chroME,isb=_isb,delta=_delta,idx=idx_counter)
# comp = clp.mvcompensate(vec,idx=idx_counter)
_repair ? repair(comp,clp,1,3) : comp
return( last )
}

# --------------------------------

function LPprotect( clip NR, clip orig, float rad, int low, int high )
{
# by Boulder - replacement for inside MCNR_simple2, to use MaskTools v2 instead of the pre-V2 Masktools, 26-Feb-2006
# http://forum.doom9.org/showthread.php?p=790633#post790633
ox = NR.width()
oy = NR.height()
HI = string(256.0/high)
LO = string(256.0/high*low)
ML = string(float(high)/(float(high)-low))
diff = mt_lutxy(orig,NR,yexpr="x y - 128 +",uexpr="y",vexpr="y",Y=3,U=3,V=3)
diffLP = repair(diff,diff.removegrain(4,-1).bicubicresize(m4(ox/rad),m4(oy/rad)).bicubicresize(ox,oy,1,0),1,0)
diff = mt_lutxy(diff,diffLP,yexpr="x 128 - y 128 - * 0 < 128 x y 128 - - ?",uexpr="x",vexpr="x",Y=3,U=2,V=2)
MyMoMask = mt_logic( mt_lutxy(NR,NR.deleteframe(0), "x y - abs "+HI+" * "+LO+" - "+ML+" *"),
\ mt_lutxy(NR,NR.duplicateframe(0),"x y - abs "+HI+" * "+LO+" - "+ML+" *"), "max",Y=3,U=1,V=1)
mt_merge(NR,mt_lutxy(orig,diff,yexpr="x y 128 - -",uexpr="y",vexpr="y",Y=3,U=3,V=3),MyMoMask.fity2uv(),Y=3,U=3,V=3)
#MyMoMask.greyscale
return( last )
}

# --------------------------------

function m4(float x) {return( x<16?16:int(round(x/4.0)*4)) }

# --------------------------------
function fRemoveDirt(clip input, bool "_grey", int "repmode")
{
# fRemoveDirt requires RemoveDirtSSE2 (if you have SSE2, otherwise the slower one) for SCSelect as at 25-Feb-2006
# http://www.removedirt.de.tf/
# http://forum.doom9.org/showthread.php?p=761036#post761036
_grey=default(_grey, false)
repmode=default(repmode, 16)
clmode=17
clensed=Clense(input, grey=_grey, cache=4)
sbegin = ForwardClense(input, grey=_grey, cache=-1)
send = BackwardClense(input, grey=_grey, cache=-1)
alt=Repair(SCSelect(input, sbegin, send, clensed, debug=true), input, mode=repmode, modeU = _grey ? -1 : repmode )
restore=Repair(clensed, input, mode=repmode, modeU = _grey ? -1 : repmode)
corrected=RestoreMotionBlocks(clensed, restore, neighbour=input, alternative=alt, gmthreshold=70, dist=1, dmode=2,
\ debug=false, noise=10, noisy=12, grey=_grey)
return RemoveGrain(corrected, mode=clmode, modeU = _grey ? -1 : clmode )
}

PS I'm in total awe of Didée. And scharfis_brain.

Boulder
25th February 2006, 10:56
I would still use the old RemoveDirt, available at http://home.pages.at/kassandro/RemoveDirt/RemoveDirt.zip . The link is at the official RemoveDirt page but it's hidden quite well under all the text;)

Oh, and the MaskTools v2 port of LPprotect wasn't my doings, Didée did that.

I'm usually helpful but don't call me clever - I am merely a user of other people's great ideas ;)

frednerk
25th February 2006, 11:07
OK :) I was a tad worried by the author's comment about jerky motion problems with the old version, at http://www.removedirt.de.tf/
...this plugin has been completely rewritten from scratch. It no more contains a RemoveDirt filter ...

The old RemoveDirt suffered from two problems. Firstly, fast motion of big objects was getting jerky after RemoveDirt filtering and secondly the essentially temporal approach of RemoveDirt was no more competitive with the spatial-temporal approach of ...

If my theory about jerky RemoveDirt motion is correct, the new RemoveDirt script function will resolve this problem. The basic idea of the new script function is to use the old RemoveDirt for static areas and a sharper version of RemoveDust for the motion areas, where RemoveDirt didn't do any cleaning before.

Altogether the new RemoveDirt aims to achieve similar or better compression than RemoveDust with considerable more details in motion areas, where RemoveDust often destroyed fine details...
Best Regards

Boulder
26th February 2006, 12:31
I think that problem is avoided by motion compensation in MCNR.

frednerk
26th February 2006, 12:45
OK. Wasn't sure. Cheers and Thanks.