View difference between Paste ID: gkBrBX7Z and f28Hu5EB
SHOW: | | - or go back to the newest paste.
1
# http://avisynth.nl/index.php/FineDehalo
2-
# 1.1 mod2
2+
# 1.1 mod3
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. See
8
# http://sam.zoy.org/wtfpl/COPYING for more details.
9
10-
Function FineDehalo (clip src, float "rx", float "ry", int "thmi", int "thma", int "thlimi", int "thlima", float "darkstr", float "brightstr", int "showmask", float "contra", bool "excl", float "edgeproc", string "exdehalo")
10+
Function FineDehalo (clip src, float "rx", float "ry", int "thmi", int "thma", int "thlimi", int "thlima", float "darkstr", float "brightstr", int "showmask", float "contra", bool "excl", float "edgeproc", val "exdehalo")
11
{
12
	rx        = Default (rx,          2)
13
	ry        = Default (ry,         rx)
14
	thmi      = Default (thmi,       80)
15
	thma      = Default (thma,      128)
16
	thlimi    = Default (thlimi,     50)
17
	thlima    = Default (thlima,    100)
18
	darkstr   = Default (darkstr,   1.0)
19
	brightstr = Default (brightstr, 1.0)
20
	showmask  = Default (showmask,    0)
21
	contra    = Default (contra,    0.0)
22
	excl      = Default (excl,     true)
23
	edgeproc  = Default (edgeproc,  0.0)
24
25
	rx_i = Round (rx)
26
	ry_i = Round (ry)
27
28
	src
29
30
31
	### Dehaloing ###
32
33-
	dehaloed = defined(exdehalo) ? eval("last." + exdehalo) : DeHalo_alpha (rx=rx, ry=ry, darkstr=darkstr, brightstr=brightstr)
33+
	dehaloed = defined(exdehalo) ? isclip(exdehalo) ? exdehalo : eval("last." + exdehalo) : DeHalo_alpha (rx=rx, ry=ry, darkstr=darkstr, brightstr=brightstr)
34
35
	# Contrasharpening
36
	dehaloed =   (contra > 0)
37
\	           ? dehaloed.FineDehalo_contrasharp (src, contra)
38
\	           : dehaloed
39
40
41
	### Main edges ###
42
43
	# Basic edge detection, thresholding will be applied later.
44
	edges = mt_edge (mode="prewitt", thY1=0, thY2=255)
45
46
	# Keeps only the sharpest edges (line edges)
47
	strong = edges.mt_lut (expr="x "+String(thmi)+" - "+String(thma-thmi)+" / 255 *")
48
49
	# Extends them to include the potential halos
50
	large = strong.mt_expand_multi (sw=rx_i, sh=ry_i)
51
52
53
	### Exclusion zones ###
54
55
	# When two edges are close from each other (both edges of a single
56
	# line or multiple parallel color bands), the halo removal
57
	# oversmoothes them or makes seriously bleed the bands, producing
58
	# annoying artifacts. Therefore we have to produce a mask to exclude
59
	# these zones from the halo removal.
60
61
	# Includes more edges than previously, but ignores simple details
62
	light = edges.mt_lut (expr="x "+String(thlimi)+" - "+String(thlima-thlimi)+" / 255 *")
63
64
	# To build the exclusion zone, we make grow the edge mask, then shrink
65
	# it to its original shape. During the growing stage, close adjacent
66
	# edge masks will join and merge, forming a solid area, which will
67
	# remain solid even after the shrinking stage.
68
69
	# Mask growing
70
	shrink = light.mt_expand_multi (sw=rx_i, sh=ry_i, mode="ellipse")
71
72
	# At this point, because the mask was made of a shades of grey, we may
73
	# end up with large areas of dark grey after shrinking. To avoid this,
74
	# we amplify and saturate the mask here (actually we could even
75
	# binarize it).
76
	shrink = shrink.mt_lut ("x 4 *")
77
78
	# Mask shrinking
79
	shrink = shrink.mt_inpand_multi (sw=rx_i, sh=ry_i, mode="ellipse")
80
81
	# This mask is almost binary, which will produce distinct
82
	# discontinuities once applied. Then we have to smooth it.
83
	shrink = shrink.RemoveGrain (20, -1)
84
	shrink = shrink.RemoveGrain (20, -1)
85
86
87
	### Final mask building ###
88
89
	# Previous mask may be a bit weak on the pure edge side, so we ensure
90
	# that the main edges are really excluded. We do not want them to be
91
	# smoothed by the halo removal.
92
	shr_med = (excl) ? mt_logic (strong, shrink, mode="max") : strong
93
94
	# Substracts masks and amplifies the difference to be sure we get 255
95
	# on the areas to be processed.
96
	outside = mt_lutxy (large, shr_med, "x y - 2 *")
97
98
	# If edge processing is required, adds the edgemask
99
	ep_str  = "x y "+String(edgeproc * 0.66)+" * +"
100
	outside = (edgeproc > 0) ? mt_lutxy (outside, strong, ep_str) : outside
101
102
	# Smooth again and amplify to grow the mask a bit, otherwise the halo
103
	# parts sticking to the edges could be missed.
104
	outside = outside.RemoveGrain (20, -1).mt_lut ("x 2 *")
105
106
	### Masking ###
107
108
	mt_merge (last, dehaloed, outside, y=3, u=2, v=2)
109
110
	  (showmask == 1) ? outside.GreyScale ()
111
\	: (showmask == 2) ? shrink.GreyScale ()
112
\	: (showmask == 3) ? edges.GreyScale ()
113
\	: (showmask == 4) ? strong.GreyScale ()
114
\	:                   last
115
}
116
117
# level == 1.0 : normal contrasharp
118
Function FineDehalo_contrasharp (clip dehaloed, clip src, float level)
119
{
120
	bb  = dehaloed.RemoveGrain (11, -1)
121
	bb2 = bb.Repair (bb.Repair (bb.Medianblur (2, -256, -256), 1), 1)
122
	xd  = mt_makediff (bb, bb2)
123
	xd  = xd.mt_lut ("x 128 - 2.49 * "+String(level)+" * 128 +")
124
	xdd = mt_lutxy (
125
\		xd,
126
\		mt_makediff (src, dehaloed),
127
\		"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?"
128
\	)
129
130
	dehaloed.mt_adddiff (xdd, y=3, u=2, v=2)
131
}
132
133
134
135
136
# Try to remove 2nd order halos.
137
Function FineDehalo2 (clip src, string "hconv", string "vconv", int "showmask")
138
{
139
	hconv    = Default (hconv, "-1 -2 0 0 40 0 0 -2 -1")
140
	vconv    = Default (vconv, "-2 -1 0 0 40 0 0 -1 -2")
141
	showmask = Default (showmask, 0)
142
143
	src
144
	fix_h = mt_convolution (horizontal="1", vertical=vconv, y=3, u=2, v=2)
145
	fix_v = mt_convolution (horizontal=hconv, vertical="1", y=3, u=2, v=2)
146
	edges_h = mt_edge (mode="1 2 1 0 0 0 -1 -2 -1", thY1=0, thY2=255)
147
	edges_v = mt_edge (mode="1 0 -1 2 0 -2 1 0 -1", thY1=0, thY2=255)
148
	mask_h = edges_h	#.mt_lut (expr="x 2 *")
149
	mask_v = edges_v	#.mt_lut (expr="x 2 *")
150
	temp_h = mt_lutxy (mask_h, mask_v, expr="x 3 * y -")
151
	temp_v = mt_lutxy (mask_v, mask_h, expr="x 3 * y -")
152
	mask_h = temp_h
153
	mask_v = temp_v
154
155
	mask_h = mask_h.FineDehalo2_grow_mask ("vertical")
156
	mask_v = mask_v.FineDehalo2_grow_mask ("horizontal")
157
158
	src
159
	mt_merge (last, fix_h, mask_h, y=3, u=2, v=2)
160
	mt_merge (last, fix_v, mask_v, y=3, u=2, v=2)
161
162
	  (showmask == 1) ? mt_logic (mask_h, mask_v, mode="max").GreyScale ()
163
\	:                   last
164
}
165
166
Function FineDehalo2_grow_mask (clip mask, string mode)
167
{
168
	Assert ((mode == "horizontal" || mode == "vertical"), "Wrong mode")
169
170
	mask
171
	mt_expand (mode=mode).mt_inpand (mode=mode)
172
	mask_1 = mt_expand (mode=mode)
173
	mask_2 = mask_1.mt_expand (mode=mode).mt_expand (mode=mode)
174
	mt_lutxy (mask_2, mask_1, expr="x y -")
175
	RemoveGrain (12, -1).mt_lut (expr="x 1.8 *")
176
}
177
178
Function FineDehaloanalog (clip src)
179
{
180
src
181-
FineDehalo(exdehalo="""DeHaloHmod(2,exdehalo="DeHalo_alpha_mt(darkstr=0.2,brightstr=0.8).VHSHaloremover(4,3,200,100,0.5)",thr=255,analog=true)""")
181+
edgm = EMask_dhh(ColorYUV(autogain=true), 3, 255,true)
182
hfil = DeHalo_alpha_mt(darkstr=0.2,brightstr=0.8).FineDehalo(exdehalo=DeHaloHmod(2,exdehalo="VHSHaloremover(4,3,200,100,0.5)",extmask=edgm))
183
RM2  = DR_Radius_dhh(edgm.mt_inflate(),2,0).mt_inflate()
184
DeRinging = mt_Merge(hfil, src, edgm.mt_inflate(155,155))
185
mt_Merge(src, DeRinging, RM2, u=2, v=2)
186
}