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