gradfun3mod

Eine kleine überarbeitete Version von Gebbis gradfun3mod Release.

##################################################################################################################
#
# High bitdepth tools for Avisynth - GradFun3mod r7mod7
# based on Dither v1.27.2
# Author: Firesledge
# r7: slightly modified by Gebbi
# mod7: Modified by Saeval and eXmendiC
#
# What?
# - This is a slightly modified version of the original GradFun3.
# - It combines the usual color banding removal stuff with resizers during the process
# for sexier results (less detail loss, especially for downscales of cartoons).
# - This is a starter script, not everything is covered through parameters. Modify it to your needs.
#
# Requirements (in addition to the Dither requirements):
# - AviSynth 2.6.x
# - Debilinear, Debicubic, DebilinearM
# - NNEDI3 + nnedi3_resize16
# - AddGrainC v1.7.1
# - AVSTP v1.0.1
# - Debicubic r2
# - Debilinear r6
# - DebilinearM v1.3.1
# - Dfttest v1.9.4
# - Dither v1.27.1
# - dither.avsi v1.27.1
# - FTurn 1.4
# - MaskTools v2.1 (tp7 version)
# - MVTools v2.6.0.5
# - NNEDI3 v0.9.4.20
# - nnedi3_resize16 v3.3
# - ResizeX v1.0
# - RgTools v0.92.1
# - SmoothAdjust v3.00
# - Morefun.avsi
# - debicubicy_precise.avsi
# - DebicubicM_precise16.avsi
# - lineart_rpow2.avsi
# - Probably more
#
# - libfftw3f-3.dll to be put inside C:\Windows\SysWOW64\
#
# Changes from the original GradFun3:
# - yuv444 = true
# (4:2:0 -> 4:4:4 colorspace conversion, needs 1920x1080 input)
# - resizer = [ "none", "Debilinear", "DebilinearM", "Debicubic", "DebicubicM", "Spline16",
# "Spline36", "Spline64", "lineart_rpow2", "lineart_rpow2_bicubic" ]
# (use it only for downscales)
# NOTE: As of r2 Debicubic doesn't have 16-bit precision, so a Y (luma) plane fix by torch is used here,
# more info: https://mechaweaponsvidya.wordpress.com/2015/07/07/a-precise-debicubic/
# Without yuv444=true Dither_resize16 is used with an inverse bicubic kernel.
# - w = 1280, h = 720
# (output width & height for the resizers; or production resolution for resizer="lineart_rpow2")
# - smode = 4
# (the old GradFun3mod behaviour for legacy reasons; based on smode = 1 (dfttest);
# not useful anymore in most cases, use smode = 2 instead (less detail loss))
#
# Usage examples:
# - Source is bilinear 720p->1080p upscale (BD) with 1080p credits overlayed,
# revert the upscale without fucking up the credits:
# lwlibavvideosource("lol.m2ts")
# GradFun3mod(smode=2, lsb=true, yuv444=true, resizer="DebilinearM")
#
# - Source is bicubic 720p->1080p upscale (BD) with 1080p credits overlayed,
# revert the upscale without fucking up the credits:
# lwlibavvideosource("lol.m2ts")
# GradFun3mod(smode=2, lsb=true, yuv444=true, resizer="DebicubicM")
#
# - If you don't care about credits and want it faster:
# GradFun3mod(smode=2, lsb=true, yuv444=true, resizer="Debilinear")
# or
# GradFun3mod(smode=2, lsb=true, yuv444=true, resizer="Debicubic")
#
# - You just want to get rid of the banding without changing the resolution:
# GradFun3mod(smode=2, lsb=true)
#
# - Source is a 1080p production (BD) or HDTV transportstream (or CR or whatever), downscale to 720p:
# GradFun3mod(smode=2, lsb=true, resizer="Spline36")
# or
# GradFun3mod(smode=2, lsb=true, resizer="Gauss")
# or
# GradFun3mod(smode=2, lsb=true, resizer="Bicubic")
#
# - If you rather work in 8bit instead of 16bit:
# lsb=false (or just delete lsb=true)
#
# - If you rather want 4:2:2/4:2:0 output instead of 4:4:4:
# yuv444=false (or just delete yuv444=true)
#
# - If your source is oversharped and you want to fix that:
# b=0, c=1 (maybe try some other values too)
# Note: This only works with resizer="Debicubic","DebicubicM","Bicubic" and "Gauss"
#
# - If your source is undersharped and you want to fix that:
# b=1, c=0 (maybe try some other values too)
# Note: This only works with resizer="Debicubic","DebicubicM","Bicubic" and "Gauss"
#
# - Source is anime, 720p->1080p upscale, keep the resolution
# but with smoother lineart instead of bilinear upscaled shit:
# GradFun3mod(smode=2, resizer="lineart_rpow2")
# This won't actually resize the video but instead mask the lineart and re-upscale it using
# nnedi3_rpow2 which often results in much better looking lineart (script mostly by Daiz).
#
# Note: Those examples don't include parameters like thr, radius, elast, mode, ampo, ampn, staticnoise.
# You probably don't want to use the default values.
# For 8-bit output use (use it at the end of your whole script):
# Output8bit()
# For 10-bit output use (use it at the end of your whole script):
# Output10bit()
# For 16-bit output use (use it at the end of your whole script):
# Output16bit()
# or
# Dither_out()
#
# What's the production resolution of my korean cartoon?
# - Use your eyes combined with Debilinear(1280,720) - if it looks like oversharped shit,
# it was probably produced in a higher resolution.
# - Use Debicubic(1280,720).BicubicResize(1920,1080) for detail loss search.
# - Use Debicubic(1280,720,b=0,c=1).BicubicResize(1920,1080) for detail loss search.
# - Use Debilinear(1280,720).BilinearResize(1920,1080) for detail loss search.
# - Alternatively you can lookup the (estimated) production resolution at
# http://anibin.blogspot.com (but don't blindly trust those results)
# - You can try yuv444=true and check if it's worth 4:4:4
# GradFun3mod(smode=2, lsb=true, yuv444=true, resizer="Debicubic").BicubicResize(1920,1080) #Mitchell-Netravali Bicubic
# GradFun3mod(smode=2, lsb=true, yuv444=true, resizer="Debicubic").BicubicResize(1920,1080, b=0, c=0.5) #Catmull-Rom Bicubic
# Gradfun3mod(smode=2, lsb=true, yuv444=true, resizer="Debilinear").BilinearResize(1920,1080)
#
# - If you don't want to see a green screen use (remove or comment Output10bit/Output8bit/Dither_out):
# DitherPost(Mode=8).Dither_convert_yuv_to_rgb("709")
#
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
#
##################################################################################################################

