BM3D denoising filter for VapourSynth, implemented in Metal
Project description
VapourSynth-BM3DMETAL
Copyright© 2021 WolframRhodium
Copyright© 2025 Sunflower Dolls
BM3D denoising filter for VapourSynth, implemented in Metal.
Ported from VapourSynth-BM3DCUDA.
Description
-
Please check VapourSynth-BM3D for the original CPU implementation.
-
This Metal implementation leverages Apple's Metal API for GPU acceleration on macOS systems, providing efficient denoising on Apple Silicon and Intel Macs with Metal-capable GPUs.
Requirements
-
macOS 12.0 (Monterey) or later.
-
Metal-capable GPU:
- Apple Silicon (M1, M2, M3, or newer)
- Intel Mac with Metal-capable GPU (requires SIMD width/thread execution width of 32; older Intel GPUs may not be supported)
-
VapourSynth R74 or later on macOS.
Installation
For VapourSynth R74 or later, install both VapourSynth and this plugin from PyPI:
python3 -m pip install -U vapoursynth vapoursynth-bm3dmetal
vapoursynth config
The wheel installs libbm3dmetal.dylib into VapourSynth's Python package plugin
directory and provides a manifest.vs for autoloading.
Parameters
bm3dmetal.BM3D(clip clip[, clip ref=None, float[] sigma=3.0, int[] block_step=8, int[] bm_range=9, int radius=0, int[] ps_num=2, int[] ps_range=4, bint chroma=False, int device_id=0, bool fast=False])
-
clip:
The input clip. Must be of 32 bit float format. Each plane is denoised separately if
chromais set toFalse. Data of unprocessed planes is undefined. Frame properties of the output clip are copied from it. -
ref:
The reference clip. Must be of the same format, width, height, number of frames as
clip.Used in block-matching and as the reference in empirical Wiener filtering, i.e.
bm3d.Final/bm3d.VFinal:basic = core.bm3dmetal.BM3D(src, radius=0) final = core.bm3dmetal.BM3D(src, ref=basic, radius=0) vbasic = core.bm3dmetal.BM3D(src, radius=radius_nonzero).bm3d.VAggregate(radius=radius_nonzero) vfinal = core.bm3dmetal.BM3D(src, ref=vbasic, radius=r).bm3d.VAggregate(radius=r) # alternatively, using the v2 interface basic_or_vbasic = core.bm3dmetal.BM3Dv2(src, radius=r) final_or_vfinal = core.bm3dmetal.BM3Dv2(src, ref=basic_or_vbasic, radius=r)
corresponds to the followings (ignoring color space handling and other differences in implementation), respectively
basic = core.bm3d.Basic(clip) final = core.bm3d.Final(basic, ref=basic) vbasic = core.bm3d.VBasic(src, radius=r).bm3d.VAggregate(radius=r, sample=1) vfinal = core.bm3d.VFinal(src, ref=vbasic, radius=r).bm3d.VAggregate(radius=r)
-
sigma: The strength of denoising for each plane, defined as the standard deviation of the AWGN component, implying $Noise \sim \mathcal{N}(0, \sigma^2)$ on a $0\text{-}255$ scale.
The strength is similar (but not strictly equal) as
VapourSynth-BM3Ddue to differences in implementation. (coefficient normalization is not implemented, for example)Default
[3,3,3]. -
block_step, bm_range, radius, ps_num, ps_range:
Same as those in
VapourSynth-BM3D.If
chromais set toTrue, only the first value is in effect.Otherwise an array of values may be specified for each plane (except
radius).Note: It is generally not recommended to take a large value of
ps_numas current implementations do not take duplicate block-matching candidates into account during temporary searching, which may leads to regression in denoising quality. This issue is not present inVapourSynth-BM3D.Note2: Lowering the value of "block_step" will be useful in reducing blocking artifacts at the cost of slower processing.
-
chroma:
CBM3D algorithm.
clipmust be ofYUV444PSformat.Y channel is used in block-matching of chroma channels.
Default
False. -
device_id:
Set Metal GPU device to be used (for systems with multiple GPUs).
Default
0. -
fast:
Enables multi-threaded copy between CPU and GPU, consuming 4x more memory.
- Apple Silicon: Enabling this option will degrade performance. Keep it disabled.
- Intel Mac with AMD discrete GPU: May (or may not) provide slight performance improvement.
Default:
False. -
extractor_exp:
Used for deterministic (bitwise) output.
Pre-rounding is employed for associative floating-point summation.
The value should be a positive integer not less than 3, and may need to be higher depending on the source video and filter parameters.
Default
0. (non-determinism) -
zero_init:
This parameter only has an effect in temporal mode (
radius > 0).It controls the output of planes that are not being processed (i.e., where
sigmais set to 0).True(default): Unprocessed planes will be filled with zeros (resulting in a black image).False: Unprocessed planes will contain uninitialized data, which may appear as garbage or random noise.
This parameter has no effect in spatial mode (
radius = 0), as unprocessed planes are copied from the source clip. It also has no effect on planes that are actively being denoised.Default:
True.
Notes
-
bm3d.VAggregateshould be called after temporal filtering, as inVapourSynth-BM3D. Alternatively, you may use theBM3Dv2()interface for both spatial and temporal denoising in one step. -
The Metal implementation uses Metal Shading Language for GPU kernels, providing efficient computation on Apple platforms.
Statistics
GPU memory consumptions:
(ref ? 4 : 3) * (chroma ? 3 : 1) * (fast ? 4 : 1) * (2 * radius + 1) * size_of_a_single_frame
Compute complexity:
(chroma ? 3 : 1) * ceil((width - 8) / block_step + 1) * ceil((height - 8) / block_step + 1) * ((2 * bm_range + 1) * (2 * bm_range + 1) + 2 * radius * ps_num * (2 * ps_range + 1) * (2 * ps_range + 1)) * (ref ? 1.5 : 1) + (radius > 0 ? width * height * (chroma ? 3 : 1) * 2 * radius : 0)
Benchmarks
input: 1920x1080
chroma=False:GraySchroma=True:YUV444PS
data format: fps
| radius | chroma | final | M2 Pro 32GB (macOS 15.6.1) | M4 16GB (macOS 26.1) |
|---|---|---|---|---|
| 0 | False | False | 120.31 | 173.74 |
| 0 | False | True | 102.20 | 102.86 |
| 0 | True | False | 56.09 | 71.08 |
| 0 | True | True | 48.20 | 49.18 |
| 1 | False | False | 63.20 | 71.56 |
| 1 | False | True | 57.61 | 51.07 |
| 1 | True | False | 29.03 | 24.93 |
| 1 | True | True | 25.03 | 25.39 |
| 2 | False | False | 44.35 | 58.43 |
| 2 | False | True | 39.69 | 53.94 |
| 2 | True | False | 20.34 | 16.46 |
| 2 | True | True | 18.46 | 11.99 |
Compilation
Requires CMake 3.20 or later, Xcode Command Line Tools, and VapourSynth's Python package.
python3 -m pip install -U "VapourSynth>=74"
cmake -S . -B build -D CMAKE_BUILD_TYPE=Release
cmake --build build --config Release
The compiled dynamic library (libbm3dmetal.dylib) will be located in the build/lib directory. Copy it to your VapourSynth plugins directory.
If CMake cannot locate VapourSynth's headers from Python, pass
-D VAPOURSYNTH_INCLUDE_DIRECTORY="/path/to/vapoursynth/include".
License
This project is licensed under the GNU General Public License v3.0 or later (GPLv3+).
Based on VapourSynth-BM3DCUDA by WolframRhodium, which is licensed under GPLv2 or later.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vapoursynth_bm3dmetal-4.0.0.tar.gz.
File metadata
- Download URL: vapoursynth_bm3dmetal-4.0.0.tar.gz
- Upload date:
- Size: 33.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69486b6992d944d029c2268c3472f137d7183aabf0c71c387a27907a26f89de3
|
|
| MD5 |
54add0234cccce6b4e03a99466de5d86
|
|
| BLAKE2b-256 |
2fc0f8b1f2924cc039d6f4558de62e4a532b486a2b9beeefa649ca237c3c5403
|
Provenance
The following attestation bundles were made for vapoursynth_bm3dmetal-4.0.0.tar.gz:
Publisher:
release.yml on Sunflower-Dolls/Vapoursynth-BM3DMETAL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vapoursynth_bm3dmetal-4.0.0.tar.gz -
Subject digest:
69486b6992d944d029c2268c3472f137d7183aabf0c71c387a27907a26f89de3 - Sigstore transparency entry: 1743199381
- Sigstore integration time:
-
Permalink:
Sunflower-Dolls/Vapoursynth-BM3DMETAL@40c7fc04d1074b1f57302512b7e80335e29f493a -
Branch / Tag:
refs/tags/R4 - Owner: https://github.com/Sunflower-Dolls
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@40c7fc04d1074b1f57302512b7e80335e29f493a -
Trigger Event:
push
-
Statement type:
File details
Details for the file vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_x86_64.whl.
File metadata
- Download URL: vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_x86_64.whl
- Upload date:
- Size: 46.5 kB
- Tags: Python 3, macOS 12.0+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57bb9cb70fb3d9767b931cb59dd7d74546ba3a65c853e9c25a7a2e8135f98778
|
|
| MD5 |
9eecc7a759653b1fdc5e86bf20567870
|
|
| BLAKE2b-256 |
07f669558b5f20340c89803205f223a0c7a3939cc8ea0b654faac4218b603687
|
Provenance
The following attestation bundles were made for vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_x86_64.whl:
Publisher:
release.yml on Sunflower-Dolls/Vapoursynth-BM3DMETAL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_x86_64.whl -
Subject digest:
57bb9cb70fb3d9767b931cb59dd7d74546ba3a65c853e9c25a7a2e8135f98778 - Sigstore transparency entry: 1743199415
- Sigstore integration time:
-
Permalink:
Sunflower-Dolls/Vapoursynth-BM3DMETAL@40c7fc04d1074b1f57302512b7e80335e29f493a -
Branch / Tag:
refs/tags/R4 - Owner: https://github.com/Sunflower-Dolls
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@40c7fc04d1074b1f57302512b7e80335e29f493a -
Trigger Event:
push
-
Statement type:
File details
Details for the file vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_arm64.whl.
File metadata
- Download URL: vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_arm64.whl
- Upload date:
- Size: 46.8 kB
- Tags: Python 3, macOS 12.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c332b3d1ecb7a15d8ffe4e09dd27f86bf8ec1d08eb67cd4fb42ae130e26e1b21
|
|
| MD5 |
f9f4360f07bce98a05823866a0aee57a
|
|
| BLAKE2b-256 |
aeaffff409c6801f9ab684bef895694ab709edfdf6a52e16b2713b4bf9104226
|
Provenance
The following attestation bundles were made for vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_arm64.whl:
Publisher:
release.yml on Sunflower-Dolls/Vapoursynth-BM3DMETAL
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vapoursynth_bm3dmetal-4.0.0-py3-none-macosx_12_0_arm64.whl -
Subject digest:
c332b3d1ecb7a15d8ffe4e09dd27f86bf8ec1d08eb67cd4fb42ae130e26e1b21 - Sigstore transparency entry: 1743199478
- Sigstore integration time:
-
Permalink:
Sunflower-Dolls/Vapoursynth-BM3DMETAL@40c7fc04d1074b1f57302512b7e80335e29f493a -
Branch / Tag:
refs/tags/R4 - Owner: https://github.com/Sunflower-Dolls
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@40c7fc04d1074b1f57302512b7e80335e29f493a -
Trigger Event:
push
-
Statement type: