Skip to main content

vapoursynth-feel

GPU-accelerated filters in Vulkan for VapourSynth.

Primarily optimized for running on RDNA 3 with the RADV driver on Linux.

VapourSynth R80+ and a Vulkan 1.4 capable GPU are required.

pip install vapoursynth-feel

Performance

Filter vsfeel u16 vszipcl u16 vulkan u16 vsfeel fp32 vszipcl fp32 vulkan fp32 Speedup
Bilateral 2170 580 - 1142 387 - 3.43x
BM3Dv2 - - - 995 119 280 3.55x
DFTTest 1431 833 - 1134 488 - 1.94x
EEDI3 (AA) 165 25 36 121 25 29 4.40x
GaussBlur 2325 1298 - 1145 797 - 1.66x
NLMeans 1043 452 603 735 462 593 1.49x
NNEDI3 2703 - 2004 1393 - 1008 1.36x

Measured on a RX 7900 XTX using tools/benchmark.py --filter <filter> --bits <16|32> with a 1080p YUV420P input clip.

vulkan column: bm3dvk, eedi3vk2, knlmvk, nnedi3vk

Filters

Bilateral

A Bilateral filter is a non-linear, edge-preserving and noise-reducing smoothing filter for images. The intensity value at each pixel in an image is replaced by a weighted average of intensity values from nearby pixels. This weight can be based on a Gaussian distribution.

core.vsfeel.Bilateral(clip clip[,
    float[] sigma_spatial=3.0,      # spatial blur reach; per-plane, chroma default = sigma[0]/sqrt((1<<ssw)*(1<<ssh))
    float[] sigma_color=0.02,       # edge sensitivity: how different pixels may be to blend; depth-normalized
    int[]   radius,                 # per-plane blur window radius; default max(1, round(sigma_spatial*3))
    int     use_shared_memory=1,    # faster on-chip kernel while the window fits; falls back otherwise
    int     block_x, int block_y,   # GPU thread-block dims; auto-tuned when unset (32 x 8, x16 when radius > 12)
    clip    ref])                   # guide clip: weights from ref, values from clip

BM3Dv2

BM3D is a block-matching and 3D collaborative filtering denoiser. Groups of similar blocks (across space and time) are stacked into 3D arrays, denoised together with a hard-thresholded 3D transform, and the overlapping estimates are aggregated into the output.

core.vsfeel.BM3Dv2(clip clip[,
    clip    ref,                    # basic-estimate clip for the Wiener (final) pass
    float[] sigma=3.0,              # denoising strength per-plane; below FLT_EPSILON skips the plane
    int[]   block_step=8,           # per-plane block grid spacing, 1..8; smaller = fewer artifacts, slower
    int[]   bm_range=9,             # per-plane spatial search radius in pixels, 1..8192
    int     radius=0,               # temporal search radius in frames, 0..4 (0 = spatial only)
    int[]   ps_num=2,               # motion-predicted candidates seeding each temporal search, 1..8
    int[]   ps_range=4,             # search radius around each predicted candidate, in pixels, 1..8192
    int     extractor_exp=0])       # aggregation weight bias, -126..127; 0 = off, >= 3 = reproducible output

32-bit float only. Chroma passes through unprocessed.

DFTTest

DFTTest is a 3D block-wise frequency-domain denoiser. Each 16x16 spatial block is stacked with temporally neighboring frames, transformed to the frequency domain, filtered, and transformed back with overlap-add. It reduces noise while preserving detail, with configurable spatial and temporal windowing and a choice of frequency-domain filter variants.