Function GradFun3mod (clip src, float "thr", int "radius", float "elast",
\ int "mask", int "mode", float "ampo", float "ampn", int "pat",
\ bool "dyn", float "dthr", int "smode", float "wmin", float "thr_det",
\ float "thr_edg", int "debug", int "subspl", bool "lsb", bool "lsb_in",
\ bool "staticnoise", float "thrc", int "radiusc", float "elastc",
\ int "y", int "u", int "v", clip "ref", bool "slice", bool "yuv444", int "w", int "h", string "resizer", float "b", float "c", float "p", float "crco")
{
thr = Default (thr, 0.35)
thrc = Default (thrc, thr)
radius = Default (radius, 12)
radiusc = Default (radiusc, radius)
elast = Default (elast, 3.0)
elastc = Default (elastc, elast)
mask = Default (mask, 2)
smode = Default (smode, 2)
wmin = Default (wmin, 1.0)
thr_det = Default (thr_det, 2 + Round (Dither_max (thr - 0.35, 0) / 0.3))
debug = Default (debug, 0)
subspl = Default (subspl, 0)
lsb = Default (lsb, false)
lsb_in = Default (lsb_in, false)
ref = Default (ref, src)
yuv444 = Default (yuv444, false)
w = Default (w, 1280)
h = Default (h, 720)
resizer = Default (resizer, "none")
b = Default(b, 1.0/3)
c = Default(c, 1.0/3)
p = Default(p, 45.0)
crco = Default(crco, 0)

# Do lineart smoothing first for sharper results

ow = src.Width()
oh = src.Height()

src = (resizer == "lineart_rpow2") ? lineart_rpow2(src, w, h, ow, oh, false)
\ : (resizer == "lineart_rpow2_bicubic") ? lineart_rpow2(src, w, h, ow, oh, true, b, c)
\ : src

# Input range check. The other parameters are checked by the plugins.
Assert (radius > 0, "GradFun3: "+chr(34)+"radius" +chr(34)+" must be strictly positive.")
Assert (radiusc > 0, "GradFun3: "+chr(34)+"radiusc"+chr(34)+" must be strictly positive.")
Assert (thr > 0, "GradFun3: "+chr(34)+"thr" +chr(34)+" must be strictly positive.")
Assert (thrc > 0, "GradFun3: "+chr(34)+"thrc" +chr(34)+" must be strictly positive.")
Assert (thr_det > 0, "GradFun3: "+chr(34)+"thr_det"+chr(34)+" must be strictly positive.")
Assert (elast >= 1, "GradFun3: "+chr(34)+"elast" +chr(34)+" must be greater or equal to 1.")
Assert (elastc >= 1, "GradFun3: "+chr(34)+"elastc" +chr(34)+" must be greater or equal to 1.")

src_8 = (lsb_in) ? src.DitherPost (mode=-1) : src
src_16 = (lsb_in) ? src : src.Dither_convert_8_to_16 ()
ref_16 = (lsb_in) ? ref : ref.Dither_convert_8_to_16 ()
yv411_flag = src.Dither_isyv411 ()

# Main debanding

yp = (! Defined (y) || (y == 3)) ? 3 : 1
up = (! Defined (u) || (u == 3)) ? 3 : 1
vp = (! Defined (v) || (v == 3)) ? 3 : 1

chroma_flag = ( (thrc != thr || radiusc != radius || elastc != elast)
\ && yp == 3 && (up == 3 || vp == 3))
up2 = (chroma_flag) ? 1 : up
vp2 = (chroma_flag) ? 1 : vp

src_16
flt_y = Dither_gf3_smooth_mod (last, src_8, ref_16, smode, radius, thr, elast, lsb_in, wmin, subspl, yp, up2, vp2)
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
flt = (chroma_flag) ? flt_y.MergeChroma (flt_c) : flt_y

# Edge/detail mask

td_lo = Dither_max (thr_det * 0.75, 1)
td_hi = Dither_max (thr_det, 1)
mexpr = Dither_make_expr_gate (td_lo, td_hi)

dmask = (mask > 0 && yv411_flag) ? src_8.ConvertToY8 () : src_8
dmask = (mask > 0) ? dmask.Dither_build_gf3_range_mask (mask) : dmask
dmask = (mask > 0) ? dmask.mt_lut (expr=mexpr) : dmask
dmask = (mask > 0) ? dmask.Dither_removegrain_emul (22, -1) : dmask
dmask = (mask > 1) ? dmask.Dither_removegrain_emul (11, -1) : dmask
dmask = (mask > 2) ? dmask.Dither_removegrain_emul (20, -1) : dmask
dmask = (mask > 0 && yv411_flag) ? dmask.ConvertToYV411 () : dmask

res_16 = (mask > 0) ? Dither_merge16_8 (flt, src_16, dmask, luma=true, y=yp, u=up, v=vp) : flt

# Resizing / colorspace conversion (GradFun3mod)

resizer = (yuv444 && resizer == "none") ? "Spline36" : resizer

rkernel = (resizer == "Debilinear" && yuv444) ? res_16.DebilinearY(w,h,lsb_inout=true)
\ : (resizer == "Debilinear") ? res_16.Debilinear(w,h,lsb_inout=true)
\ : (resizer == "DebilinearM" && yuv444) ? res_16.DebilinearM(w,h,lsb_inout=true,chroma=false)
\ : (resizer == "DebilinearM") ? res_16.DebilinearM(w,h,lsb_inout=true)
\ : (resizer == "Debicubic" && yuv444) ? res_16.debicubicy_precise(w,h, b=b, c=c)
\ : (resizer == "Debicubic") ? res_16.Debicubic16(w,h,lsb_inout=true, b=b, c=c)
\ : (resizer == "DebicubicM" && yuv444) ? res_16.DebicubicM_precise16(w,h,chroma=false, b=b, c=c)
\ : (resizer == "DebicubicM") ? res_16.DebicubicM_precise16(w,h, b=b, c=c)
\ : (resizer == "Spline16" && yuv444) ? res_16.Dither_resize16(w,h,kernel="spline16").ConvertToY8()
\ : (resizer == "Spline16") ? res_16.Dither_resize16(w,h,kernel="spline16")
\ : (resizer == "Spline36" && yuv444) ? res_16.Dither_resize16(w,h,kernel="spline36").ConvertToY8()
\ : (resizer == "Spline36") ? res_16.Dither_resize16(w,h,kernel="spline36")
\ : (resizer == "Spline64" && yuv444) ? res_16.Dither_resize16(w,h,kernel="spline64").ConvertToY8()
\ : (resizer == "Spline64") ? res_16.Dither_resize16(w,h,kernel="spline64")
\ : (resizer == "SplineMod" && yuv444) ? res_16.Dither_resize16(w,h,kernel="spline16",invks=true, invkstaps=6).ConvertToY8()
\ : (resizer == "SplineMod") ? res_16.Dither_resize16(w,h,kernel="spline16",invks=true, invkstaps=6)
\ : (resizer == "Gauss") ? res_16.Dither_resize16(w,h,kernel="gauss",invks=true,invkstaps=2, a1=p)
\ : (resizer == "Gauss" && yuv444) ? res_16.Dither_resize16(w,h,kernel="gauss",invks=true,invkstaps=2, a1=p).ConvertToY8()
\ : (resizer == "Bicubic") ? res_16.Dither_resize16(w,h,kernel="bicubic",invks=true,invkstaps=2, a1=b, a2=c)
\ : (resizer == "Bicubic" && yuv444) ? res_16.Dither_resize16(w,h,kernel="bicubic",invks=true,invkstaps=2, a1=b, a2=c).ConvertToY8()
\ : (resizer == "Field") ? interleave(res_16.separatefields().selecteven().Debilinear(w,h/2,src_top=-crco,src_height=540-crco,lsb_inout=true),res_16.separatefields().selectodd().Debilinear(w,h/2,src_top=+crco,src_height=540+crco,lsb_inout=true)).weave()
\ : (resizer == "Field" && yuv444) ? interleave(res_16.separatefields().selecteven().DebilinearY(w,h/2,src_top=-crco,src_height=540-crco,lsb_inout=true),res_16.separatefields().selectodd().DebilinearY(w,h/2,src_top=+crco,src_height=540+crco,lsb_inout=true)).weave()
\ : (resizer == "Nnedi3") ? res_16.nnedi3_resize16(w,h,kernel_u="Spline16",kernel_d="Spline16",invks_u=false,invks_d=true,invkstaps=6)
\ : (resizer == "Nnedi3" && yuv444) ? res_16.nnedi3_resize16(w,h,kernel_u="Spline16",kernel_d="Spline16",invks_u=false,invks_d=true,invkstaps=6).ConvertToY8()
\ : (resizer == "Eedi3") ? res_16.EDIResize16(w,h,kernel_u="Spline16",kernel_d="Spline16",invks_u=false,invks_d=true,invkstaps=6)
\ : (resizer == "Eedi3" && yuv444) ? res_16.EDIResize16(w,h,kernel_u="Spline16",kernel_d="Spline16",invks_u=false,invks_d=true,invkstaps=6).ConvertToY8()
\ : ((resizer == "lineart_rpow2" || resizer == "lineart_rpow2_bicubic") && yuv444) ? res_16.Dither_resize16(1280,720,kernel="spline36").ConvertToY8()
\ : (resizer == "lineart_rpow2" || resizer == "lineart_rpow2_bicubic") ? res_16
\ : (resizer == "none") ? res_16
\ : Assert (false, "GradFun3mod: wrong resizer value.")

ly = rkernel
lu = res_16.utoy().dither_resize16(w,h,kernel="blackmanminlobe",src_left=0.25,u=1,v=1)
lv = res_16.vtoy().dither_resize16(w,h,kernel="blackmanminlobe",src_left=0.25,u=1,v=1)
(yuv444) ? ytouv(lu,lv,ly) : rkernel

# Dithering

result = (lsb) ? last : last.DitherPost (
\ mode=mode, ampo=ampo, ampn=ampn, pat=pat, dyn=dyn,
\ prot=false, thr=dthr, staticnoise=staticnoise,
\ y=yp, u=up, v=vp, slice=slice
\ )
result = (lsb)
\ ? Dither_switch_planes16 (src_16, result, y=y, u=u, v=v)
\ : Dither_switch_planes8 (src_8, result, y=y, u=u, v=v)

(debug == 1 ) ? dmask.GreyScale () : result
(debug == 1 && lsb) ? Dither_convert_8_to_16 () : last
}

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)
{
src_16
(smode == 0) ? Dither_gf3_smoothgrad_multistage (ref_16, radius, thr, elast, yp, up, vp)
\ : (smode == 1) ? Dither_gf3_dfttest (src_8, ref_16, radius, thr, elast, lsb_in, yp, up, vp)
\ : (smode == 2) ? Dither_gf3_bilateral_multistage (ref_16, radius, thr, elast, wmin, subspl, yp, up, vp)
\ : (smode == 3) ? Dither_gf3_smoothgrad_multistage_3 (radius, thr, elast, yp, up, vp)
\ : (smode == 4) ? Dither_gf3_dfttest_mod (src_8, ref_16, radius, thr, elast, lsb_in, yp, up, vp)
\ : Assert (false, "GradFun3mod: wrong smode value.")
}

# Valid values for y, u and v: 1 and 3
Function Dither_gf3_dfttest_mod (clip src, clip src_8, clip ref,
\ int radius, float thr, float elast, bool lsb_in,
\ int y, int u, int v)
{
Assert (radius <= 128, "GradFun3: max "+chr(34)+"radius" +chr(34)+" value is 128 when smode = 1.")

hrad = Dither_max (radius * 3 / 4, 1)

(lsb_in) ? src : src_8

dfttest (
\ sigma=thr*12, tbsize=1,
\ sbsize=hrad*4, sosize=hrad*3,
\ lsb=true, lsb_in=lsb_in,
\ Y=(y==3), U=(u==3), V=(v==3)
\ )

Dither_limit_dif16 (last, ref, thr=thr, elast=elast, y=y, u=u, v=v)
}

Für Vapoursynth Port HIER klicken.

Advertisements