Skip to main content

VapourSynth-VNLB

Video Non-Local Bayes denoising filter for VapourSynth.

Description

  • vnlb.Basic builds the basic estimate contribution stack.
  • vnlb.Final builds the final estimate contribution stack using a reference clip, usually the aggregated basic estimate.
  • vnlb.Aggregate turns contribution stacks into normal video frames.

Supported input formats:

  • GrayS
  • YUV444PS

Note: It is recommended to convert your source into OPP colorspace before calling VNLB, as the plugin does not perform any internal color-space conversion.

Installation

pip install -U vapoursynth-vnlb

Usage

VNLB Functions

basic estimate of VNLB denoising filter

This basic estimate produces a decent estimate of the noise-free image, as a reference for the final estimate.

vnlb.Basic(clip clip, float sigma[, int block_size=8, int block_step=8, int group_size=8, float cap_factor=4.0, float model_cap_factor=1.0, int bm_range=9, int patch_time=1, int radius=1, int search_bwd=1, int search_fwd=1, int rank=8, float beta=1.0, float tau=0.0, float variance_threshold=1.1, float weight_alpha=0.75, float weight_beta=0.35, float weight_gamma=1.0, float weight_epsilon=1e-6, float membership_noise_floor=0.25, int chroma=1, clip mvfw=None, clip mvbw=None])
  • clip: The input clip, the clip to be filtered. It must be constant-format GrayS or YUV444PS. Integer sources should be converted before calling VNLB.

  • sigma: The strength of denoising in 8-bit sample units (e.g., 5.1 means about 5.1 luma levels on an 8-bit scale). The plugin divides it by 255 internally for float clips. Technically, this is the standard deviation of i.i.d. zero mean additive white Gaussian noise in 8 bit scale.

  • block_size: The size of a spatial block is block_size x block_size, representing a local patch. A value of 8 uses 8x8 patches. Generally, larger blocks capture broader structure but cost more and can blur small details if the rank is too low.

  • block_step: Sliding step to process every next reference block (anchor block spacing). Lower values process more anchor positions and reduce sparse-anchor artifacts; higher values are faster. The default is 8. Set block_step=0 to use the automatic step, which is block_size.

  • group_size: Maximum number of similar blocks in each group before threshold expansion. More patches improve averaging stability but increase cost and may smooth texture when the search admits weak matches.

  • cap_factor: Soft cap for threshold-expanded groups. VNLB can keep additional patches after the best group_size matches when tau is active; this limits the expanded group to at most ceil(group_size * cap_factor) patches. Use 0.0 to disable this soft cap and keep all candidates admitted by the search threshold. Non-zero values must be at least 1.0.

  • model_cap_factor: Soft cap for the patches used to estimate the Bayesian model mean and covariance. The model uses at most ceil(group_size * model_cap_factor) retained patches. The default 1.0 keeps model construction fast while still allowing extra threshold-expanded patches to be filtered and aggregated. Use 0.0 to build the model from all retained patches. Non-zero values must be at least 1.0.

  • bm_range: Length of the side of the search neighborhood for block-matching around the guided center. The size of the search window is (bm_range * 2 + 1) x (bm_range * 2 + 1). 3 means candidates are searched inside a 7x7 window. Larger is slower, with more chances to find similar patches.

  • patch_time: Number of consecutive frames in each temporal patch. A value of 2 estimates patches spanning the anchor frame and the next frame.

  • radius: The temporal radius for denoising. Symmetric temporal search radius. It sets both search_bwd and search_fwd. Explicit search_bwd or search_fwd values override the shorthand for their respective directions.

  • search_bwd, search_fwd: Number of previous and next patch origins to search. With patch_time=2 and radius=1, each anchor can use patch origins from one frame before through one frame after, while still reading the extra frame needed by the temporal patch.

  • rank: Retained Bayesian model rank. Lower ranks remove more high-frequency variation; higher ranks preserve more detail and noise. For YUV444PS with chroma=1, the estimator dimension is 3 * block_size * block_size * patch_time, so useful ranks can be higher than Gray-only settings.

  • tau: Distance expansion threshold in 8-bit squared-distance units. VNLB first selects the best group_size patches, then keeps any additional candidates whose distance is at or below max(kth_distance, tau). Set tau=0.0 to keep only the nearest group_size patches.

  • beta: Multiplier applied to the noise variance used in Bayesian shrinkage. Higher values increase denoising strength.

  • variance_threshold: Dimensionless cutoff applied to the internal normalized noise variance. Components below variance_threshold * beta * sigma^2 are discarded. Higher values usually smooth more.

  • weight_alpha: Strength of group-confidence weighting during aggregation. Higher values give more influence to groups whose Bayesian model is more confident, usually reducing weak-match blur and improving stable detail. Too high can over-favor very smooth or very confident groups and suppress subtle texture. Set 0.0 to disable this term.

  • weight_beta: Strength of patch membership weighting during aggregation. Higher values reject patches that fit the current group poorly, which can reduce bad temporal matches and texture smearing. Too high can make aggregation too selective, leaving more residual noise or a slightly patchy look. Set 0.0 to disable this term.

  • weight_gamma: Strength of the spatial patch aggregation window. Higher values favor patch centers over patch borders, usually reducing blocking or grid-like artifacts. Too high can make overlapping patches contribute less evenly. Set 0.0 to disable the window.

  • weight_epsilon: Stabilizer for group-confidence weighting. Most users should leave it as default.

  • membership_noise_floor: Noise tolerance floor for patch membership weighting. Higher values make membership weighting less strict, allowing more averaging and smoother output. Lower values make it stricter, which can reject bad matches more aggressively but may leave more noise or uneven aggregation. Most users should leave it as default.

  • chroma: Defaults to 1. For YUV444PS, chroma=1 estimates one coupled multi-channel model across Y, U, and V. Use chroma=0 to process planes independently. GrayS clips ignore this setting.

  • mvfw, mvbw: Optional MVTools vector clips. They guide temporal search centers but do not replace exhaustive patch search inside bm_range. mvfw must come from isb=False, and mvbw from isb=True, both with delta=1 and dimensions matching clip.