core.vsfeel.DFTTest(clip clip[,
    int     ftype=0,                # 0 = Wiener: mult by max((psd-sigma)/psd, 0) ** f0beta
                                    # 1 = hard threshold: zero the bin when psd < sigma
                                    # 2 = mult every bin by sigma
                                    # 3 = mult by sigma inside [pmin,pmax], else by sigma2
                                    # 4 = mult by sigma*sqrt(psd*pmax / ((psd+pmin)*(psd+pmax)))
    float   sigma=8.0,              # base denoising strength
    float   sigma2=8.0,             # ftype=3 only: strength outside [pmin,pmax]
    float   pmin=0.0,               # ftype=3/4 only: lower PSD bound
    float   pmax=500.0,             # ftype=3/4 only: upper PSD bound
    int     sbsize=16,              # spatial block size; must be 16 in this backend
    int     sosize=12,              # spatial overlap, 0..15; >50% needs (sbsize-sosize) | sbsize
    int     tbsize=3,               # temporal block size; ODD, 1..7 (1 = spatial only)
    int     swin=0,                 # spatial window, 0..11: 0=hanning 1=hamming 2=blackman
                                    #   3=4-term b-harris 4=kaiser-bessel 5=7-term b-harris
                                    #   6=flat top 7=rectangular 8=bartlett 9=bartlett-hann
                                    #   10=nuttall 11=blackman-nuttall
    int     twin=7,                 # temporal window, the same 0..11 set; default 7=rectangular
    float   sbeta=2.5,              # kaiser-bessel beta (swin=4 only)
    float   tbeta=2.5,              # kaiser-bessel beta (twin=4 only)
    int     zmean=1,                # subtract the windowed mean before filtering
    float   f0beta=1.0,             # ftype=0 exponent (1.0 = plain Wiener, 0.5 = sqrt)
    int     ssystem=0,              # slocation scale: 0 = relative to block size, 1 = absolute
    float[] slocation,              # frequency-dependent sigma: [freq, sigma, freq, sigma, ...]
    float[] ssx,                    # slocation along the X axis only
    float[] ssy,                    # slocation along the Y axis only
    float[] sst,                    # slocation along time only
    int[]   planes])                # planes to process; default: all

EEDI3

EEDI3 is an edge-directed interpolator for deinterlacing and upscaling. For each missing pixel it searches candidate connection angles between the neighboring lines, picks the one minimizing a cost functional over local neighborhoods, and interpolates along that direction so edges stay sharp instead of stair-stepping.

core.vsfeel.EEDI3(clip clip, int field[,   # and EEDI3H, same args, horizontal
    int     dh=False,               # double-height output keeping every source line (no field extracted)
    int[]   planes,                 # planes to process; default: all
    float   alpha=0.2,              # 0..1 (alpha+beta <= 1): weight given to connecting similar
                                    #   neighborhoods. Larger = more lines/edges connected
    float   beta=0.25,              # 0..1: weight given to the vertical difference created by
                                    #   the interpolation. Larger = fewer edges connected
                                    #   (1.0 = no edge directedness at all)
    float   gamma=20.0,             # >= 0: penalizes changes in interpolation direction.
                                    #   Larger = smoother interpolation field
    int     nrad=2,                 # radius used for neighborhood similarity, 0..3
    int     mdis=20,                # max connection radius, 1..40; larger connects shallower
                                    #   lines, but costs speed and risks artifacts
    int     vcheck=2,               # 0..3: strength of the vertical-consistency check
    float   vthresh0=32.0,          # vcheck thresholds; all must be > 0 when vcheck > 0
    float   vthresh1=64.0,
    float   vthresh2=4.0,
    clip    sclip,                  # source for the vcheck comparison
    clip    mclip])                 # edge mask; fully-masked spans are skipped

field 2/3 are the double-rate variants (not allowed with dh=True).

GaussBlur

Gaussian blur is a smoothing filter that blends each pixel with its neighbors, weighting nearby pixels more heavily than distant ones according to a bell-shaped (Gaussian) curve. It is commonly used to soften an image or reduce noise.

core.vsfeel.GaussBlur(clip clip[,
    float[] sigma=0.5])             # blur strength; per-plane, chroma default = sigma[0]/sqrt((1<<ssw)*(1<<ssh))

NLMeans

Non-local means is a denoising filter that replaces every pixel with a weighted average of pixels across a search window, weighting them by the similarity of their surrounding patches. Searching across space and time suppresses noise while preserving detail.

