View difference between Paste ID: JNJQKHm9 and zV5tZEU4
SHOW: | | - or go back to the newest paste.
1-
function deblink4(clip clp, float "ratio", int "level")  {
1+
LoadPlugin("mvtools2.dll")
2
LoadPlugin("mt_masktools-26.dll")
3
4-
    \      "[deblink4] 1.0 >= ratio >= 0.0, it was " + string(ratio))
4+
function ng_deblink(clip clp,
5
\ float "ratio",
6
\ int "level",
7
\ clip "blinkmask"
8-
    \      "[deblink4] 257 >= level >= 0, it was " + string(level))
8+
\){
9
#Version 10 2012.04.22
10-
    blink=clp.ng_blinkmask_new
10+
11-
    m01=mt_logic(blink.selectevery(4,0),
11+
    blink = default(blinkmask, clp.ng_blinkmask())
12-
\                blink.selectevery(4,1),
12+
13-
\                mode="or").converttorgb32
13+
14-
    m01=mt_logic(blink.selectevery(4,2),
14+
15-
\                blink.selectevery(4,3),
15+
    \      "[ng_deblink] 1.0 >= ratio >= 0.0, it was " + string(ratio))
16-
\                mode="or").converttorgb32
16+
17
    level = default(level, round(ratio * 257))
18-
    f0=layer(clp.selectevery(4,0),
18+
19-
\            clp.selectevery(4,1).mask(m01),
19+
    \      "[ng_deblink] 257 >= level >= 0, it was " + string(level))
