Log in

View Full Version : SC_Interleave


joka
17th June 2013, 12:19
I tested Freds / Johnmeyers script for restoration of super 8 films. I found that the dirt from the frames before /after the Scene change are not removed and it took some frames till the Grain removal fully worked. Looking for the reason I found, that simply are not enougth frames can be taken. So I made this script to reorder the frames.

It works, but it slows down etherything a bit. However, status is more a technology proof (minimum parameters). It is good, if SCSelect find the scene change - if not ...

##### SC_Interleave - 20130121
#
# Interleaves 7 frames to consider scene changes in temporal filters.
# For progressive frames only.
# Required plugins RemoveDirt, masktools2, MVTools2
#
# P, p .. previouse
# C .. current
# N, n .. next
#
# The order is selected to "feed" filters with temporal radius of 1, 2 and 3.
# Reordered frames shown in small characters.
#
# P3 P2 P1 C N1 N2 N3 other before scene change
# P3 P2 P1 C N1 N2 p4 three before scene change
# p4 P2 P1 C N1 p3 p5 two before scene change
# p5 p3 P1 C p2 p4 p6 last before scene change
# n6 n4 n2 C N1 n3 n5 first after scene change
# n5 n3 P1 C N1 N2 n4 second after scene change
# n4 P2 P1 C N1 N2 N3 third after scene change
# P3 P2 P1 C N1 N2 N3 other after scene change
#
# Functions:
#
# SC_Analyse return - small clip with scene change information, uses SCSelect() from RemoveDirt
# y = 125 (three before scene change), 126 (two before scene change), 127 (last before scene change)
# y = 128 (all others)
# y = 129 (first after scene change), 130 (second after scene change), 131 (third after scene change)
# c - your clip
# "dfactor" - parameter for scene change detection (2.0 seems to be good for HD)
#
# SC_Interleave return - clip with 7 frames per original frame ordered considering the results of scene change analyses
# c - your clip
# sc_clip - clip created by SC_Analyse
# "r" - default c, optional different clip for previouse and next frames
#
# SC_ReInterleave return - reordered clip, current frame from c7, previouse and next frames from r7
# c7 - your interleaved clip (processed)
# r7 - different interleaved clip for previouse and next frames (usually unprocessed interleaved clip)
#
# SC_MotionCompensation
# return - motion compensated interleaved clip
# c7 - your interleaved clip
# bs - blocksize (default bs=8 (SD) and bs=16 (HD))
#
# SC_Select return - selected frame out of the 7 frames.
#
#
# Example for usage
#
# Ex1 - usage with/without motion compensation
# c = your_clip
# sc_clip = c .SC_Analyse(dfactor=2.0) # dfactor = 2.0 ... 4.0 (2.0 for HD)
# c7 = c .SC_Interleave(sc_clip)
# c7 = c7.SC_MotionCompensation() # only if motion compensation is required
# c7 = c7.your_temporal_filter()
# c = c7.SC_Select()
#
# Ex2 - chain temporal filters 1
# c = your_clip
# sc_clip = c .SC_Analyse(dfactor=2.0)
# c7 = c .SC_Interleave(sc_clip)
# c7 = c7.your_first_temporal_filter()
# c = c7.SC_Select()
# c7 = c .SC_Interleave(sc_clip) # interleaves the processed frames from c
# c7 = c7.your_second_temporal_filter()
# c = c7.SC_Select()
#
# Ex3 - chain temporal filters 2
# c = your_clip
# sc_clip = c .SC_Analyse(dfactor=2.0)
# r7 = c .SC_Interleave(sc_clip)
# c7 = r7.your_first_temporal_filter()
# c7 = c7.SC_ReInterleave(r7) # takes current frame from c7 and previouse/next frames from r7
# c7 = c7.your_second_temporal_filter()
# c = c7.SC_Select()
#
# Ex4 - avoid double motion compensation
# r = your_clip
# c = r .your_first_filter() # first motion compensation (Stabilization ?)
# sc_clip = r .SC_Analyse(dfactor=2.0)
# c7 = c .SC_Interleave(sc_clip, r) # takes current frame from c and previouse/next frames from r
# c7 = c7.your_second_temporal_filter() # for instance MDegrain with own MC
# c = c7.SC_Select()
#

Function SC_Analyse(clip c, float "dfactor") {

dfactor = Defined(dfactor) ? dfactor : (c.width() > 1050) ? 2.0 : dfactor
sc = SCSelect(c, c.mt_lut(y=-255), c.mt_lut(y=0), c.mt_lut(y=-128), dfactor=dfactor).crop(0, 0, 16, 16)

sc_clip = mt_lutxy(sc.SelectEvery(1, 2), sc.SelectEvery(1,-2), expr="x 128 < 125 y 128 > 131 128 ? ?")
sc_clip = sc_clip.mt_lutxy(sc.SelectEvery(1,-1), expr="y 128 > 130 x ?")
sc_clip = sc_clip.mt_lutxy(sc.SelectEvery(1, 1), expr="y 128 < 126 x ?")
sc_clip = sc_clip.mt_lutxy(sc , expr="y 128 = x y 128 < 127 129 ? ?")

Return sc_clip.Greyscale() }


Function SC_Interleave(clip c, clip sc_clip, clip "r") {

sc_clip = sc_clip.mt_lut(expr="x 125 < 3 x 131 > 3 x 125 - ? ?").pointresize(c.width(), c.height())
r = default(r, c)

rb6 = r.SelectEvery(1,-6)
rb5 = r.SelectEvery(1,-5)
rb4 = r.SelectEvery(1,-4)
rb3 = r.SelectEvery(1,-3)
rb2 = r.SelectEvery(1,-2)
rb1 = r.SelectEvery(1,-1)
# c = c.SelectEvery(1, 0)
rf1 = r.SelectEvery(1, 1)
rf2 = r.SelectEvery(1, 2)
rf3 = r.SelectEvery(1, 3)
rf4 = r.SelectEvery(1, 4)
rf5 = r.SelectEvery(1, 5)
rf6 = r.SelectEvery(1, 6)

cp3 = SC_Helper(sc_clip, rb3, rb4, rb5, rb3, rf6, rf5, rf4)
cp2 = SC_Helper(sc_clip, rb2, rb2, rb3, rb2, rf4, rf3, rb2)
cp1 = SC_Helper(sc_clip, rb1, rb1, rb1, rb1, rf2, rb1, rb1)
# c = SC_Helper(sc_clip, c, c, c, c, c, c, c)
cn1 = SC_Helper(sc_clip, rf1, rf1, rb2, rf1, rf1, rf1, rf1)
cn2 = SC_Helper(sc_clip, rf2, rb3, rb4, rf2, rf3, rf2, rf2)
cn3 = SC_Helper(sc_clip, rb4, rb5, rb6, rf3, rf5, rf4, rf3)

Return Interleave(cp3, cp2, cp1, c, cn1, cn2, cn3) }


Function SC_ReInterleave(clip c7, clip r7) {

cp3 = r7.SelectEvery(7, 0)
cp2 = r7.SelectEvery(7, 1)
cp1 = r7.SelectEvery(7, 2)
c = c7.SelectEvery(7, 3)
cn1 = r7.SelectEvery(7, 4)
cn2 = r7.SelectEvery(7, 5)
cn3 = r7.SelectEvery(7, 6)

Return Interleave(cp3, cp2, cp1, c, cn1, cn2, cn3) }


Function SC_MotionCompensation(clip c7, int "bs") {

## Parameters
bs = Default(bs, (c7.width() > 1050 ) ? 16 : 8) # Blocksize 16 for HD
ov = bs/2 # Overlap

## Motion Compensation
s7 = c7.MSuper(pel=2)
vb3 = s7.MAnalyse(isb=true, delta=3, blksize=bs, overlap=ov)
vb2 = s7.MAnalyse(isb=true, delta=2, blksize=bs, overlap=ov)
vb1 = s7.MAnalyse(isb=true, delta=1, blksize=bs, overlap=ov)
vf1 = s7.MAnalyse(isb=false, delta=1, blksize=bs, overlap=ov)
vf2 = s7.MAnalyse(isb=false, delta=2, blksize=bs, overlap=ov)
vf3 = s7.MAnalyse(isb=false, delta=3, blksize=bs, overlap=ov)

cp3 = c7.MCompensate(s7, vb3).SelectEvery(7, 3)
cp2 = c7.MCompensate(s7, vb2).SelectEvery(7, 3)
cp1 = c7.MCompensate(s7, vb1).SelectEvery(7, 3)
c = c7 .SelectEvery(7, 3)
cn1 = c7.MCompensate(s7, vf1).SelectEvery(7, 3)
cn2 = c7.MCompensate(s7, vf2).SelectEvery(7, 3)
cn3 = c7.MCompensate(s7, vf3).SelectEvery(7, 3)

Return Interleave(cp3, cp2, cp1, c, cn1, cn2, cn3) }


Function SC_Select(clip c7) {
Return c7.SelectEvery(7, 3) }


Function SC_Helper(clip sc_clip, clip c_0, clip c_1, clip c_2, clip c_3, clip c_4, clip c_5, clip c_6) {

c_a = ConditionalFilter(sc_clip, c_0, c_1, "AverageLuma()", "<", "1")
c_a = ConditionalFilter(sc_clip, c_a, c_2, "AverageLuma()", "<", "2")
c_b = ConditionalFilter(sc_clip, c_6, c_5, "AverageLuma()", ">", "5")
c_b = ConditionalFilter(sc_clip, c_b, c_4, "AverageLuma()", ">", "4")
c_c = ConditionalFilter(sc_clip, c_b, c_a, "AverageLuma()", ">", "3")

Return ConditionalFilter(sc_clip, c_3, c_c, "AverageLuma().round()", "=", "3") }