final estimate of VNLB denoising filter

It takes the basic estimate as a reference. This final estimate can be realized as a refinement. It can significantly improve the denoising quality, keeping more details and fine structures that were removed in basic estimate.

vnlb.Final(clip clip, clip ref, float sigma[, ...])
  • clip: The input clip, the clip to be filtered.

  • ref: The reference clip, this clip is used in block-matching and as the reference in filtering. It must match clip format, dimensions, and frame count. In the usual two-stage chain this is the aggregated Basic estimate.

  • sigma_basic: Final-stage reference noise level in 8-bit sample units. Models residual noise in ref. Use 0.0 when treating the Basic/reference clip as clean; increasing it makes Final discount noisy reference variance and can smooth more.

  • gamma: Flat-area detector multiplier. It is used only when flat_areas=1; a group is treated as flat when its variance is below gamma * sigma^2.

  • flat_areas: Enables the flat-area path. Can improve very flat regions, but may smooth low-contrast texture. Final defaults to 1.

  • Other parameters: Same as those in vnlb.Basic. Final uses different defaults for tau=400.0, variance_threshold=1.7, weight_alpha=1.0, and weight_beta=0.5.

aggregation of VNLB denoising filter

vnlb.Aggregate(clip clip, clip src[, int patch_time=1, int radius=1, int search_bwd=1, int search_fwd=1])
  • clip: Contribution stack returned by Basic or Final. Stack height is src.height * 2 * (search_bwd + search_fwd + patch_time).

  • src: Original input clip used for dimensions and fallback pixels where no VNLB contribution is available.

  • patch_time, radius, search_bwd, search_fwd: Must receive the same temporal settings used to create its contribution stack in vnlb.Basic or vnlb.Final.

Examples

Basic Example

import vapoursynth as vs

core = vs.core

params = dict(
    sigma=5.1,
    block_size=8,
    block_step=8,
    patch_time=1,
    bm_range=9,
    radius=1,
    group_size=8,
    rank=8,
)

