View difference between Paste ID: NamQ8g66 and Gz62Fhv9
SHOW: | | - or go back to the newest paste.
1
# FineDehalo
2-
# 1.1 mod8.7
2+
# 1.1 mod8.75
3
#
4
# This program is free software. It comes without any warranty, to
5
# the extent permitted by applicable law. You can redistribute it
6
# and/or modify it under the terms of the Do What The Fuck You Want
7
# To Public License, Version 2, as published by Sam Hocevar.
8
9
Function FineDehalo (clip src, float "rx", float "ry", float "thmi", float "thma", float "thlimi", float "thlima", float "darkstr", float "brightstr", int "showmask", float "contra", bool "excl", float "edgeproc", val "exdehalo", clip "exedgesm")
10
{
11
	rx        = Default (rx,          2)
12
	ry        = Default (ry,         rx)
13
	thmi      = Default (thmi,       80)
14
	thma      = Default (thma,      128)
15
	thlimi    = Default (thlimi,     50)
16
	thlima    = Default (thlima,    100)
17
	darkstr   = Default (darkstr,   1.0)
18
	brightstr = Default (brightstr, 1.0)
19
	showmask  = Default (showmask,    0)
20
	contra    = Default (contra,    0.0)
21
	excl      = Default (excl,     true)
22
	edgeproc  = Default (edgeproc,  0.0)
23
24
	rx_i = Round (rx)
25
	ry_i = Round (ry)
26
27
	src
28
29
30
	### Dehaloing ###
31
32
	dehaloed = defined(exdehalo) ? isclip(exdehalo) ? exdehalo : eval("last." + exdehalo) : DeHalo_alpha (rx=rx, ry=ry, darkstr=darkstr, brightstr=brightstr)
33
34
	# Contrasharpening
35
	dehaloed =   (contra > 0)
36
\	           ? dehaloed.FineDehalo_contrasharp (src, contra)
37
\	           : dehaloed
38
39
	edgesm = defined(exedgesm) ? exedgesm : FineDehaloedges(rx=rx, ry=ry, thmi=thmi, thma=thma, thlimi=thlimi, thlima=thlima, showmask=showmask, excl=excl, edgeproc=edgeproc)
40
41
	### Masking ###
42
43
		  (showmask != 0) ? edgesm
44
	\	:                   mt_merge (last, dehaloed, edgesm, y=3, u=2, v=2)
45
}
46
47
# level == 1.0 : normal contrasharp
48
Function FineDehalo_contrasharp (clip dehaloed, clip src, float level)
49
{
50
	bb  = dehaloed.RemoveGrain (11, -1)
51
	bb2 = bb.Repair (bb.Repair (bb.Medianblur (2, -256, -256), 1), 1)
52
	xd  = mt_makediff (bb, bb2)
53
	xd  = VersionNumber() < 2.6 ? xd.mt_lut ("x 128 - 2.49 * "+String(level)+" * 128 +")
54
              \                     : xd.mt_lut ("x range_half - 2.49 * "+String(level)+" * range_half +", use_expr=2)
55
	xdd = VersionNumber() < 2.6 ? mt_lutxy (
56
\		xd,
57
\		mt_makediff (src, dehaloed),
58
\		"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?"
59
\	) : mt_lutxy (
60
\		xd,
61
\		mt_makediff (src, dehaloed),
62
\		"x range_half - y range_half - * 0 < range_half x range_half - abs y range_half - abs < x y ? ?", use_expr=2
63
\	)
64
65
	dehaloed.mt_adddiff (xdd, y=3, u=2, v=2)
66
}
67
68
# moved FineDehalo edges mask in stand-alone Function
69
Function FineDehaloedges (clip src, float "rx", float "ry", float "thmi", float "thma", float "thlimi", float "thlima", int "showmask", bool "excl", float "edgeproc", clip "edgemask")
70
{
71
	rx        = Default (rx,          2)
72
	ry        = Default (ry,         rx)
73
	thmi      = Default (thmi,       80)
74
	thma      = Default (thma,      128)
75
	thlimi    = Default (thlimi,     50)
76
	thlima    = Default (thlima,    100)
77
	showmask  = Default (showmask,    0)
78
	excl      = Default (excl,     true)
79
	edgeproc  = Default (edgeproc,  0.0)
80
81
	rx_i = Round (rx)
82
	ry_i = Round (ry)
83
84
	src
85
86
	### Main edges ###
87
88
	# Basic edge detection, thresholding will be applied later.
89
	edges = defined(edgemask) ? edgemask : mt_edge (mode="prewitt", thY1=0, thY2=255)
90
91
	# Keeps only the sharpest edges (line edges)
92
	strong = VersionNumber() < 2.6 ? edges.mt_lut (expr="x "+String(thmi)+" - "+String(thma-thmi)+" / 255 *")
93
                 \                     : edges.mt_lut (expr="x "+String(thmi)+" scalef - "+String(thma-thmi)+" scalef / range_max *", scale_inputs="floatf", use_expr=2)
94
95
	# Extends them to include the potential halos
96
	large = strong.mt_expand_multi (sw=rx_i, sh=ry_i)
97
98
99
	### Exclusion zones ###
100
101
	# When two edges are close from each other (both edges of a single
102
	# line or multiple parallel color bands), the halo removal
103
	# oversmoothes them or makes seriously bleed the bands, producing
104
	# annoying artifacts. Therefore we have to produce a mask to exclude
105
	# these zones from the halo removal.
106
107
	# Includes more edges than previously, but ignores simple details
108
	light = VersionNumber() < 2.6 ? edges.mt_lut (expr="x "+String(thlimi)+" - "+String(thlima-thlimi)+" / 255 *")
109
                \                     : edges.mt_lut (expr="x "+String(thlimi)+" scalef - "+String(thlima-thlimi)+" scalef / range_max *", scale_inputs="floatf", use_expr=2)
110
111
	# To build the exclusion zone, we make grow the edge mask, then shrink
112
	# it to its original shape. During the growing stage, close adjacent
113
	# edge masks will join and merge, forming a solid area, which will
114
	# remain solid even after the shrinking stage.
115
116
	# Mask growing
117
	shrink = light.mt_expand_multi (sw=rx_i, sh=ry_i, mode="ellipse")
118
119
	# At this point, because the mask was made of a shades of grey, we may
120
	# end up with large areas of dark grey after shrinking. To avoid this,
121
	# we amplify and saturate the mask here (actually we could even
122
	# binarize it).
123
	shrink = VersionNumber() < 2.6 ? shrink.mt_lut ("x 4 *")
124
                 \                     : shrink.mt_lut ("x 4 *", clamp_float=true, use_expr=2)
125
126
	# Mask shrinking
127
	shrink = shrink.mt_inpand_multi (sw=rx_i, sh=ry_i, mode="ellipse")
128
129
	# This mask is almost binary, which will produce distinct
130
	# discontinuities once applied. Then we have to smooth it.
131
	shrink = shrink.RemoveGrain (20, -1)
132
	shrink = shrink.RemoveGrain (20, -1)
133
134
135
	### Final mask building ###
136
137
	# Previous mask may be a bit weak on the pure edge side, so we ensure
138
	# that the main edges are really excluded. We do not want them to be
139
	# smoothed by the halo removal.
140
	shr_med = (excl) ? mt_logic (strong, shrink, mode="max") : strong
141
142
	# Substracts masks and amplifies the difference to be sure we get 255
143
	# on the areas to be processed.
144
	outside = VersionNumber() < 2.6 ? mt_lutxy (large, shr_med, "x y - 2 *")
145
                  \                     : mt_lutxy (large, shr_med, "x y - 2 *", clamp_float=true, use_expr=1)
146
147
	# If edge processing is required, adds the edgemask
148
	outside = (edgeproc > 0) ? VersionNumber() < 2.6 ? mt_lutxy(outside, strong, "x y "+String(edgeproc * 0.66)+" * +") : mt_lutxy(outside, strong, "x y "+String(edgeproc * 0.66)+" * +", clamp_float=true, use_expr=1) : outside
149
150
	# Smooth again and amplify to grow the mask a bit, otherwise the halo
151
	# parts sticking to the edges could be missed.
152
	VersionNumber() < 2.6 ? outside.RemoveGrain (20, -1).mt_lut ("x 2 *")
153
        \                     : outside.RemoveGrain (20, -1).mt_lut ("x 2 *", clamp_float=true, use_expr=1)
154
155
	  (showmask == 1) ? outside.GreyScale ()
156
\	: (showmask == 2) ? shrink.GreyScale ()
157
\	: (showmask == 3) ? edges.GreyScale ()
158
\	: (showmask == 4) ? strong.GreyScale ()
159
\	:                   last
160
}
161
162
163
164
# Try to remove 2nd order halos.
165
Function FineDehalo2 (clip src, string "hconv", string "vconv", int "showmask")
166
{
167
	hconv    = Default (hconv, "-1 -2 0 0 40 0 0 -2 -1")
168
	vconv    = Default (vconv, "-2 -1 0 0 40 0 0 -1 -2")
169
	showmask = Default (showmask, 0)
170
171
	src
172
	fix_h = mt_convolution (horizontal="1", vertical=vconv, y=3, u=2, v=2)
173
	fix_v = mt_convolution (horizontal=hconv, vertical="1", y=3, u=2, v=2)
174
	edges_h = mt_edge (mode="1 2 1 0 0 0 -1 -2 -1", thY1=0, thY2=255)
175
	edges_v = mt_edge (mode="1 0 -1 2 0 -2 1 0 -1", thY1=0, thY2=255)
176
	mask_h = edges_h	#.mt_lut (expr="x 2 *")
177
	mask_v = edges_v	#.mt_lut (expr="x 2 *")
178
	temp_h = VersionNumber() < 2.6 ? mt_lutxy (mask_h, mask_v, expr="x 3 * y -")
179
                 \	               : mt_lutxy (mask_h, mask_v, expr="x 3 * y -", clamp_float=true, use_expr=1)
180
	temp_v = VersionNumber() < 2.6 ? mt_lutxy (mask_v, mask_h, expr="x 3 * y -")
181
                 \	               : mt_lutxy (mask_v, mask_h, expr="x 3 * y -", clamp_float=true, use_expr=1)
182
	mask_h = temp_h
183
	mask_v = temp_v
184
185
	mask_h = mask_h.FineDehalo2_grow_mask ("vertical")
186
	mask_v = mask_v.FineDehalo2_grow_mask ("horizontal")
187
188
	src
189
	mt_merge (last, fix_h, mask_h, y=3, u=2, v=2)
190
	mt_merge (last, fix_v, mask_v, y=3, u=2, v=2)
191
192
	  (showmask == 1) ? mt_logic (mask_h, mask_v, mode="max").GreyScale ()
193
\	:                   last
194
}
195
196
Function FineDehalo2_grow_mask (clip mask, string mode)
197
{
198
	Assert ((mode == "horizontal" || mode == "vertical"), "Wrong mode")
199
200
	mask
201
	mt_expand (mode=mode).mt_inpand (mode=mode)
202
	mask_1 = mt_expand (mode=mode)
203
	mask_2 = mask_1.mt_expand (mode=mode).mt_expand (mode=mode)
204
	VersionNumber() < 2.6 ? mt_lutxy (mask_2, mask_1, expr="x y -")
205
        \		      : mt_lutxy (mask_2, mask_1, expr="x y -", clamp_float=true, use_expr=1)
206
	VersionNumber() < 2.6 ? RemoveGrain (12, -1).mt_lut (expr="x 1.8 *")
207-
        \		      : RemoveGrain (12, -1).mt_lut (expr="x 1.8 *", clamp_float=true", use_expr=2)
207+
        \		      : RemoveGrain (12, -1).mt_lut (expr="x 1.8 *", clamp_float=true, use_expr=2)
208
}
209
210
211
# new Functions added to the mod ver.
212
213
214
Function FineDehaloanalog (clip src, int "dhhradius", float "arx", float "ary", string "exdehalo", clip "fexedgesm", clip "linesm", bool "remasked", float "darkstr", float "brightstr")
215
{
216
rx       = Default (arx,          2) # DeHalo_alpha rx
217
ry       = Default (ary,         rx) # DeHalo_alpha ry
218
edgm     = Defined(linesm) ? linesm : src.slinesm()
219
rad      = Default(dhhradius,      2)
220
remasked = Default(remasked, true)
221
blurmix  = remasked ? 0.5 : 0.8
222
	rx_i = Round (rx)
223
	ry_i = Round (ry)
224
exdehalo = Default(exdehalo, "VHSHaloremover("+String(rx_i)+","+String(ry_i)+",200,100,"+String(blurmix)+")")
225
useldh   = !defined(darkstr) && !defined(brightstr) && !defined(arx) && !defined(ary)
226
227
src
228
lightdh = DeHalo_alpha_mt(rx=rx_i,ry=ry_i,darkstr=0.2,brightstr=0.8)
229
FDedges = Defined(fexedgesm) ? fexedgesm : lightdh.FineDehaloedges(rx=rx_i,ry=ry_i)
230
alphadh = remasked ? lightdh : \ 
231
                     FineDehalo(rx=rx,ry=ry,exdehalo=useldh ? lightdh : \
232
                                                              undefined(),darkstr=darkstr,brightstr=brightstr,exedgesm=FDedges)
233
234
hfil = alphadh.FineDehalo(rx=rx,ry=ry,exdehalo=DeHaloHmod(rad,exdehalo=exdehalo,extmask=edgm), exedgesm=FDedges)
235
RM2  = remasked ? DR_Radius_dhh(edgm.mt_inflate(),rad,0).mt_inflate() : nop()
236
237
DeRinging = mt_Merge(hfil, src, edgm.mt_inflate(155,155),u=remasked ? 1 : 4,v=remasked ? 1 : 4)
238
remasked ? mt_Merge(src, DeRinging, RM2, u=2, v=2) : DeRinging
239
}
240
241
# filtering with black borders by A.SONY
242
Function filtering_wbb (clip src, string "filter", int "oneborder", clip "linesm", clip "clip4lines", int "mmy", bool "mmLuma", int "mmuv", bool "minflate")
243
{
244
filtering_wsb(src,filter,oneborder,linesm,clip4lines,mmy,mmLuma,mmuv,minflate)
245
}
246
247
# black lines mask by A.SONY
248
Function slinesm (clip i, float "thr", float "thr2", bool "analog", bool "autogain", val "edgesm", int "useMedianBlur", bool "noedges", float "mblur", float "thrfade", bool "honly", bool "lumaonly")
249
{
250
analog        = Default(analog,   true)
251
autogain      = Default(autogain, true)
252
noedges       = Default(noedges,  false)
253
mblur         = Default(mblur, 0.1)
254
thr           = Default(thr, mblur==0 ? 100 : 200)
255
thr2          = Default(thr2, 170)
256
thrfade       = Default(thrfade, 2.46)
257
useMedianBlur = default(useMedianBlur, -1)
258
lumaonly      = default(lumaonly, true)
259
260
sisphbd = AvsPlusVersionNumber > 2294
261
262
oi          = autogain ? i.ColorYUV(autogain=true) : i
263
sislumaonly = sisphbd ? oi.isy() : VersionNumber() < 2.6 ? true : oi.isy8()
264
i = sislumaonly || !lumaonly ? oi : sisphbd ? oi.converttoy() : oi.converttoy8()
265
266
edgesm     = !noedges ? defined(edgesm) ? isclip(edgesm) ? edgesm : eval("i." + edgesm) : i.Camembert_dhh(useMedianBlur,honly,lumaonly) : nop()
267
268
edgesm     = !noedges ? defined(edgesm) ? isclip(edgesm) ? edgesm : eval("i." + edgesm) : i.Camembert_dhh(useMedianBlur) : nop()
269
270
LineDarkenclip = thr==0 ? nop() : mblur==0 ? i.FastLineDarkenMOD3_dhh(thr) : i.FastLineDarkenMOD3_dhh(thr).blur(mblur)
271
LineDarkenclip = thr==0 ? i : LineDarkenclip.FastLineDarkenMOD3_dhh(250,1,250,-2)
272
273
thr1 = analog ? thr2/thrfade : nop()
274
lut4dark   = analog ? VersionNumber() < 2.6 ? LineDarkenclip.mt_lut("x "+String(thr1)+" < 255 x "+String(thr2)+" > 0 255 x "+String(thr1)+" - 255 "+String(thr2)+" "+String(thr1)+" - / * - ? ?",u=1,v=1) : LineDarkenclip.mt_lut("x "+String(thr1)+" scalef < range_max x "+String(thr2)+" scalef > 0 range_max x "+String(thr1)+" scalef - range_max "+String(thr2)+" scalef "+String(thr1)+" scalef - / * - ? ?", use_expr=2,u=1,v=1) : 
275
                    \ LineDarkenclip.mt_binarize(70, mode="0 255")
276
277
noedges ? lut4dark : 
278
        \ mt_merge(i.mt_edge(mode="min/max", thY1=255, thY2=255), edgesm, lut4dark)
279
sislumaonly ? last : sisphbd ? CombinePlanes(last,oi,planes="YUV",sample_clip=oi) : YToUV(oi.UToY8(),oi.VToY8(),last)
280
}
281
282
# tophf lines mask
283
function t_linemask( clip c, int "blur", float "thresh", float "str" )
284
{
285
	blur=default(blur,5)
286
	thresh=default(thresh,4)
287
	str=default(str,16)
288
	VersionNumber() < 2.6 ? mt_lutxy(c,c.binomialblur(blur,u=1,v=1),"x "+string(thresh)+" + y < y x - "+string(str)+" * 0 ?")
289
        \                     : mt_lutxy(c,c.binomialblur(blur,u=1,v=1),"x "+string(thresh)+" scalef + y < y x - "+string(str)+" * 0 ?", clamp_float=true, use_expr=2)
290
}
291
292
# white lines mask by A.SONY
293
Function swlinesm (clip i, float "thr", float "thr2", bool "analog", bool "autogain", val "edgesm", int "useMedianBlur", bool "noedges", float "mblur", float "thrfade", float "bthr", bool "honly", bool "lumaonly")
294
{
295
analog        = Default(analog,   true)
296
autogain      = Default(autogain, true)
297
noedges       = Default(noedges,  false)
298
mblur         = Default(mblur, 0.1)
299
thr           = Default(thr, mblur==0 ? 100 : 200)
300
bthr          = Default(bthr, thr)
301
thr2          = Default(thr2, 200)
302
thrfade       = Default(thrfade, 2.46)
303
useMedianBlur = default(useMedianBlur, -1)
304
lumaonly      = default(lumaonly, true)
305
306
sisphbd = AvsPlusVersionNumber > 2294
307
308
oi          = autogain ? i.ColorYUV(autogain=true) : i
309
sislumaonly = sisphbd ? oi.isy() : VersionNumber() < 2.6 ? true : oi.isy8()
310
i = sislumaonly || !lumaonly ? oi : sisphbd ? oi.converttoy() : oi.converttoy8()
311
312
edgesm     = !noedges ? defined(edgesm) ? isclip(edgesm) ? edgesm : eval("i." + edgesm) : i.Camembert_dhh(useMedianBlur,honly,lumaonly) : nop()
313
314
LineDarkenclip = bthr==0 ? i : mblur==0 ? i.FastLineDarkenMOD3_dhh(bthr) : i.FastLineDarkenMOD3_dhh(bthr).blur(mblur)
315
Linewhitenclip = thr==0 ? nop() : mblur==0 ? LineDarkenclip.mt_invert().FastLineDarkenMOD3_dhh(thr) : LineDarkenclip.mt_invert().FastLineDarkenMOD3_dhh(thr).blur(mblur)
316
Linewhitenclip = thr==0 ? i : Linewhitenclip.FastLineDarkenMOD3_dhh(250,1,250,-2).mt_invert()
317
318
thr1 = analog ? thr2/thrfade : nop()
319
lut4whit   = analog ? VersionNumber() < 2.6 ? Linewhitenclip.mt_lut("x "+String(thr2)+" > 255 x "+String(thr1)+" < 0 255 x "+String(thr1)+" - 255 "+String(thr2)+" "+String(thr1)+" - / * - ? ?",u=1,v=1) : Linewhitenclip.mt_lut("x "+String(thr2)+" scalef > range_max x "+String(thr1)+" scalef < 0 range_max x "+String(thr1)+" scalef - range_max "+String(thr2)+" scalef "+String(thr1)+" scalef - / * - ? ?",use_expr=2,u=1,v=1) : 
320
                    \ Linewhitenclip.mt_binarize(128, mode="255 0")
321
322
noedges ? lut4whit : 
323
        \ mt_merge(i.mt_edge(mode="min/max", thY1=255, thY2=255), edgesm, lut4whit)
324
sislumaonly ? last : sisphbd ? CombinePlanes(last,oi,planes="YUV",sample_clip=oi) : YToUV(oi.UToY8(),oi.VToY8(),last)
325
}