Skip to content

prefilters

This module implements prefilters for denoisers.

Classes:

Functions:

Attributes:

PrefilterLike module-attribute

AbstractPrefilter

Methods:

__call__

__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    **kwargs: Any
) -> VideoNode | PrefilterPartial
Source code in vsdenoise/prefilters.py
133
134
135
136
def __call__(
    self, clip: vs.VideoNode, planes: PlanesT = None, full_range: bool | float = False, **kwargs: Any
) -> vs.VideoNode | PrefilterPartial:
    raise NotImplementedError

MultiPrefilter

MultiPrefilter(*prefilters: Prefilter)

Bases: AbstractPrefilter

A wrapper to apply multiple prefilters in sequence.

Stores a sequence of prefilter functions and applies them one after another to a given clip using the same parameters.

Parameters:

  • *prefilters

    (Prefilter, default: () ) –

    One or more prefilter functions to apply in order.

Methods:

  • __call__

    Apply a sequence of prefilters to the given clip.

Attributes:

Source code in vsdenoise/prefilters.py
545
546
547
548
549
550
551
552
553
def __init__(self, *prefilters: Prefilter) -> None:
    """
    Stores a sequence of prefilter functions and applies them one after
    another to a given clip using the same parameters.

    Args:
        *prefilters: One or more prefilter functions to apply in order.
    """
    self.prefilters = prefilters

prefilters instance-attribute

prefilters = prefilters

__call__

__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    **kwargs: Any
) -> VideoNode

Apply a sequence of prefilters to the given clip.

Parameters:

  • clip

    (VideoNode) –

    Clip to be preprocessed.

  • planes

    (PlanesT, default: None ) –

    Planes to be preprocessed.

  • full_range

    (bool | float, default: False ) –

    Whether to return a prefiltered clip in full range.

  • **kwargs

    (Any, default: {} ) –

    Additional keyword arguments passed to each prefilter.

Returns:

  • VideoNode

    Preprocessed clip.

Source code in vsdenoise/prefilters.py
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
def __call__(
    self, clip: vs.VideoNode, planes: PlanesT = None, full_range: bool | float = False, **kwargs: Any
) -> vs.VideoNode:
    """
    Apply a sequence of prefilters to the given clip.

    Args:
        clip: Clip to be preprocessed.
        planes: Planes to be preprocessed.
        full_range: Whether to return a prefiltered clip in full range.
        **kwargs: Additional keyword arguments passed to each prefilter.

    Returns:
        Preprocessed clip.
    """
    for pref in self.prefilters:
        clip = pref(clip, planes, full_range, **kwargs)

    return clip

Prefilter

Bases: AbstractPrefilter, CustomEnum

Enum representing available filters.

These are mainly thought of as prefilters for MVTools but can be used standalone as-is.

Methods:

  • __call__

    Run the selected prefilter.

Attributes:

  • BILATERAL

    Classic bilateral filtering or edge-preserving bilateral multi pass filtering.

  • BM3D

    Normal spatio-temporal denoising using BM3D.

  • DFTTEST

    Denoising in frequency domain with dfttest and an adaptive mask for retaining details.

  • FLUXSMOOTHST

    Perform smoothing using zsmooth.FluxSmoothST.

  • GAUSS

    Gaussian blur.

  • MINBLUR

    Minimum difference of a gaussian/median blur.

  • NLMEANS

    Denoising with NLMeans.

  • NONE

    Don't do any prefiltering. Returns the clip as-is.

BILATERAL class-attribute instance-attribute

BILATERAL = auto()

Classic bilateral filtering or edge-preserving bilateral multi pass filtering.

BM3D class-attribute instance-attribute

BM3D = auto()

Normal spatio-temporal denoising using BM3D.

DFTTEST class-attribute instance-attribute

DFTTEST = auto()

Denoising in frequency domain with dfttest and an adaptive mask for retaining details.

FLUXSMOOTHST class-attribute instance-attribute

FLUXSMOOTHST = auto()

Perform smoothing using zsmooth.FluxSmoothST.

GAUSS class-attribute instance-attribute

GAUSS = auto()

Gaussian blur.

MINBLUR class-attribute instance-attribute

MINBLUR = auto()

Minimum difference of a gaussian/median blur.

NLMEANS class-attribute instance-attribute

NLMEANS = auto()

Denoising with NLMeans.

NONE class-attribute instance-attribute

NONE = auto()

Don't do any prefiltering. Returns the clip as-is.

__call__

