RestoreSuper8Frames
From Avisynth wiki
copy the code below into a file 'RestoreSuper8Frames.avsi' in your AviSynth plugins directory or directly into your script:
# RestoreSuper8Frames() ( 9 Mar 2007 )
#
# A combed-frames eliminator for transcript of old movies to video by Martin Wagener
#
# RestoreSuper8Frames() is designed to select the video frames that were best exposed with single images of the movie
# and transform all the other frames to plain black.
#
# RestoreSuper8Frames() expects a data stream with at least 3 and no more than 4 time the field(!) rate of the movie.
# i.e. the video frame rate must be between 1.5 and 2 of the movie image rate.
#
# The algorithm is simple: with the help of FieldDeinterlace(), the combing of the previous, current and
# next frame are compared and a black frame is returned if the current frame is not the minimum.
#
# The filter returns irregular sequences of single best-choice frames and one to three black frames.
# These sequences can be turned into alternating black-good-black-good sequences with MultiDecimate()
# and then into the perfect sequence with SelectEven().
#
# In favor to guarantee that it is always SelectEven() and not SelectOdd() for the good frames,
# this filter always turns the first frame black.
#
# To supply RestoreSuper8Frames() with the neccessary frames, use DoubleWeave().
# DoubleWeave() will recombine all fields of the raw video in a way that always outputs one uncombed frame in the sequence.
#
# Movie: | A |~| B |~| C |~| D ( A...D are the movie images - Projector slow at B, ~ is shutter)
# source vid.: |a* a*|b b*|c* c*|d d*|e* e | (a..e are the video frames, * shows the uncombed)
# |1 2 |1 2 |1 2 |1 2 |1 2 | (1 and 2 are the the fields of the frames)
# | a | b | c | d | e | (this shows the complete frames before DoubleWeave()
# DoubleWeave: |aa|ab|bb|bc|cc|cd|dd|de|ee|
# |12|21|12|21|12|21|12|21|12|
# |a |a'|b |b'|c |c'|d |d'|e | (the frames after DoubleWeave())
# A - - B - - - C - (A-C=good frames after RestoreSuper8Frames(), -=black frames)
#
# The exact(!) image sequence of the celluloid movie will be reconstructed if the camera takes not less than
# three and not more than four fields per image.
#
## --------
function RestoreSuper8Frames(clip "clip", bool "map", bool "show")
{
map= default(map, false)
SC= "clip=(ip<=ic)?blank:last"+chr(13)+"clip=(in<ic)?blank:clip"+chr(13)+"return((RS8Fshow)?clip.Subtitle(string(ic)):clip)"
FE= "ip=AverageLuma(cp)"+chr(13)+"ic=AverageLuma(cc)"+chr(13)+"in=AverageLuma(cn)"
global RS8Fshow= default(show,false)
global ip=0
global ic=0
global in=0
dt=8
global cf=clip.GreyScale().HorizontalReduceBy2().Blur(1.58,0)
global blank=BlankClip(clip,length=clip.FrameCount(),color=0)
global cp=cf.DuplicateFrame(0).FieldDeinterlace(threshold=255,dthreshold=dt,map=true).Levels(140,1,255,0,255,coring=false)
global cc=cf.FieldDeinterlace(threshold=255,dthreshold=dt,map=true).Levels(140,1,255,0,255,coring=false)
global cn=cf.DeleteFrame(0).DuplicateFrame(clip.Framecount()-1).FieldDeinterlace(threshold=255,dthreshold=dt,map=true).Levels(140,1,255,0,255,coring=false)
f1= clip.ScriptClip(SC)
f0= f1.FrameEvaluate(FE)
return((map) ? Overlay(f0,clip,opacity=0.5).Overlay(BilinearResize(cc,clip.Width(),clip.Height()),opacity=0.5,mode="add") : f0)
# return((show) ? BilinearResize(cc,clip.Width(),clip.Height()) : f0)
}
Back to Shared functions.