20
21-
    f1=layer(clp.selectevery(4,1),
21+
    m01=mt_logic(blink.SelectEvery(4,0),
22-
\            clp.selectevery(4,0).mask(m01),
22+
\                blink.SelectEvery(4,1),
23
\                mode="or").ConvertToRGB32()
24-
    f2=layer(clp.selectevery(4,2),
24+
    m23=mt_logic(blink.SelectEvery(4,2),
25-
\            clp.selectevery(4,3).mask(m23),
25+
\                blink.SelectEvery(4,3),
26
\                mode="or").ConvertToRGB32()
27-
    f3=layer(clp.selectevery(4,3),
27+
28-
\            clp.selectevery(4,2).mask(m23),
28+
    f0=Layer(clp.SelectEvery(4,0),
29
\            clp.SelectEvery(4,1).Mask(m01),
30
\            level=level)
31-
    interleave(f0,f1,f2,f3)
31+
    f1=Layer(clp.SelectEvery(4,1),
32
\            clp.SelectEvery(4,0).Mask(m01),
33
\            level=level)
34-
function deblink3(clip clp){
34+
    f2=Layer(clp.SelectEvery(4,2),
35-
    blink=clp.ng_blinkmask_new
35+
\            clp.SelectEvery(4,3).Mask(m23),
36-
    m01=mt_logic(blink.selectevery(4,0),
36+
37-
\                blink.selectevery(4,1),
37+
    f3=Layer(clp.SelectEvery(4,3),
38-
\                mode="or").converttorgb32
38+
\            clp.SelectEvery(4,2).Mask(m23),
39-
    f0=layer(clp.selectevery(4,0),
39+
40-
\            clp.selectevery(4,1).mask(m01))
40+
41-
    f1=layer(clp.selectevery(4,1),
41+
    Interleave(f0,f1,f2,f3)
42-
\            clp.selectevery(4,0).mask(m01))
42+
43-
    interleave(f0,f1,
43+
44-
\              clp.selectevery(4,2),clp.selectevery(4,3))
44+
function ng_blinkmask(clip clp,
45
\ bool "TEST",
46
\ bool "STABILIZE",
47-
function ng_blinkmask_new(clip c,int "ml"){
47+
\ bool "SHARP",
48-
    ml=default(ml,128)
48+
\ bool "HYSTER",
49-
    src=c.ConvertToYv12
49+
\ int "inpand",
50-
    super=MSuper(src, pel=1)
50+
\ int "expand",
51-
    fvec =MAnalyse(super, isb=false, blksize=4)
51+
\ int "ml"
52-
    bvec =MAnalyse(super, isb=true , blksize=4)
52+
\){
53-
    fmask=Mmask(src,fvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
53+
#Version 10 2012.04.22
54-
    bmask=Mmask(src,bvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
54+
55
#BLINK
56-
    eo0_to =fmask.selectevery(2,1)
56+
# Blinking is a block that alternates on/off each frame
57-
    oe_from=bmask.selectevery(2,1)
57+
# SelectEven would only see either the on or the off
58-
    front  =mt_logic(eo0_to,oe_from,mode="and")
58+
59
#FLASH
60-
    oe_to  =fmask.selectevery(2,2)
60+
# Flashing is a block that is only on for a single frame
61-
    eo_from=bmask.selectevery(2,2)
61+
# SelectEven might miss the flash
62-
    back   =mt_logic(oe_to,eo_from,mode="and")
62+
63
#SHAKE
64-
    ee_src=src.selecteven
64+
# Shaking is a block that moves back/forth each frame
65-
    ee_super=MSuper(ee_src, pel=1)
65+
# SelectEven would only see one position
66-
    ee_fvec =MAnalyse(ee_super, isb=false, blksize=4)
66+
67-
    ee_bvec =MAnalyse(ee_super, isb=true , blksize=4)
67+
# The goal of this function is to make a blink mask for use with
68-
    ee_fmask=Mmask(ee_src,ee_fvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
68+
# ng_deblink. For overly complicated scenes where a clean blinkmask
69-
    ee_bmask=Mmask(ee_src,ee_bvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
69+
# can't be found, just use TASBlend. Uniform softness looks better
70
# than sharp artifacts.
71-
    ee_to  =ee_fmask.trim(1,0)
71+
72-
    ee_from=ee_bmask
72+
# This function calculates flash and shake info for the test script,
73-
    ee     =mt_logic(ee_to,ee_from,mode="or")
73+
# but those effects should be handled in different ways.
74
# Flash - choose frames to make sure the flash is in your final clip.
75-
    oo_src=src.selectodd
75+
# Shake - SelectEvery(4,0,2,1,3) or SelectEvery(4,1,0,2,3)
76-
    oo_super=MSuper(oo_src, pel=1)
76+
# SelectEvery doesn't generally work because it messes with the fluidity
77-
    oo_fvec =MAnalyse(oo_super, isb=false, blksize=4)
77+
# of motion. But that won't be noticable on a shaking screen.
78-
    oo_bvec =MAnalyse(oo_super, isb=true , blksize=4)
78+
# Be careful if 2 frame blinking is present, as the selectevery can turn
79-
    oo_fmask=Mmask(oo_src,oo_fvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
79+
# it into 1 frame blinking.
80-
    oo_bmask=Mmask(oo_src,oo_bvec,kind=1,ml=ml).mt_binarize(u=-128,v=-128)
80+
81
    TEST      = default(     TEST, false)
82-
    oo_to  =oo_fmask.trim(1,0)
82+
    STABILIZE = default(STABILIZE, true)
83-
    oo_from=oo_bmask
83+
    SHARP     = default(    SHARP, true)
84-
    oo     =mt_logic(oo_to,oo_from,mode="or")
84+
    HYSTER    = default(   HYSTER, false)
85
    inpand    = default(   inpand, 1)
86-
    #to e0-o1, from o1-e2, nothing e0-e2
86+
    expand    = default(   expand, 1)
87-
    even_blink=mt_logic(front,ee.mt_invert,mode="and")
87+
    ml        = default(       ml, 128)
88
89-
    #to o1-e2, from e2-o3, nothing o1-o3
89+
# The functions used to make the masks work in the YV12 colorspace. Once
90-
    odd_blink =mt_logic(back,oo.mt_invert,mode="and")
90+
# the masks are created they can be used in the RGB32 colorspace direcly
91
    src=clp.ConvertToYV12()
92-
    interleave(even_blink, odd_blink).selectevery(1,-1)
92+
93
# Blinking is located by looking for blocks that don't exist in
94
# consecutive frames. The motion vector will match blocks that exist in
95
# both frames. The blocks that aren't in both will end up with huge
96
# values that are picked out by the motion mask.
97
    super = MSuper(src, pel=1)
98
    fvec  = MAnalyse(super, isb=false, blksize=4)
99
    bvec  = MAnalyse(super, isb=true , blksize=4)
100
    fmask = Mmask(src, fvec, kind=1, ml=ml).mt_binarize()
101
    bmask = Mmask(src, bvec, kind=1, ml=ml).mt_binarize()
102
    blink = mt_logic(fmask, bmask, mode="and")
103
104
# Blinking usually occurs against a stable background. This is found
105
# by looking at blocks 2 frames apart. This distinguishes a blink from
106
# blocks that are just changing every frame.
107
    ee_src   = src.SelectEven()
108
    ee_super = MSuper(ee_src, pel=1)
109
    ee_fvec  = MAnalyse(ee_super, isb=false, blksize=4)
110
    ee_bvec  = MAnalyse(ee_super, isb=true , blksize=4)
111
    ee_fmask = Mmask(ee_src, ee_fvec, kind=1, ml=ml).mt_binarize()
112
    ee_bmask = Mmask(ee_src, ee_bvec, kind=1, ml=ml).mt_binarize()
113
114
    oo_src   = src.SelectOdd()
115
    oo_super = MSuper(oo_src, pel=1)
116
    oo_fvec  = MAnalyse(oo_super, isb=false, blksize=4)
117
    oo_bvec  = MAnalyse(oo_super, isb=true , blksize=4)
118
    oo_fmask = Mmask(oo_src, oo_fvec, kind=1, ml=ml).mt_binarize()
119
    oo_bmask = Mmask(oo_src, oo_bvec, kind=1, ml=ml).mt_binarize()
120
121
    fmask_2   = Interleave(ee_fmask, oo_fmask)
122
    bmask_2   = Interleave(ee_bmask, oo_bmask)
123
    background = mt_logic(fmask_2.SelectEvery(1,1),
124
\                         bmask_2.SelectEvery(1,-1),
125
\                         mode="or")
126
    stable_blink = mt_hysteresis(background.mt_invert, blink)
127
    blink2 = (STABILIZE) ? stable_blink : blink
128
129
# Shrinking the blink mask can get rid of noise,
130
# too much will lose signal as well.
131
    blink3 = blink2.mt_inpand(mode=mt_diamond(inpand))
132
    
133
# Using just pixels that changed helps sharpen the mask
134
    diff   = ng_diff(clp.SelectEvery(1,-1), clp)
135
    diff_2 = mt_logic(diff, diff.SelectEvery(1,1), mode="and")
136
137
#Hysteresis
138
# Matches continuous blocks of pixels.
139
# Use with care, will match the whole screen on fades.
140
    hyster_blink = mt_hysteresis(blink3, diff_2)
141
142
# Expand the mask to make up for shrinking it (or just use hysteresis)
143
    blink4 = blink3.mt_expand(mode=mt_circle(expand))
144
    sharp_blink = mt_logic(blink4, diff_2, mode="and")
145
146
    blink5 = (HYSTER) ? hyster_blink :
147
\            (SHARP)  ? sharp_blink  : blink4
148
149
    
150
# A flash won't match blocks 1 or 2 frames away.
151
    sub_flash = mt_logic(fmask_2, bmask_2, mode="and")
152
    flash     = mt_logic(blink, sub_flash, mode="and")
153
    
154
# A shake changes in one frame and changes back in the next.
155
# This isn't detected by the motion vectors because the blocks exist in
156
# both frames, they are just shifting around.
157
    same   = ng_same(clp.SelectEvery(1,-1), clp.SelectEvery(1,1))
158
    shake  = mt_logic(same, diff_2, mode="and")
159
160
    (TEST) ? stackhorizontal(clp, mergeRGB(blink5, flash, shake))
161
\          : blink5.GreyScale()
162
}
163
164
function ng_diff(clip A, clip B, int "thr"){
165
    thr=default(thr,0)
166
    TAD=ng_TAD(A,B)
167
    return mt_binarize(TAD, threshold=thr)
168
}
169
170
function ng_same(clip A, clip B, int "thr"){
171
    thr=default(thr,0)
172
    TAD=ng_TAD(A,B)
173
    return mt_binarize(TAD, threshold=thr, upper=true)
174
}
175
176
function ng_TAD(clip A, clip B){
177
    R=ng_AD(A  .showRed("YV12"),B  .showRed("YV12"))
178
    G=ng_AD(A.showGreen("YV12"),B.showGreen("YV12"))
179
    B=ng_AD(A .showBlue("YV12"),B .showBlue("YV12"))
180
    return ng_plus(R, ng_plus(G, B))
181
}
182
183
function ng_AD(clip A, clip B){
184
    return mt_lutxy(A,B,"x y - abs")
185
}
186
187
function ng_plus(clip A, clip B){
188
    return mt_lutxy(A,B,"x y +")
189
}