Skip to content
dnjulek edited this page Jul 9, 2026 · 1 revision

WNNM

Weighted Nuclear Norm Minimization denoiser — a port of VapourSynth-WNNM with the MKL/ArmPL LAPACK dependency replaced by a built-in Gram-matrix + Jacobi eigensolver, making it several times faster and dependency-free on every platform.

vszip.WNNM(vnode clip[, float[] sigma=3.0, int block_size=8, int block_step=8, int group_size=8, int bm_range=7, int radius=0, int ps_num=2, int ps_range=4, bint residual=False, bint adaptive_aggregation=True, vnode rclip=None])

Parameters:

  • clip

    Input clip. Must be 32-bit float (any color family). Each plane is denoised separately.

  • sigma

    Denoising strength per plane. A plane with sigma < FLT_EPSILON is copied through. Missing entries inherit the previous one.

  • block_size, block_step, group_size, bm_range, radius, ps_num, ps_range

    Same as VapourSynth-BM3D. radius > 0 enables temporal denoising with V-BM3D-style predictive search.

  • residual

    Center the block group (subtract the group mean) before collaborative filtering. Default False.

  • adaptive_aggregation

    Weight aggregated blocks by the inverse of the number of kept singular values. Default True.

  • rclip

    Reference clip for block matching (same format/dimensions/length as clip); patch data is always taken from clip.

Notes / differences vs the original plugin

  • Output matches the original within ~2e-4 (the original's own AVX2 aggregation uses a 12-bit approximate reciprocal; vszip divides exactly). Temporal interior frames match within ~1e-6.
  • Block selection uses a stable tie-break (the original's std::partial_sort tie order is unspecified), so output is fully deterministic across runs and thread counts.
  • Constraints checked at creation (the original crashes or silently misbehaves instead): block_size must fit every processed plane, block_step <= block_size, group_size <= 256, ps_num <= 256, radius <= 15, and min(block_size^2, group_size) <= 64.

Clone this wiki locally