core.vsfeel.NLMeans(clip clip[,
    int     d=1,                    # temporal radius; 0 = spatial only
    int     a=2,                    # search-window radius, 1..64
    int     s=4,                    # patch radius, 0..8
    float   h=1.2,                  # > 0: filtering strength
    int     wmode=0,                # weighting function of the patch distance x, 0..3:
                                    #   0 = exp(-x) | 1 = max(1-x, 0)
                                    #   2 = max(1-x, 0)**2 | 3 = max(1-x, 0)**8
    float   wref=1.0,               # >= 0: weight of the pixel itself
    string  channels="auto",        # planes to process, jointly for YUV/RGB; auto picks by format
    clip    rclip])                 # weights computed from rclip, values from clip

channels="YUV" requires 4:4:4 so on subsampled clips run a "Y" pass and a "UV" pass instead.

Accuracy caveat. The weight accumulator is fp16. At small h with wref=0 the exp() weights fall into fp16 subnormals and the whole ring can flush to zero; the kernel then falls back to the centre sample rather than evaluating 0/0, so the output can differ from the reference by thousands of codes (measured ~4600 LSB at h=1.2, wref=0 on the 16-bit test clip; back to 1 LSB at h=3.0). Raise h or wref if that matters.

NNEDI3

NNEDI3 is a neural-network edge-directed interpolator for deinterlacing and upscaling. A small neural network predicts each missing pixel from its local neighborhood, while a prescreener network skips pixels that simple cubic interpolation already handles.

core.vsfeel.NNEDI3(clip clip, int field[,
    int     dh=False,               # double-height output keeping every source line (no field extracted)
    int[]   planes,                 # planes to process; default: all
    int     nsize=6,                # predictor neighborhood, 0..6: 0=8x6 1=16x6 2=32x6
                                    #   3=48x6 4=8x4 5=16x4 6=32x4
    int     nns=1,                  # predictor neurons, 0..4: 0=16 1=32 2=64 3=128 4=256
    int     qual=1,                 # 1 or 2: number of predictor passes averaged
    int     etype=0,                # 0 = weights trained on absolute error, 1 = squared error
    int     pscrn=2])               # prescreener, 0..4: 0=off (predict every pixel)
                                    #   1=original, 2..4=new levels 0..2 (higher = fewer pixels
                                    #   left to cubic interpolation: slower, slightly better)

field 2/3 are the double-rate variants (not allowed with dh=True).

vs-jetpack integration

The wheel ships a small Python module alongside the plugin that adds vsfeel as a backend for the vs-jetpack wrappers.

vsjetpack is an optional dependency, only needed at runtime when you use these backends.

from vsrgtools import bilateral, gauss_blur
from vsdenoise import bm3d, DFTTest, nl_means

import vsfeel

# Bilateral
blurred = bilateral(clip, ref, 3.0, 0.02, backend=vsfeel.Backend)

# BM3D
denoised = bm3d(clip, 0.7, tr=2, profile=bm3d.Profile.NORMAL, ref=ref, planes=0, backend=vsfeel.Backend)

# DFTTest
dft = DFTTest(clip, backend=vsfeel.Backend).denoise({0.0: 16.0, 0.5: 8.0, 1.0: 0.0}, tr=1)

# GaussBlur
smooth = gauss_blur(clip, 1.5, backend=vsfeel.Backend)

# NLMeans
denoised = nl_means(clip, h=0.2, tr=2, a=2, s=4, ref=ref, planes=[1, 2], backend=vsfeel.Backend)

To also route the internal filters vs-jetpack calls on its own (e.g. the bilateral postfilter inside vsaa.based_aa), use the backend as a context manager:

from vsaa import based_aa

with vsfeel.Backend():
    based = based_aa(clip, antialiaser=vsfeel.EEDI3())

Manual Compilation

Full Python Package

pip install .

Plugin-Only

cmake -S . -B build -D CMAKE_BUILD_TYPE=Release
cmake --build build --config Release
cmake --install build

Metadata

Release files for vapoursynth-feel 1.0.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-feel 1.0.0
File Size Uploaded
vapoursynth_feel-1.0.0.tar.gz 17.2 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for vapoursynth-feel 1.0.0
File
vapoursynth_feel-1.0.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
vapoursynth_feel-1.0.0-py3-none-manylinux_2_34_x86_64.whl Python 3 none Linux glibc 2.34+ x86-64 Details
vapoursynth_feel-1.0.0-py3-none-manylinux_2_34_aarch64.whl Python 3 none Linux glibc 2.34+ ARM64 Details
vapoursynth_feel-1.0.0-py3-none-macosx_13_0_x86_64.whl Python 3 none macOS 13.0+ x86-64 Details
vapoursynth_feel-1.0.0-py3-none-macosx_13_0_arm64.whl Python 3 none macOS 13.0+ ARM64 Details