basic_stack = core.vnlb.Basic(src, **params)
basic = core.vnlb.Aggregate(
    basic_stack,
    src=src,
    patch_time=params["patch_time"],
    radius=params["radius"],
)

final_stack = core.vnlb.Final(src, ref=basic, **params)
final = core.vnlb.Aggregate(
    final_stack,
    src=src,
    patch_time=params["patch_time"],
    radius=params["radius"],
)

final.set_output()

For YUV444PS, chroma defaults to 1, estimating a coupled multi-channel model. Set chroma=0 to process planes independently.

MVTools Motion Guidance Example

VNLB can run without motion vectors. In that mode each temporal search window is centered at the same (x, y) location. When mvfw and mvbw are passed, the vectors are used as block-motion guidance for block-matching centers.

src = core.resize.Bicubic(src, format=vs.GRAYS)

# MVTools does not operate on float clips.
mvsrc = core.resize.Bicubic(src, format=vs.GRAY8)

sup = core.mv.Super(mvsrc, pel=2, hpad=16, vpad=16)
mvfw = core.mv.Analyse(sup, isb=False, delta=1, blksize=8, overlap=4)
mvbw = core.mv.Analyse(sup, isb=True,  delta=1, blksize=8, overlap=4)

params = dict(
    sigma=5.1,
    block_size=8,
    block_step=8,
    patch_time=1,
    bm_range=9,
    radius=1,
    group_size=8,
    rank=8,
    mvfw=mvfw,
    mvbw=mvbw,
)

basic_stack = core.vnlb.Basic(src, **params)
basic = core.vnlb.Aggregate(
    basic_stack,
    src=src,
    patch_time=params["patch_time"],
    radius=params["radius"],
)

final_stack = core.vnlb.Final(src, ref=basic, **params)
final = core.vnlb.Aggregate(
    final_stack,
    src=src,
    patch_time=params["patch_time"],
    radius=params["radius"],
)

Scene Cuts Example

Invalid MVTools vector frames fall back to zero motion automatically. For scene cuts, VNLB checks scene-change props on the clip passed to vnlb.Basic / vnlb.Final: _SceneChangePrev, _SceneChangeNext, Scenechange.

Use mv.SCDetection() on the integer motion source, then copy the props to the float clip used by VNLB:

src = core.resize.Bicubic(src, format=vs.GRAYS)
mvsrc = core.resize.Bicubic(src, format=vs.GRAY8)

sup = core.mv.Super(mvsrc, pel=2, hpad=16, vpad=16)
mvfw = core.mv.Analyse(sup, isb=False, delta=1, blksize=8, overlap=4)
mvbw = core.mv.Analyse(sup, isb=True,  delta=1, blksize=8, overlap=4)

mvsrc_sc = core.mv.SCDetection(mvsrc, mvfw)
mvsrc_sc = core.mv.SCDetection(mvsrc_sc, mvbw)

src = core.std.CopyFrameProps(
    src,
    prop_src=mvsrc_sc,
    props=["_SceneChangePrev", "_SceneChangeNext", "Scenechange"], # MVTools does not produce `Scenechange`, but other ones might (vapoursynth-wwxd).
)

basic_stack = core.vnlb.Basic(
    src,
    sigma=5.1,
    patch_time=2,
    radius=1,
    mvfw=mvfw,
    mvbw=mvbw,
)

If _SceneChangePrev or Scenechange is set, mvfw for that frame is ignored. If _SceneChangeNext is set, mvbw for that frame is ignored.

Build

Configure and build the release plugin:

cmake --preset release
cmake --build --preset release

Tests

Run the native and VapourSynth integration tests:

cmake --preset dev
cmake --build --preset dev
ctest --preset dev --output-on-failure
python3 tests/vs/integration_bestsource.py \
  build/release/libvnlb.dylib \
  . \
  build/release/bestsource-cache

Notes

  • The implementation does not copy the original VNLB reference source, so output is not bit-exact.
  • MVTools support is nearest-block sampling of the finest vector level.

References

License

AGPL-3.0-or-later

Metadata

