Skip to content

Instantly share code, notes, and snippets.

View wiwaz's full-sized avatar
🥤
fizz

wiwaz

🥤
fizz
View GitHub Profile
def descale_args(
clip: vs.VideoNode,
width: int | float = None,
height: int | float = None,
src_left: float = None,
src_top: float = None,
width_parity: int = None,
height_parity: int = None,
):
out_args = dict()
def vinverse(
clip: vs.VideoNode,
blur: GenericVSFunction = partial(core.std.Convolution, matrix=[1, 2, 1], mode=ConvMode.VERTICAL),
blur2: GenericVSFunction = partial(core.std.Convolution, matrix=[1, 4, 6, 4, 1], mode=ConvMode.VERTICAL),
csstr: float = 2.7, scale: float = 0.25, threshold: int = 255, planes: PlanesT = None
) -> vs.VideoNode:
"""
A simple but effective plugin to remove residual combing. Based on an AviSynth script by Didée.
:param clip: Clip to process.
class LowpassType(Enum):
Test1 = 0
"""Two horizontal 1x resamples, for DVDs"""
Test2 = 1
"""One 1x resample in both directions, for BDs"""
class FmtConvLanczos(vskernels.FmtConv):
_kernel = "lanczos"
def clippedmask(clip, vertical=False, threshold: list = None, columns: list = None, rows: list = None):
expr = f"x {threshold[0]} <= x {threshold[1]} >= or "
if vertical:
positions = rows
direction = "Y"
else:
positions = columns
direction = "X"
@wiwaz
wiwaz / crop_resize.py
Last active November 25, 2023 21:45
Resize images without introducing aspect ratio error
def crop_resize(clip: vs.VideoNode, apply_sar: bool = False, kernel: str = "Bicubic", **resize_args) -> vs.VideoNode:
defaults = ["width", "height", "src_width", "src_height"]
for i in defaults:
if i not in resize_args:
resize_args[i] = clip.height if defaults.index(i) % 2 else clip.width
src_res = (resize_args["src_width"], resize_args["src_height"])
out_res = [resize_args["width"], resize_args["height"]]
props = clip.get_frame(0).props
from typing import Callable
import vsdenoise
import vsrgtools
import vstools
vs, core = vstools.vs, vstools.core
# requires vsdenoise commit 2d7fed4 or newer
def temporal_lehmer_merge(
# in vstools now, gist no longer useful
import vapoursynth as vs
from math import gcd
def get_dar(width: int, height: int) -> tuple:
dar = gcd(width, height)
return (width // dar, height // dar)
@wiwaz
wiwaz / lehmer.py
Last active November 26, 2022 17:00
def lehmer_merge(clip, lowpass=lambda i: core.std.BoxBlur(i, hradius=3, vradius=3, hpasses=2, vpasses=2)):
count = len(clip)
expr = ""
for i in range(count):
expr += f"src{i} src{count + i} - D{i}! "
for v in range(2):
for i in range(count):
expr += f"D{i}@ {v + 2} pow "
@wiwaz
wiwaz / ftf.py
Last active January 3, 2023 13:58
def fix_telecined_fades(clip: vs.VideoNode, color: float | list[float] = 0.0) -> vs.VideoNode:
if clip.format.color_family == vs.RGB:
raise ValueError("fix_telecined_fades: Input must be YUV or GRAY!")
if clip.format.sample_type != vs.FLOAT:
raise ValueError("fix_telecined_fades: Input must be FLOAT!")
if not isinstance(color, list):
color = [color] * clip.format.num_planes
expr = []
def MLMDegrain(
clip: vs.VideoNode,
resolutions: tuple | list,
degrain_args: dict | list = {},
) -> vs.VideoNode:
if type(resolutions) is tuple:
resolutions = [resolutions]
if type(degrain_args) is dict:
degrain_args = [degrain_args] * (len(resolutions) + 1)
levels = range(len(resolutions))