-
Notifications
You must be signed in to change notification settings - Fork 2
NLMeans
dnjulek edited this page Jul 9, 2026
·
3 revisions
Non-local means denoiser — an OpenCL port matching KNLMeansCL (knlm.KNLMeansCL).
Non-local means denoises by replacing each pixel with a weighted average of pixels across a search window, where a neighbour's weight comes from the similarity of the small patches around the two pixels. It preserves texture and detail that simpler denoisers blur away.
Output matches knlm.KNLMeansCL to the floating-point floor (≈1 ULP; the difference is only
native_exp/native_divide rounding).
vszipcl.NLMeans(vnode clip[, int d=1, int a=2, int s=4, float h=1.2, data channels="auto", int wmode=0, float wref=1.0, vnode rclip, int device_id=0, int num_streams=1, int[] tune])- clip:
Clip to process. 8/16-bit integer, 16-bit half, or 32-bit float; Gray / YUV / RGB. - d: (Default: 1, range: 0..16)
Temporal radius.0= spatial only (single frame);d > 0averages over a2d+1frame window. - a: (Default: 2, range: 1..64)
Spatial search radius. The search window is(2a+1) × (2a+1). - s: (Default: 4, range: 0..8)
Patch radius (similarity window). The patch is(2s+1) × (2s+1). - h: (Default: 1.2)
Filtering strength. Higher removes more noise (and more detail). Must be> 0. - channels: (Default: "auto")
Which channels to denoise (like KNLMeansCL):- Gray:
"Y"(or"auto"). - YUV:
"Y"(luma),"UV"(chroma), or"YUV"(all three jointly — requires 4:4:4). - RGB:
"RGB"(or"auto").
- Gray:
- wmode: (Default: 0, range: 0..3)
Weight function applied to the patch distance (matching KNLMeansCL'swmode), whereargis the normalized patch distance:-
0:exp(-arg)(exponential decay) -
1:max(1 - arg, 0) -
2:max(1 - arg, 0)^2 -
3:max(1 - arg, 0)^8
-
- wref: (Default: 1.0)
Weight of the reference (center) pixel in the average. Must be≥ 0. - rclip: (Default: None)
Reference / guide clip. When set, the patch weights are computed fromrclipwhile the averaged pixels come fromclip(the classic NLM oracle/guide split). Must matchclip's format, dimensions and frame count. - device_id / num_streams: see Home.
- tune: (Default: unset)
Launch-geometry override —[blk_x, blk_y, vrt, qb, pin_min_streams](work-group tile + per-thread rows + displacement batching + the pinned-staging stream threshold). The ship defaults are the measured Ampere values used on every vendor, so you can retune at runtime — especially on AMD / Apple — instead of rebuilding; untuned is byte-identical to the ship build. See Tune for the full table, ranges, and vendor starting points.
out = core.vszipcl.NLMeans(src) # spatial, luma
out = core.vszipcl.NLMeans(src, d=1, a=3, s=2, h=0.8) # temporal, stronger search
out = core.vszipcl.NLMeans(src, channels="UV") # chroma only
out = core.vszipcl.NLMeans(src, channels="YUV") # all planes (4:4:4)
out = core.vszipcl.NLMeans(src, rclip=prefiltered) # guided (weights from rclip)-
his depth-independent (defined on the same normalized scale as KNLMeansCL at every bit depth). - Integer/half output matches the float-path result requantized (≈1-code from the float floor); f16 output is the IEEE-rounded f32 pipeline.
1080p YUV420, fps (higher is better), RTX 3070 Ti — see Benchmarks for method.
d=1, a=2, s=4, h=1.2.
| Implementation | u16 | f16 | f32 |
|---|---|---|---|
| vszipcl (s=1) | 151.0 | 145.8 | 117.8 |
| vszipcl (s=2) | 155.3 | 154.7 | 121.2 |
| nlm_cuda (s=1) | 83.2 | — | 64.3 |
| nlm_cuda (s=2) | 88.3 | — | 73.3 |
| knlm | 75.8 | 75.5 | 62.4 |