Release files for vapoursynth-vnlb 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vapoursynth-vnlb 0.6.0
File Size Uploaded
vapoursynth_vnlb-0.6.0.tar.gz 64.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for vapoursynth-vnlb 0.6.0
File
vapoursynth_vnlb-0.6.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
vapoursynth_vnlb-0.6.0-py3-none-musllinux_1_2_x86_64.whl Python 3 none Linux musl 1.2+ x86-64 Details
vapoursynth_vnlb-0.6.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 Details
vapoursynth_vnlb-0.6.0-py3-none-macosx_12_0_x86_64.whl Python 3 none macOS 12.0+ x86-64 Details
vapoursynth_vnlb-0.6.0-py3-none-macosx_12_0_arm64.whl Python 3 none macOS 12.0+ ARM64 Details

Total release size: 37.5 MB

Release files / vapoursynth_vnlb-0.6.0.tar.gz

Download URL vapoursynth_vnlb-0.6.0.tar.gz
Size 64.0 kB
Tags Source
SHA-256 checksum
How to use checksums
af6282fd099f385f99a07cdfcdc1008e3f314fee2cfa38728f744c27e05a5640
BLAKE2b-256 checksum
How to use checksums
5c4b59f6518d57c13fd4563c6ce8105d733c463652291f042f1ce829846c42ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / vapoursynth_vnlb-0.6.0-py3-none-win_amd64.whl

Download URL vapoursynth_vnlb-0.6.0-py3-none-win_amd64.whl
Size 7.7 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
dac15f3cccc7445391cf27c6d5e65864e39db92fa2a193656f6d9f9c048cb83d
BLAKE2b-256 checksum
How to use checksums
9685acec2bbe62538acb1d9301e8fe61d93d26d2ad641d263d25ab28092da371
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / vapoursynth_vnlb-0.6.0-py3-none-musllinux_1_2_x86_64.whl

Download URL vapoursynth_vnlb-0.6.0-py3-none-musllinux_1_2_x86_64.whl
Size 13.0 MB
Tags Linux musl 1.2+ x86-64 Python 3
SHA-256 checksum
How to use checksums
64ccf6191fc749b9d71e94e52e5eaa84c06610a4388526d36d72e8f9c944ee41
BLAKE2b-256 checksum
How to use checksums
331e62b453cb1a3549d02b7eb4115e3d3fd0cd8dd301a9ec8c39aae38b7cdd25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / vapoursynth_vnlb-0.6.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl

Download URL vapoursynth_vnlb-0.6.0-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Size 16.5 MB
Tags Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
11452cecc76a03c17434aa3ae2be6c2b425f5af0c3a6f6674ff17b24226184f2
BLAKE2b-256 checksum
How to use checksums
026fdb10c595c8213ca01e9da48c7dd75ccecab43e1faad5f76d6e0e42e1f6cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / vapoursynth_vnlb-0.6.0-py3-none-macosx_12_0_x86_64.whl

Download URL vapoursynth_vnlb-0.6.0-py3-none-macosx_12_0_x86_64.whl
Size 140.0 kB
Tags Python 3 macOS 12.0+ x86-64
SHA-256 checksum
How to use checksums
6ebd4a97d3216f57441e331affc79b899a098f118e4a20618adc0864e9d0a40b
BLAKE2b-256 checksum
How to use checksums
1dc6d85693df54733a3f50bf54e46105105daa18ab4cf8f95031c0a5894d2333
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / vapoursynth_vnlb-0.6.0-py3-none-macosx_12_0_arm64.whl

Download URL vapoursynth_vnlb-0.6.0-py3-none-macosx_12_0_arm64.whl
Size 118.6 kB
Tags Python 3 macOS 12.0+ ARM64
SHA-256 checksum
How to use checksums
ba518c54d29669e227d5926186ad724b5c37c957781171553f672676e1b5fef5
BLAKE2b-256 checksum
How to use checksums
80c0ee6ce90a521717441a0b477ab6163753168cb5b6a8a2158234078d6c36a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.6.0 This release

6 release files

0.5.0

6 release files

0.4.0

6 release files

0.3.0

6 release files

0.2.0

6 release files

0.1.0

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page