__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    *,
    temp_thr: float | Sequence[float] = 2.0,
    spat_thr: float | Sequence[float] | None = 2.0,
    **kwargs: Any
) -> VideoNode
__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    *,
    sloc: SLocationT | MultiDim | None = {0.0: 4.0, 0.2: 9.0, 1.0: 15.0},
    pref_mask: VideoNode | Literal[False] | tuple[int, int] = (16, 75),
    **kwargs: Any
) -> VideoNode
__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    *,
    h: float | Sequence[float] = 7.0,
    s: int | Sequence[int] = 2,
    **kwargs: Any
) -> VideoNode
__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    *,
    sigma: float | Sequence[float] = 10,
    radius: int | Sequence[int | None] | None = 1,
    **kwargs: Any
) -> VideoNode
__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    *,
    sigmaS: float | list[float] | tuple[float | list[float], ...] = 3.0,
    sigmaR: float | list[float] | tuple[float | list[float], ...] = 0.02,
    **kwargs: Any
) -> VideoNode
__call__(
    *,
    planes: PlanesT = None,
    full_range: bool | float = False,
    temp_thr: float | Sequence[float] = 2.0,
    spat_thr: float | Sequence[float] | None = 2.0,
    **kwargs: Any
) -> PrefilterPartial
__call__(
    *,
    planes: PlanesT = None,
    full_range: bool | float = False,
    sloc: SLocationT | MultiDim | None = {0.0: 4.0, 0.2: 9.0, 1.0: 15.0},
    pref_mask: VideoNode | Literal[False] | tuple[int, int] = (16, 75),
    **kwargs: Any
) -> PrefilterPartial
__call__(
    *,
    planes: PlanesT = None,
    full_range: bool | float = False,
    h: float | Sequence[float] = 7.0,
    s: int | Sequence[int] = 2,
    **kwargs: Any
) -> PrefilterPartial
__call__(
    *,
    planes: PlanesT = None,
    full_range: bool | float = False,
    sigma: float | Sequence[float] = 10,
    radius: int | Sequence[int | None] | None = 1,
    **kwargs: Any
) -> PrefilterPartial
__call__(
    *,
    planes: PlanesT = None,
    full_range: bool | float = False,
    sigmaS: float | list[float] | tuple[float | list[float], ...] = 3.0,
    sigmaR: float | list[float] | tuple[float | list[float], ...] = 0.02,
    **kwargs: Any
) -> PrefilterPartial
__call__(
    clip: VideoNode,
    planes: PlanesT = None,
    full_range: bool | float = False,
    **kwargs: Any
) -> VideoNode
__call__(
    *, planes: PlanesT = None, full_range: bool | float = False, **kwargs: Any
) -> PrefilterPartial
__call__(
    clip: VideoNode | MissingT = MISSING,
    planes: PlanesT = None,
    full_range: bool | float = False,
    **kwargs: Any
) -> VideoNode | PrefilterPartial

Run the selected prefilter.

Parameters:

  • clip

    (VideoNode | MissingT, default: MISSING ) –

    Clip to be preprocessed.

  • planes

    (PlanesT, default: None ) –

    Planes to be preprocessed.

  • full_range

    (bool | float, default: False ) –

    Whether to return a prefiltered clip in full range.

  • **kwargs

    (Any, default: {} ) –

    Additional arguments to pass to the specified prefilter.

Returns:

Source code in vsdenoise/prefilters.py
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
def __call__(
    self,
    clip: vs.VideoNode | MissingT = MISSING,
    planes: PlanesT = None,
    full_range: bool | float = False,
    **kwargs: Any,
) -> vs.VideoNode | PrefilterPartial:
    """
    Run the selected prefilter.

    Args:
        clip: Clip to be preprocessed.
        planes: Planes to be preprocessed.
        full_range: Whether to return a prefiltered clip in full range.
        **kwargs: Additional arguments to pass to the specified prefilter.

    Returns:
        Preprocessed clip or Partial Prefilter.
    """
    if clip is MISSING:
        return PrefilterPartial(self, planes, full_range, **kwargs)

    out = _run_prefilter(self, clip, planes, **kwargs)

    if full_range is not False:
        if full_range is True:
            full_range = 2.0

        return prefilter_to_full_range(out, full_range)

    return out

PrefilterPartial

PrefilterPartial(
    prefilter: Prefilter,
    planes: PlanesT,
    full_range: bool | float,
    **kwargs: Any
)

Bases: AbstractPrefilter

A partially-applied prefilter wrapper.

Stores a prefilter function, allowing it to be reused with different clips.

Parameters:

  • prefilter

    (Prefilter) –

    Prefilter enumeration.

  • planes

    (PlanesT) –

    Planes to be preprocessed.

  • full_range

    (bool | float) –

    Whether to return a prefiltered clip in full range.

  • **kwargs

    (Any, default: {} ) –

    Arguments for the specified prefilter.

Methods:

  • __call__

    Apply the prefilter to the given clip with optional argument overrides.

Attributes:

Source code in vsdenoise/prefilters.py
496
497
498
499
500
501
502
503
504
505
506
507
508
509
def __init__(self, prefilter: Prefilter, planes: PlanesT, full_range: bool | float, **kwargs: Any) -> None:
    """
    Stores a prefilter function, allowing it to be reused with different clips.

    Args:
        prefilter: [Prefilter][vsdenoise.prefilters.Prefilter] enumeration.
        planes: Planes to be preprocessed.
        full_range: Whether to return a prefiltered clip in full range.
        **kwargs: Arguments for the specified prefilter.
    """
    self.prefilter = prefilter
    self.planes = planes
    self.full_range = full_range
    self.kwargs = kwargs

full_range instance-attribute

full_range = full_range

kwargs instance-attribute

kwargs = kwargs

planes instance-attribute

planes = planes

prefilter instance-attribute

prefilter = prefilter

__call__

__call__(
    clip: VideoNode,
    planes: PlanesT | MissingT = MISSING,
    full_range: bool | float | MissingT = MISSING,
    **kwargs: Any
) -> VideoNode

Apply the prefilter to the given clip with optional argument overrides.

Parameters:

  • clip

    (VideoNode) –

    Clip to be preprocessed.

  • planes

    (PlanesT | MissingT, default: MISSING ) –

    Optional override for the planes to preprocess. If not provided, the default set in the constructor is used.

  • full_range

    (bool | float | MissingT, default: MISSING ) –

    Optional override for full range setting. If not provided, the default set in the constructor is used.

  • **kwargs

    (Any, default: {} ) –

    Additional keyword arguments to override or extend the stored ones.

Returns:

  • VideoNode

    Preprocessed clip.

Source code in vsdenoise/prefilters.py
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
def __call__(
    self,
    clip: vs.VideoNode,
    planes: PlanesT | MissingT = MISSING,
    full_range: bool | float | MissingT = MISSING,
    **kwargs: Any,
) -> vs.VideoNode:
    """
    Apply the prefilter to the given clip with optional argument overrides.

    Args:
        clip: Clip to be preprocessed.
        planes: Optional override for the planes to preprocess. If not provided, the default set in the constructor
            is used.
        full_range: Optional override for full range setting. If not provided, the default set in the constructor is
            used.
        **kwargs: Additional keyword arguments to override or extend the stored ones.

    Returns:
        Preprocessed clip.
    """
    return self.prefilter(
        clip,
        self.planes if planes is MISSING else planes,
        self.full_range if full_range is MISSING else full_range,
        **self.kwargs | kwargs,
    )

prefilter_to_full_range

prefilter_to_full_range(
    clip: VideoNode, slope: float = 2.0, smooth: float = 0.0625
) -> ConstantFormatVideoNode

Converts a clip to full range if necessary and amplifies dark areas. Essentially acts like a luma-based multiplier on the SAD when used as an mvtools prefilter.

Parameters:

  • clip

    (VideoNode) –

    Clip to process.

  • slope

    (float, default: 2.0 ) –

    Slope to amplify the scale of the dark areas relative to bright areas.

  • smooth

    (float, default: 0.0625 ) –

    Indicates the length of the transition between the amplified dark areas and normal range conversion.

Returns:

  • ConstantFormatVideoNode

    Range expanded clip.

Source code in vsdenoise/prefilters.py
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
def prefilter_to_full_range(clip: vs.VideoNode, slope: float = 2.0, smooth: float = 0.0625) -> ConstantFormatVideoNode:
    """
    Converts a clip to full range if necessary and amplifies dark areas.
    Essentially acts like a luma-based multiplier on the SAD when used as an mvtools prefilter.

    Args:
        clip: Clip to process.
        slope: Slope to amplify the scale of the dark areas relative to bright areas.
        smooth: Indicates the length of the transition between the amplified dark areas and normal range conversion.

    Returns:
        Range expanded clip.
    """
    assert check_variable_format(clip, prefilter_to_full_range)

    InvalidColorFamilyError.check(clip, (vs.YUV, vs.GRAY), prefilter_to_full_range)

    clip_range = ColorRange.from_video(clip)

    curve = (slope - 1) * smooth
    luma_expr = (
        "x yrange_in_min - 1 yrange_in_max yrange_in_min - / * 0 1 clip LUMA! "
        "{k} 1 {c} + {c} sin LUMA@ {c} + / - * LUMA@ 1 {k} - * + range_max * "
    )
    chroma_expr = "x neutral - range_max crange_in_max crange_in_min - / * range_half + round"

    if clip.format.sample_type is vs.INTEGER:
        luma_expr += "round"

    planes = 0 if clip_range.is_full or clip.format.sample_type is vs.FLOAT else None

    return ColorRange.FULL.apply(norm_expr(clip, (luma_expr, chroma_expr), k=curve, c=smooth, planes=planes))