SHOW:
|
|
- or go back to the newest paste.
1 | ################################################################################################################## | |
2 | # | |
3 | - | # High bitdepth tools for Avisynth - GradFun3mod r6 mod 2 |
3 | + | # High bitdepth tools for Avisynth - GradFun3mod r6 mod 3 |
4 | # based on Dither v1.27.1 | |
5 | # Author: Firesledge, slightly modified by Gebbi | |
6 | # | |
7 | # What? | |
8 | # - This is a slightly modified version of the original GradFun3. | |
9 | # - It combines the usual color banding removal stuff with resizers during the process | |
10 | # for sexier results (less detail loss, especially for downscales of cartoons). | |
11 | # - This is a starter script, not everything is covered through parameters. Modify it to your needs. | |
12 | # | |
13 | # Requirements (in addition to the Dither requirements): | |
14 | # - AviSynth 2.6.x | |
15 | # - Debilinear, Debicubic, DebilinearM | |
16 | # - NNEDI3 + nnedi3_resize16 | |
17 | # | |
18 | # Changes from the original GradFun3: | |
19 | # - yuv444 = true | |
20 | # (4:2:0 -> 4:4:4 colorspace conversion, needs 1920x1080 input) | |
21 | - | # - resizer = [ "none", "Debilinear", "DebilinearM", "Debicubic", "DebicubicM", "Spline16", |
21 | + | # - resizer = [ "none", "Debilinear", "DebilinearMT", "DebilinearM", "DebilinearMTM", "Debicubic", "DebicubicMT", "DebicubicM", "DebicubicMTM", "Spline16", |
22 | - | # "Spline36", "Spline64", "lineart_rpow2", "lineart_rpow2_bicubic" ] |
22 | + | # "Spline36", "Spline64", "lineart_rpow2", "lineart_rpow2_bicubic", "lineart_rpow2MT", "lineart_rpow2_bicubicMT" ] |
23 | # (use it only for downscales) | |
24 | # NOTE: As of r2 Debicubic doesn't have 16-bit precision, so a Y (luma) plane fix by torch is used here, | |
25 | # more info: https://mechaweaponsvidya.wordpress.com/2015/07/07/a-precise-debicubic/ | |
26 | # Without yuv444=true Dither_resize16 is used with an inverse bicubic kernel. | |
27 | # - w = 1280, h = 720 | |
28 | # (output width & height for the resizers; or production resolution for resizer="lineart_rpow2") | |
29 | # - smode = 4 | |
30 | # (the old GradFun3mod behaviour for legacy reasons; based on smode = 1 (dfttest); | |
31 | # not useful anymore in most cases, use smode = 2 instead (less detail loss)) | |
32 | # - deb = true | |
33 | # (legacy parameter; same as resizer = "DebilinearM") | |
34 | # | |
35 | # Usage examples: | |
36 | # - Source is bilinear 720p->1080p upscale (BD) with 1080p credits overlayed, | |
37 | # revert the upscale without fucking up the credits: | |
38 | # lwlibavvideosource("lol.m2ts") | |
39 | # GradFun3mod(smode=1, yuv444=true, resizer="DebilinearM") | |
40 | # | |
41 | # - You just want to get rid off the banding without changing the resolution: | |
42 | # GradFun3(smode=2) | |
43 | # | |
44 | # - Source is 1080p production (BD), downscale to 720p: | |
45 | # GradFun3mod(smode=2, yuv444=true, resizer="Spline36") | |
46 | # | |
47 | # - Source is a HDTV transportstream (or CR or whatever), downscale to 720p: | |
48 | # GradFun3mod(smode=2, resizer="Spline36") | |
49 | # | |
50 | # - Source is anime, 720p->1080p upscale, keep the resolution | |
51 | # but with smoother lineart instead of bilinear upscaled shit: | |
52 | # GradFun3mod(smode=2, resizer="lineart_rpow2") | |
53 | # This won't actually resize the video but instead mask the lineart and re-upscale it using | |
54 | # nnedi3_rpow2 which often results in much better looking lineart (script mostly by Daiz). | |
55 | # | |
56 | # Note: Those examples don't include parameters like thr, radius, elast, mode, ampo, ampn, staticnoise. | |
57 | # You probably don't want to use the default values. | |
58 | # For 16-bit output use: | |
59 | # GradFun3mod(lsb=true).Dither_out() | |
60 | # | |
61 | # What's the production resolution of my korean cartoon? | |
62 | # - Use your eyes combined with Debilinear(1280,720) - if it looks like oversharped shit, | |
63 | # it was probably produced in a higher resolution. | |
64 | # - Use Debilinear(1280,720).BilinearResize(1920,1080) for detail loss search. | |
65 | # - Alternatively you can lookup the (estimated) production resolution at | |
66 | # http://anibin.blogspot.com (but don't blindly trust those results) | |
67 | # | |
68 | # This program is free software. It comes without any warranty, to | |
69 | # the extent permitted by applicable law. You can redistribute it | |
70 | # and/or modify it under the terms of the Do What The Fuck You Want | |
71 | # To Public License, Version 2, as published by Sam Hocevar. See | |
72 | # http://sam.zoy.org/wtfpl/COPYING for more details. | |
73 | # | |
74 | ################################################################################################################## | |
75 | ||
76 | ||
77 | Function GradFun3mod (clip src, float "thr", int "radius", float "elast", | |
78 | \ int "mask", int "mode", float "ampo", float "ampn", int "pat", | |
79 | \ bool "dyn", float "dthr", int "smode", float "wmin", float "thr_det", | |
80 | \ float "thr_edg", int "debug", int "subspl", bool "lsb", bool "lsb_in", | |
81 | \ bool "staticnoise", float "thrc", int "radiusc", float "elastc", | |
82 | \ int "y", int "u", int "v", clip "ref", bool "slice", bool "yuv444", int "w", int "h", string "resizer", bool "deb") | |
83 | { | |
84 | thr = Default (thr, 0.35) | |
85 | thrc = Default (thrc, thr) | |
86 | radius = Default (radius, 12) | |
87 | radiusc = Default (radiusc, radius) | |
88 | elast = Default (elast, 3.0) | |
89 | elastc = Default (elastc, elast) | |
90 | mask = Default (mask, 2) | |
91 | smode = Default (smode, 2) | |
92 | wmin = Default (wmin, 1.0) | |
93 | thr_det = Default (thr_det, 2 + Round (Dither_max (thr - 0.35, 0) / 0.3)) | |
94 | debug = Default (debug, 0) | |
95 | subspl = Default (subspl, 0) | |
96 | lsb = Default (lsb, false) | |
97 | lsb_in = Default (lsb_in, false) | |
98 | ref = Default (ref, src) | |
99 | yuv444 = Default (yuv444, false) | |
100 | w = Default (w, 1280) | |
101 | h = Default (h, 720) | |
102 | resizer = Default (resizer, "none") | |
103 | deb = Default (deb, false) | |
104 | ||
105 | ||
106 | # Do lineart smoothing first for sharper results | |
107 | ||
108 | ow = src.Width() | |
109 | oh = src.Height() | |
110 | ||
111 | - | src = (resizer == "lineart_rpow2") ? lineart_rpow2(src, w, h, ow, oh, false) |
111 | + | src = (resizer == "lineart_rpow2") ? lineart_rpow2(src, w, h, ow, oh, false, false) |
112 | - | \ : (resizer == "lineart_rpow2_bicubic") ? lineart_rpow2(src, w, h, ow, oh, true) |
112 | + | \ : (resizer == "lineart_rpow2MT") ? lineart_rpow2(src, w, h, ow, oh, true, true) |
113 | \ : (resizer == "lineart_rpow2_bicubic") ? lineart_rpow2(src, w, h, ow, oh, true, false) | |
114 | \ : (resizer == "lineart_rpow2_bicubicMT") ? lineart_rpow2(src, w, h, ow, oh, true, true) | |
115 | \ : src | |
116 | ||
117 | # Input range check. The other parameters are checked by the plugins. | |
118 | Assert (radius > 0, "GradFun3: "+chr(34)+"radius" +chr(34)+" must be strictly positive.") | |
119 | Assert (radiusc > 0, "GradFun3: "+chr(34)+"radiusc"+chr(34)+" must be strictly positive.") | |
120 | Assert (thr > 0, "GradFun3: "+chr(34)+"thr" +chr(34)+" must be strictly positive.") | |
121 | Assert (thrc > 0, "GradFun3: "+chr(34)+"thrc" +chr(34)+" must be strictly positive.") | |
122 | Assert (thr_det > 0, "GradFun3: "+chr(34)+"thr_det"+chr(34)+" must be strictly positive.") | |
123 | - | (yuv444 && resizer != "lineart_rpow2" && resizer != "lineart_rpow2_bicubic") ? Assert (w == 1280, "GradFun3mod: Output resolution must be 1280x720 when using 4:4:4 colorspace.") : true |
123 | + | |
124 | - | (yuv444 && resizer != "lineart_rpow2" && resizer != "lineart_rpow2_bicubic") ? Assert (h == 720, "GradFun3mod: Output resolution must be 1280x720 when using 4:4:4 colorspace.") : true |
124 | + | |
125 | (yuv444 && resizer != "lineart_rpow2" && resizer != "lineart_rpow2_bicubic" && resizer != "lineart_rpow2MT" && resizer != "lineart_rpow2_bicubicMT") ? Assert (w == 1280, "GradFun3mod: Output resolution must be 1280x720 when using 4:4:4 colorspace.") : true | |
126 | (yuv444 && resizer != "lineart_rpow2" && resizer != "lineart_rpow2_bicubic" && resizer != "lineart_rpow2MT" && resizer != "lineart_rpow2_bicubicMT") ? Assert (h == 720, "GradFun3mod: Output resolution must be 1280x720 when using 4:4:4 colorspace.") : true | |
127 | ||
128 | src_8 = (lsb_in) ? src.DitherPost (mode=-1) : src | |
129 | src_16 = (lsb_in) ? src : src.Dither_convert_8_to_16 () | |
130 | ref_16 = (lsb_in) ? ref : ref.Dither_convert_8_to_16 () | |
131 | yv411_flag = src.Dither_isyv411 () | |
132 | ||
133 | # Main debanding | |
134 | ||
135 | yp = (! Defined (y) || (y == 3)) ? 3 : 1 | |
136 | up = (! Defined (u) || (u == 3)) ? 3 : 1 | |
137 | vp = (! Defined (v) || (v == 3)) ? 3 : 1 | |
138 | ||
139 | chroma_flag = ( (thrc != thr || radiusc != radius || elastc != elast) | |
140 | \ && yp == 3 && (up == 3 || vp == 3)) | |
141 | up2 = (chroma_flag) ? 1 : up | |
142 | vp2 = (chroma_flag) ? 1 : vp | |
143 | ||
144 | src_16 | |
145 | flt_y = Dither_gf3_smooth_mod (last, src_8, ref_16, smode, radius, thr, elast, lsb_in, wmin, subspl, yp, up2, vp2) | |
146 | flt_c = (chroma_flag) ? Dither_gf3_smooth_mod (last, src_8, ref_16, smode, radiusc, thrc, elastc, lsb_in, wmin, subspl, 1, up, vp) : flt_y | |
147 | flt = (chroma_flag) ? flt_y.MergeChroma (flt_c) : flt_y | |
148 | ||
149 | # Edge/detail mask | |
150 | ||
151 | td_lo = Dither_max (thr_det * 0.75, 1) | |
152 | td_hi = Dither_max (thr_det, 1) | |
153 | mexpr = Dither_make_expr_gate (td_lo, td_hi) | |
154 | ||
155 | dmask = (mask > 0 && yv411_flag) ? src_8.ConvertToY8 () : src_8 | |
156 | dmask = (mask > 0) ? dmask.Dither_build_gf3_range_mask (mask) : dmask | |
157 | dmask = (mask > 0) ? dmask.mt_lut (expr=mexpr) : dmask | |
158 | dmask = (mask > 0) ? dmask.Dither_removegrain_emul (22, -1) : dmask | |
159 | dmask = (mask > 1) ? dmask.Dither_removegrain_emul (11, -1) : dmask | |
160 | dmask = (mask > 2) ? dmask.Dither_removegrain_emul (20, -1) : dmask | |
161 | dmask = (mask > 0 && yv411_flag) ? dmask.ConvertToYV411 () : dmask | |
162 | ||
163 | res_16 = (mask > 0) ? Dither_merge16_8 (flt, src_16, dmask, luma=true, y=yp, u=up, v=vp) : flt | |
164 | ||
165 | # Resizing / colorspace conversion (GradFun3mod) | |
166 | ||
167 | resizer = (deb) ? "DebilinearM" : resizer | |
168 | resizer = (yuv444 && resizer == "none") ? "Spline36" : resizer | |
169 | ||
170 | rkernel = (resizer == "Debilinear" && yuv444) ? res_16.DebilinearY(w,h,lsb_inout=true) | |
171 | \ : (resizer == "Debilinear") ? res_16.Debilinear(w,h,lsb_inout=true) | |
172 | \ : (resizer == "DebilinearMT" && yuv444) ? res_16.ResizeX(w, h, desampling=true, kernel="Bilinear",lsb_in=true,lsb_out=true) | |
173 | \ : (resizer == "DebilinearMT") ? res_16.ResizeX(w, h, desampling=true, kernel="Bilinear",lsb_in=true,lsb_out=true) | |
174 | \ : (resizer == "DebilinearM" && yuv444) ? res_16.DebilinearM(w,h,lsb_inout=true,chroma=false) | |
175 | \ : (resizer == "DebilinearM") ? res_16.DebilinearM(w,h,lsb_inout=true) | |
176 | \ : (resizer == "DebilinearMTM" && yuv444) ? res_16.DebilinearM(w,h,lsb_inout=true,chroma=false, DeResizeMT=true) | |
177 | \ : (resizer == "DebilinearMTM") ? res_16.DebilinearM(w,h,lsb_inout=true, DeResizeMT=true) | |
178 | \ : (resizer == "Debicubic" && yuv444) ? res_16.debicubicy_precise(w,h) | |
179 | \ : (resizer == "Debicubic") ? res_16.Dither_resize16(w,h,kernel="bicubic",invksh=true,fh=1.3,fv=1.3,invkstaps=7) | |
180 | \ : (resizer == "DebicubicMT" && yuv444) ? res_16.debicubicy_precise(w,h, DeResizeMT=true) | |
181 | \ : (resizer == "DebicubicMT") ? res_16.Dither_resize16(w,h,kernel="bicubic",invksh=true,fh=1.3,fv=1.3,invkstaps=7) | |
182 | \ : (resizer == "DebicubicM" && yuv444) ? res_16.DebicubicM_precise16(w,h,chroma=false) | |
183 | \ : (resizer == "DebicubicM") ? res_16.DebicubicM_precise16(w,h) | |
184 | \ : (resizer == "DebicubicMMT" && yuv444) ? res_16.DebicubicM_precise16(w,h,chroma=false, DeResizeMT=true) | |
185 | \ : (resizer == "DebicubicMMT") ? res_16.DebicubicM_precise16(w,h, DeResizeMT=true) | |
186 | \ : (resizer == "Spline16" && yuv444) ? res_16.Dither_resize16(w,h,kernel="spline16",fh=1.2,fv=1.2).ConvertToY8() | |
187 | \ : (resizer == "Spline16") ? res_16.Dither_resize16(w,h,kernel="spline16",fh=1.2,fv=1.2) | |
188 | \ : (resizer == "Spline36" && yuv444) ? res_16.Dither_resize16(w,h,kernel="spline36",fh=1.2,fv=1.2).ConvertToY8() | |
189 | \ : (resizer == "Spline36") ? res_16.Dither_resize16(w,h,kernel="spline36",fh=1.2,fv=1.2) | |
190 | \ : (resizer == "Spline64" && yuv444) ? res_16.Dither_resize16(w,h,kernel="spline64",fh=1.2,fv=1.2).ConvertToY8() | |
191 | \ : (resizer == "Spline64") ? res_16.Dither_resize16(w,h,kernel="spline64",fh=1.2,fv=1.2) | |
192 | \ : ((resizer == "lineart_rpow2" || resizer == "lineart_rpow2_bicubic") && yuv444) ? res_16.Dither_resize16(1280,720,kernel="spline36",fh=1.2,fv=1.2).ConvertToY8() | |
193 | \ : (resizer == "lineart_rpow2" || resizer == "lineart_rpow2_bicubic") ? res_16 | |
194 | \ : ((resizer == "lineart_rpow2MT" || resizer == "lineart_rpow2_bicubicMT") && yuv444) ? res_16.Dither_resize16(1280,720,kernel="spline36",fh=1.2,fv=1.2).ConvertToY8() | |
195 | \ : (resizer == "lineart_rpow2MT" || resizer == "lineart_rpow2_bicubicMT") ? res_16 | |
196 | \ : (resizer == "none") ? res_16 | |
197 | \ : Assert (false, "GradFun3mod: wrong resizer value.") | |
198 | ||
199 | ly = rkernel | |
200 | lu = res_16.utoy8().Dither_resize16(1280, 720, src_left=0.25, kernel="blackman") | |
201 | lv = res_16.vtoy8().Dither_resize16(1280, 720, src_left=0.25, kernel="blackman") | |
202 | (yuv444) ? ytouv(lu,lv,ly) : rkernel | |
203 | ||
204 | # Dithering | |
205 | ||
206 | result = (lsb) ? last : last.DitherPost ( | |
207 | \ mode=mode, ampo=ampo, ampn=ampn, pat=pat, dyn=dyn, | |
208 | \ prot=false, thr=dthr, staticnoise=staticnoise, | |
209 | \ y=yp, u=up, v=vp, slice=slice | |
210 | \ ) | |
211 | result = (lsb) | |
212 | \ ? Dither_switch_planes16 (src_16, result, y=y, u=u, v=v) | |
213 | \ : Dither_switch_planes8 (src_8, result, y=y, u=u, v=v) | |
214 | ||
215 | (debug == 1 ) ? dmask.GreyScale () : result | |
216 | (debug == 1 && lsb) ? Dither_convert_8_to_16 () : last | |
217 | } | |
218 | ||
219 | ||
220 | ||
221 | Function Dither_gf3_smooth_mod (clip src_16, clip src_8, clip ref_16, int smode, int radius, float thr, float elast, bool lsb_in, float wmin, int subspl, int yp, int up, int vp) | |
222 | { | |
223 | src_16 | |
224 | (smode == 0) ? Dither_gf3_smoothgrad_multistage (ref_16, radius, thr, elast, yp, up, vp) | |
225 | \ : (smode == 1) ? Dither_gf3_dfttest (src_8, ref_16, radius, thr, elast, lsb_in, yp, up, vp) | |
226 | \ : (smode == 2) ? Dither_gf3_bilateral_multistage (ref_16, radius, thr, elast, wmin, subspl, yp, up, vp) | |
227 | \ : (smode == 3) ? Dither_gf3_smoothgrad_multistage_3 (radius, thr, elast, yp, up, vp) | |
228 | \ : (smode == 4) ? Dither_gf3_dfttest_mod (src_8, ref_16, radius, thr, elast, lsb_in, yp, up, vp) | |
229 | \ : Assert (false, "GradFun3mod: wrong smode value.") | |
230 | } | |
231 | ||
232 | ||
233 | ||
234 | # Valid values for y, u and v: 1 and 3 | |
235 | Function Dither_gf3_dfttest_mod (clip src, clip src_8, clip ref, | |
236 | \ int radius, float thr, float elast, bool lsb_in, | |
237 | \ int y, int u, int v) | |
238 | { | |
239 | Assert (radius <= 128, "GradFun3: max "+chr(34)+"radius" +chr(34)+" value is 128 when smode = 1.") | |
240 | ||
241 | hrad = Dither_max (radius * 3 / 4, 1) | |
242 | ||
243 | (lsb_in) ? src : src_8 | |
244 | ||
245 | - | Function lineart_rpow2 (clip src, int w, int h, int ow, int oh, bool bicubic) |
245 | + | |
246 | \ sigma=thr*12, tbsize=1, | |
247 | \ sbsize=hrad*4, sosize=hrad*3, | |
248 | \ lsb=true, lsb_in=lsb_in, | |
249 | \ Y=(y==3), U=(u==3), V=(v==3) | |
250 | \ ) | |
251 | ||
252 | Dither_limit_dif16 (last, ref, thr=thr, elast=elast, y=y, u=u, v=v) | |
253 | } | |
254 | - | (bicubic) ? DebicubicM(src, w, h) : DebilinearM(src, w, h) |
254 | + | |
255 | Function lineart_rpow2 (clip src, int w, int h, int ow, int oh, bool bicubic, bool DeResizeMT) | |
256 | { | |
257 | w = default(w, 1280) | |
258 | h = default(h, 720) | |
259 | ow = default(ow, 1920) | |
260 | oh = default(oh, 1080) | |
261 | - | Function debicubicy_precise(clip src, int dst_width, int dst_height, float "src_left", float "src_top", float "src_width", float "src_height") |
261 | + | |
262 | DeResizeMT = default(DeResizeMT, false) | |
263 | ||
264 | orig = src | |
265 | DeResizeMT ? ResizeX(src, w, h, desampling=true, kernel=bicubic ? "Bicubic" : "Bilinear") : (bicubic) ? DebicubicM(src, w, h) : DebilinearM(src, w, h) | |
266 | nnedi3_rpow2(2, cshift="Spline36Resize", fwidth=ow, fheight=oh) | |
267 | edges = last.mt_edge("prewitt", 4, 24, 4, 24, chroma="true").removegrain(20, 1) | |
268 | sharp = last | |
269 | mt_merge(orig, sharp, edges) | |
270 | } | |
271 | ||
272 | Function debicubicy_precise(clip src, int dst_width, int dst_height, float "src_left", float "src_top", float "src_width", float "src_height", bool "DeResizeMT") | |
273 | { | |
274 | # script by torch | |
275 | ||
276 | sw = src.width() | |
277 | - | seed = debicubicy(src, dst_width, dst_height, src_left, src_top, src_width+src_left, src_height+src_top, lsb_inout=true) |
277 | + | |
278 | src_left = default(src_left, 0.0) | |
279 | src_top = default(src_top, 0.0) | |
280 | - | down = diff.debicubicy(dst_width, dst_height, src_left, src_top, src_width+src_left, src_height+src_top, lsb_inout=true) |
280 | + | |
281 | src_height = default(src_height, sh) | |
282 | DeResizeMT = default(DeResizeMT, false) | |
283 | ||
284 | inv_left = -src_left * dst_width/src_width | |
285 | inv_top = -src_top * dst_height/src_height | |
286 | - | Function DebicubicM_precise16(clip input, int target_width, int target_height, bool "chroma") |
286 | + | |
287 | inv_height = (sh-src_top) * dst_height/src_height | |
288 | ||
289 | seed = DeResizeMT ? ResizeX(src, dst_width, dst_height, src_left, src_top, src_width+src_left, src_height+src_top, chroma=false, desampling=true, kernel="Bicubic", lsb_in=true, lsb_out=true) : debicubicy(src, dst_width, dst_height, src_left, src_top, src_width+src_left, src_height+src_top, lsb_inout=true) | |
290 | up = seed.dither_resize16(sw, sh, inv_left, inv_top, inv_width, inv_height, kernel="bicubic", fh=-1.0, fv=-1.0) | |
291 | diff = dither_sub16(src, up, dif=true).dither_lut16("x 32768 - 99 * 32768 +") | |
292 | down = DeResizeMT ? diff.ResizeX(dst_width, dst_height, src_left, src_top, src_width+src_left, src_height+src_top, chroma=false, desampling=true, kernel="Bicubic", lsb_in=true, lsb_out=true) : diff.debicubicy(dst_width, dst_height, src_left, src_top, src_width+src_left, src_height+src_top, lsb_inout=true) | |
293 | down = down.dither_lut16("x 32768 - 99 / 32768 + round") | |
294 | ||
295 | return seed.dither_add16(down, dif=true) | |
296 | } | |
297 | ||
298 | Function DebicubicM_precise16(clip input, int target_width, int target_height, bool "chroma", bool "DeResizeMT") | |
299 | { | |
300 | # based on DebilinearM v1.3.1 | |
301 | ||
302 | Assert(target_width > 0, "GradFun3mod: target width must be greater than 0") | |
303 | Assert(target_height > 0, "GradFun3mod: target height must be greater than 0") | |
304 | ||
305 | thr = 10 | |
306 | - | \ : input.debicubicy_precise(target_width,target_height) |
306 | + | |
307 | - | dbi_8bit = chroma ? input_8bit.Debicubic(target_width,target_height) |
307 | + | |
308 | kernel = "Spline36" | |
309 | chroma = Default(chroma, true) | |
310 | - | rs = input.ResizeX(target_width,target_height, kernel=kernel, chroma=chroma, lsb_in=true, lsb=true) |
310 | + | DeResizeMT = default(DeResizeMT, false) |
311 | ||
312 | w = input.Width() | |
313 | h = input.Height()/2 | |
314 | uvint = chroma ? 3 : 1 | |
315 | ||
316 | # Resizing | |
317 | input_8bit = input.DitherPost(mode=-1) | |
318 | dbi = chroma ? input.Dither_resize16(target_width,target_height,kernel="bicubic",invksh=true,fh=1.3,fv=1.3,invkstaps=7) | |
319 | \ : input.debicubicy_precise(target_width,target_height,DeResizeMT=DeResizeMT) | |
320 | dbi_8bit = DeResizeMT ? input_8bit.ResizeX(target_width,target_height, chroma=chroma, desampling=true, kernel="Bicubic") : chroma ? input_8bit.Debicubic(target_width,target_height) | |
321 | \ : input_8bit.DebicubicY(target_width,target_height) | |
322 | dbi2 = dbi_8bit.ResizeX(w,h, kernel="Bicubic", chroma=chroma) | |
323 | rs = input.ResizeX(target_width,target_height, kernel=kernel, chroma=chroma, lsb_in=true, lsb_out=true) | |
324 | ||
325 | # Masking | |
326 | diffmask = mt_lutxy(input_8bit,dbi2, "x y - abs", U=uvint, V=uvint).mt_binarize(threshold=thr, U=uvint, V=uvint) | |
327 | diffmask = diffmask.ResizeX(target_width,target_height, kernel="Bilinear", chroma=chroma) | |
328 | \ .mt_binarize(threshold=3, U=uvint, V=uvint) | |
329 | \ .DebilinearM_expand(expand=expand, U=uvint, V=uvint) | |
330 | \ .DebilinearM_inflate(inflate=inflate, U=uvint, V=uvint) | |
331 | merged = Dither_merge16_8(dbi,rs,diffmask, u=uvint, v=uvint) | |
332 | ||
333 | return merged | |
334 | } |