Total release size: 86.8 MB

Release files / vapoursynth_feel-1.0.0.tar.gz

Download URL vapoursynth_feel-1.0.0.tar.gz
Size 17.2 MB
Tags Source
SHA-256 checksum
How to use checksums
b62ab2f7ef411a7f9c4820093f1d87a734b65fb5125ba6087bfdd97f60025982
BLAKE2b-256 checksum
How to use checksums
39a2b030f1e2f6007d1560197a596a9e1ee5367ad4e69b1d6c034018adc22d9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 2, 2026.

Transparency log

Release files / vapoursynth_feel-1.0.0-py3-none-win_amd64.whl

Download URL vapoursynth_feel-1.0.0-py3-none-win_amd64.whl
Size 14.3 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
6ea87b7c9941bd2319d0619c9c5a04bc44b18bb7d3f1fb116f41e16fe1b73f53
BLAKE2b-256 checksum
How to use checksums
3acf54cba1d6baedb19ce9806cb8d5a54355867ea11ede57c33c549375c2a441
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 2, 2026.

Transparency log

Release files / vapoursynth_feel-1.0.0-py3-none-manylinux_2_34_x86_64.whl

Download URL vapoursynth_feel-1.0.0-py3-none-manylinux_2_34_x86_64.whl
Size 13.9 MB
Tags Linux glibc 2.34+ x86-64 Python 3
SHA-256 checksum
How to use checksums
1444c662356552c4897611d5e356a69a4eb24df0eff9b590af244917811b9adb
BLAKE2b-256 checksum
How to use checksums
8de824b4e291527d45aee520ef5802e98abf875b369f94f681e0b51404f60c76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 2, 2026.

Transparency log

Release files / vapoursynth_feel-1.0.0-py3-none-manylinux_2_34_aarch64.whl

Download URL vapoursynth_feel-1.0.0-py3-none-manylinux_2_34_aarch64.whl
Size 13.8 MB
Tags Linux glibc 2.34+ ARM64 Python 3
SHA-256 checksum
How to use checksums
4893acf733112bb3d7ac5f9498492785d3f9f02ff019a878a20a7034a283c13f
BLAKE2b-256 checksum
How to use checksums
c0d5af500f034768c6b4ee003a92f7b19118130bdc63a65cdbd5d2f95636dbb6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 2, 2026.

Transparency log

Release files / vapoursynth_feel-1.0.0-py3-none-macosx_13_0_x86_64.whl

Download URL vapoursynth_feel-1.0.0-py3-none-macosx_13_0_x86_64.whl
Size 13.8 MB
Tags Python 3 macOS 13.0+ x86-64
SHA-256 checksum
How to use checksums
b42c68387efdef83d7748ed19aab3bafb80d31eb5d4191e697713cc1be220748
BLAKE2b-256 checksum
How to use checksums
66b1e4789ff19fbfff9bf1ce3771efec45d5366e9e6bb9e14620e5b155e681a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 2, 2026.

Transparency log

Release files / vapoursynth_feel-1.0.0-py3-none-macosx_13_0_arm64.whl

Download URL vapoursynth_feel-1.0.0-py3-none-macosx_13_0_arm64.whl
Size 13.9 MB
Tags Python 3 macOS 13.0+ ARM64
SHA-256 checksum
How to use checksums
74231550819896866e56bb99973112459e2600abfa457d7d88d6679d38791902
BLAKE2b-256 checksum
How to use checksums
25f69579ba071767e862fc991e57b60b4ea6db5fb77f4b8d004aa3149ec47388
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 2, 2026.

Transparency log

Release history Release notifications | RSS feed

1.1.1

6 release files

1.1.0

6 release files

This release

1.0.0 This release

6 release files

0.2.2

3 release files

0.2.1

3 release files

0.2.0

3 release files

0.1.0

3 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