Skip to content

Commit

Permalink
0.91
Browse files Browse the repository at this point in the history
Misc: expand version. I don't want to introduce 1.0 yet.
Change: descale mechanism modification.
  • Loading branch information
DJATOM committed Oct 21, 2021
1 parent 2f6eda5 commit 166c862
Showing 1 changed file with 71 additions and 33 deletions.
104 changes: 71 additions & 33 deletions insaneAA.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from vapoursynth import core, VideoNode, GRAY, YUV
from vapoursynth import core, VideoNode, GRAY, YUV # pylint: disable=no-name-in-module
import descale

from functools import partial
from enum import Enum
from typing import Any, Type, Union, Tuple
from finedehalo import fine_dehalo

__version__ = 0.9
__version__ = 0.91

"""
InsaneAA Anti-Aliasing Script (VS port) v0.9c (16.02.2020)
InsaneAA Anti-Aliasing Script (VS port) v0.91 (21.04.2020)
Original idea by tonik & tophf, edited and ported by DJATOM.
Use this script to fix ugly upscaled anime BDs.
Expand Down Expand Up @@ -57,6 +60,9 @@
Please do something with FullHD details! At least mask them or somehow exclude from processing.
Changelog:
version 0.91
Misc: expand version. I don't want to introduce 1.0 yet.
Change: descale mechanism modification.
version 0.9c
Fix: pass lanczos_taps to actual Descale call.
version 0.9b
Expand Down Expand Up @@ -97,41 +103,49 @@
"""

""" various modes stuff """


class ClipMode(Enum):
FULL = 0
FULL = 0
UNMASKED = 1
MASKED = 2
MASKED = 2


class EEDI3Mode(Enum):
CPU = 0
OPENCL = 1
CPU = 0
OPENCL = 1


class NNEDI3Mode(Enum):
NNEDI3 = 0
ZNEDI3 = 1
NNEDI3 = 0
ZNEDI3 = 1
NNEDI3CL = 2

def insaneAA(clip: VideoNode, external_aa: VideoNode = None, external_mask: VideoNode = None, faster_aa: bool = False, \
eedi3_mode: Union[EEDI3Mode, Tuple[EEDI3Mode, EEDI3Mode]] = EEDI3Mode.CPU, eedi3_device: Union[int, Tuple[int, int]] = -1, eedi3_opt: Union[int, Tuple[int, int]] = 0, \
nnedi3_mode: Union[NNEDI3Mode, Tuple[NNEDI3Mode, NNEDI3Mode]] = NNEDI3Mode.NNEDI3, nnedi3_device: Union[int, Tuple[int, int]] = -1, nnedi3_opt: Union[int, str, Tuple[Union[int, str], Union[int, str]]] = 0, \
descale_strength: float = 0.3, kernel: str = 'bilinear', bicubic_b: float = 1/3, bicubic_c: float = 1/3, lanczos_taps: int = 3, descale_width: int = None, descale_height: int = 720, pscrn: int = 1, \
alpha: float = 0.2, beta: float = 0.25, gamma: float = 1000.0, nrad: int = 2, mdis: float = 20, nsize: int = 0, nns: int = 4, \
output_mode: ClipMode = ClipMode.FULL, input_mode: ClipMode = ClipMode.FULL) -> VideoNode:

def insaneAA(clip: VideoNode, external_aa: VideoNode = None, external_mask: VideoNode = None, faster_aa: bool = False,
eedi3_mode: Union[EEDI3Mode, Tuple[EEDI3Mode, EEDI3Mode]] = EEDI3Mode.CPU, eedi3_device: Union[int, Tuple[int, int]] = -1, eedi3_opt: Union[int, Tuple[int, int]] = 0,
nnedi3_mode: Union[NNEDI3Mode, Tuple[NNEDI3Mode, NNEDI3Mode]] = NNEDI3Mode.NNEDI3, nnedi3_device: Union[int, Tuple[int, int]] = -1, nnedi3_opt: Union[int, str, Tuple[Union[int, str], Union[int, str]]] = 0,
descale_strength: float = 0.3, kernel: str = 'bilinear', bicubic_b: float = 1/3, bicubic_c: float = 1/3, lanczos_taps: int = 3, descale_width: int = None, descale_height: int = 720, pscrn: int = 1,
alpha: float = 0.2, beta: float = 0.25, gamma: float = 1000.0, nrad: int = 2, mdis: float = 20, nsize: int = 0, nns: int = 4, dehalo: bool = False,
output_mode: ClipMode = ClipMode.FULL, input_mode: ClipMode = ClipMode.FULL) -> VideoNode:
if not isinstance(clip, VideoNode):
raise TypeError('insaneAA: this is not a clip.')
width = clip.width
height = clip.height
gray_clip = core.std.ShufflePlanes(clip, 0, GRAY)
if not isinstance(external_aa, VideoNode):
descale_clip = revert_upscale(gray_clip, descale_strength, kernel, descale_width, descale_height, bicubic_b, bicubic_c, lanczos_taps)
upscale = rescale(descale_clip, faster_aa, eedi3_mode, eedi3_device, eedi3_opt, nnedi3_mode, nnedi3_device, nnedi3_opt, width, height, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
descale_clip = revert_upscale(gray_clip, descale_strength, kernel,
descale_width, descale_height, bicubic_b, bicubic_c, lanczos_taps, dehalo)
upscale = rescale(descale_clip, faster_aa, eedi3_mode, eedi3_device, eedi3_opt, nnedi3_mode,
nnedi3_device, nnedi3_opt, width, height, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
else:
upscale = external_aa
if output_mode in [ClipMode.UNMASKED, 1, "unmasked"]:
return upscale
if not isinstance(external_aa, VideoNode) or input_mode in [ClipMode.UNMASKED, 1, "unmasked"]:
if not isinstance(external_mask, VideoNode):
linemask = core.std.Sobel(gray_clip).std.Expr("x 2 *").std.Maximum()
linemask = core.std.Sobel(
gray_clip).std.Expr("x 2 *").std.Maximum()
else:
linemask = external_mask
aa_clip = core.std.MaskedMerge(gray_clip, upscale, linemask)
Expand All @@ -142,13 +156,22 @@ def insaneAA(clip: VideoNode, external_aa: VideoNode = None, external_mask: Vide
else:
return core.std.ShufflePlanes([aa_clip, clip], planes=[0, 1, 2], colorfamily=YUV)

def revert_upscale(clip: VideoNode, descale_strength: float = 0.3, kernel: str = 'bilinear', descale_width: int = None, descale_height: int = 720, bicubic_b: float = 1/3, bicubic_c: float = 1/3, lanczos_taps: int = 3) -> VideoNode:

def revert_upscale(clip: VideoNode, descale_strength: float = 0.3, kernel: str = 'bilinear', descale_width: int = None, descale_height: int = 720, bicubic_b: float = 1/3, bicubic_c: float = 1/3, lanczos_taps: int = 3, dehalo: bool = False) -> VideoNode:
width = clip.width
height = clip.height
descale_width = m4((width * descale_height) / height) if descale_width == None else descale_width
descale_natural = descale.Descale(clip, descale_width, descale_height, kernel=kernel, b=bicubic_b, c=bicubic_c, taps=lanczos_taps)
descale_width = m4((width * descale_height) /
height) if descale_width == None else descale_width
descale_natural = descale.Descale(
clip, descale_width, descale_height, kernel=kernel, b=bicubic_b, c=bicubic_c, taps=lanczos_taps)
descale_smooth = core.resize.Spline36(clip, descale_width, descale_height)
return core.std.Expr([descale_natural, descale_smooth], 'x {strength} * y 1 {strength} - * +'.format(strength=descale_strength))
descale_mix = core.std.Expr([descale_natural, descale_smooth],
'x {strength} * y 1 {strength} - * +'.format(strength=descale_strength))
if dehalo:
descale_mix = fine_dehalo(descale_mix, darkstr=0, brightstr=1.5, thmi=45,
thma=128, thlimi=60, thlima=120, showmask=0, useMtEdge=True)
return descale_mix


def rescale(clip: VideoNode, faster_aa: bool = False, eedi3_mode: Union[EEDI3Mode, Tuple[EEDI3Mode, EEDI3Mode]] = EEDI3Mode.CPU, eedi3_device: Union[int, Tuple[int, int]] = -1, eedi3_opt: Union[int, Tuple[int, int]] = 0, nnedi3_mode: Union[NNEDI3Mode, Tuple[NNEDI3Mode, NNEDI3Mode]] = NNEDI3Mode.NNEDI3, nnedi3_device: Union[int, Tuple[int, int]] = -1, nnedi3_opt: Union[int, str, Tuple[Union[int, str], Union[int, str]]] = 0, dx: int = None, dy: int = None, pscrn: int = 1, alpha: float = 0.2, beta: float = 0.25, gamma: float = 1000.0, nrad: int = 2, mdis: float = 20, nsize: int = 0, nns: int = 4):
ux = clip.width * 2
Expand All @@ -157,26 +180,38 @@ def rescale(clip: VideoNode, faster_aa: bool = False, eedi3_mode: Union[EEDI3Mod
raise ValueError('insaneAA: rescale lacks "dx" parameter.')
if dy is None:
raise ValueError('insaneAA: rescale lacks "dy" parameter.')
eedi3_mode_a, eedi3_mode_b = validateInput(eedi3_mode, (EEDI3Mode, int), 'insaneAA: eedi3_mode should be enum with valid mode or tuple with 2 values providing valid modes.')
nnedi3_mode_a, nnedi3_mode_b = validateInput(nnedi3_mode, (NNEDI3Mode, int), 'insaneAA: nnedi3_mode should be enum with valid mode or tuple with 2 values providing valid modes.')
eedi3_device_a, eedi3_device_b = validateInput(eedi3_device, int, 'insaneAA: eedi3_device should be integer with valid device ID or tuple with 2 values providing valid device IDs.')
nnedi3_device_a, nnedi3_device_b = validateInput(nnedi3_device, int, 'insaneAA: nnedi3_device should be integer with valid device ID or tuple with 2 values providing valid device IDs.')
eedi3_opt_a, eedi3_opt_b = validateInput(eedi3_opt, int, 'insaneAA: eedi3_opt should be integer with valid eedi3/eedi3cl opt value or tuple with 2 values providing valid values.')
nnedi3_opt_a, nnedi3_opt_b = validateInput(nnedi3_opt, (int, str), 'insaneAA: nnedi3_opt should be integer or string with valid eedi3/eedi3cl opt value or tuple with 2 values providing valid values.')
eedi3_mode_a, eedi3_mode_b = validateInput(
eedi3_mode, (EEDI3Mode, int), 'insaneAA: eedi3_mode should be enum with valid mode or tuple with 2 values providing valid modes.')
nnedi3_mode_a, nnedi3_mode_b = validateInput(
nnedi3_mode, (NNEDI3Mode, int), 'insaneAA: nnedi3_mode should be enum with valid mode or tuple with 2 values providing valid modes.')
eedi3_device_a, eedi3_device_b = validateInput(
eedi3_device, int, 'insaneAA: eedi3_device should be integer with valid device ID or tuple with 2 values providing valid device IDs.')
nnedi3_device_a, nnedi3_device_b = validateInput(
nnedi3_device, int, 'insaneAA: nnedi3_device should be integer with valid device ID or tuple with 2 values providing valid device IDs.')
eedi3_opt_a, eedi3_opt_b = validateInput(
eedi3_opt, int, 'insaneAA: eedi3_opt should be integer with valid eedi3/eedi3cl opt value or tuple with 2 values providing valid values.')
nnedi3_opt_a, nnedi3_opt_b = validateInput(nnedi3_opt, (
int, str), 'insaneAA: nnedi3_opt should be integer or string with valid eedi3/eedi3cl opt value or tuple with 2 values providing valid values.')
if faster_aa:
clip = core.std.Transpose(clip)
clip = eedi3_instance(clip, eedi3_mode_a, eedi3_device_a, eedi3_opt_a, nnedi3_mode_a, nnedi3_device_a, nnedi3_opt_a, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
clip = core.resize.Spline36(clip, height=dx, src_top=-0.5, src_height=ux)
clip = eedi3_instance(clip, eedi3_mode_a, eedi3_device_a, eedi3_opt_a, nnedi3_mode_a,
nnedi3_device_a, nnedi3_opt_a, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
clip = core.resize.Spline36(
clip, height=dx, src_top=-0.5, src_height=ux)
clip = core.std.Transpose(clip)
clip = eedi3_instance(clip, eedi3_mode_b, eedi3_device_b, eedi3_opt_b, nnedi3_mode_b, nnedi3_device_b, nnedi3_opt_b, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
clip = eedi3_instance(clip, eedi3_mode_b, eedi3_device_b, eedi3_opt_b, nnedi3_mode_b,
nnedi3_device_b, nnedi3_opt_b, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
return core.resize.Spline36(clip, height=dy, src_top=-0.5, src_height=uy)
else:
clip = eedi3_instance(clip, eedi3_mode_a, eedi3_device_a, eedi3_opt_a, nnedi3_mode_a, nnedi3_device_a, nnedi3_opt_a, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
clip = eedi3_instance(clip, eedi3_mode_a, eedi3_device_a, eedi3_opt_a, nnedi3_mode_a,
nnedi3_device_a, nnedi3_opt_a, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
clip = core.std.Transpose(clip)
clip = eedi3_instance(clip, eedi3_mode_b, eedi3_device_b, eedi3_opt_b, nnedi3_mode_b, nnedi3_device_b, nnedi3_opt_b, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
clip = eedi3_instance(clip, eedi3_mode_b, eedi3_device_b, eedi3_opt_b, nnedi3_mode_b,
nnedi3_device_b, nnedi3_opt_b, pscrn, alpha, beta, gamma, nrad, mdis, nsize, nns)
clip = core.std.Transpose(clip)
return core.resize.Spline36(clip, dx, dy, src_left=-0.5, src_top=-0.5, src_width=ux, src_height=uy)


def eedi3_instance(clip: VideoNode, eedi3_mode: EEDI3Mode = EEDI3Mode.CPU, eedi3_device: int = -1, eedi3_opt: int = 0, nnedi3_mode: NNEDI3Mode = NNEDI3Mode.NNEDI3, nnedi3_device: int = -1, nnedi3_opt: Union[int, str] = 0, pscrn: int = 1, alpha: float = 0.2, beta: float = 0.25, gamma: float = 1000.0, nrad: int = 2, mdis: float = 20, nsize: int = 0, nns: int = 4) -> VideoNode:
if eedi3_mode in [EEDI3Mode.OPENCL, 1, "opencl"]:
return core.eedi3m.EEDI3CL(clip, field=1, dh=True, alpha=alpha, beta=beta, gamma=gamma, vcheck=3, nrad=nrad, mdis=mdis, sclip=nnedi3_superclip(clip, nnedi3_mode, nnedi3_device, nnedi3_opt, pscrn, nsize, nns), device=eedi3_device, opt=eedi3_opt)
Expand All @@ -185,6 +220,7 @@ def eedi3_instance(clip: VideoNode, eedi3_mode: EEDI3Mode = EEDI3Mode.CPU, eedi3
else:
raise ValueError(f'insaneAA: invalid eedi3 mode - {eedi3_mode}.')


def nnedi3_superclip(clip: VideoNode, nnedi3_mode: NNEDI3Mode = NNEDI3Mode.NNEDI3, nnedi3_device: int = -1, opt: Union[int, str] = 0, pscrn: int = 1, nsize: int = 0, nns: int = 4) -> VideoNode:
if nnedi3_mode in [NNEDI3Mode.NNEDI3CL, 2, "nnedi3cl"]:
return core.nnedi3cl.NNEDI3CL(clip, field=1, dh=True, nsize=nsize, nns=nns, pscrn=pscrn, device=nnedi3_device)
Expand All @@ -205,6 +241,7 @@ def nnedi3_superclip(clip: VideoNode, nnedi3_mode: NNEDI3Mode = NNEDI3Mode.NNEDI
else:
raise ValueError(f'insaneAA: invalid nnedi3 mode - {nnedi3_mode}.')


def validateInput(var: Union[EEDI3Mode, NNEDI3Mode, int, str, tuple], varType: Union[Type[EEDI3Mode], Type[NNEDI3Mode], Type[int], Type[str], Type[tuple], tuple], errorString: str) -> Any:
if isinstance(var, varType):
return var, var
Expand All @@ -216,5 +253,6 @@ def validateInput(var: Union[EEDI3Mode, NNEDI3Mode, int, str, tuple], varType: U
else:
raise ValueError(errorString)


def m4(x: int) -> int:
return 16 if x < 16 else int(x // 4 + 0.5) * 4

0 comments on commit 166c862

Please sign in to comment.