BM3D Film Grain Denoising
The name says BM3D, the engine underneath doesn't
- image
- denoised_image
- processing_info
Here's the honest thing to know before you drop this node into a workflow: despite the name, it doesn't run the BM3D algorithm. Under the hood it calls scikit-image's Non-Local Means denoiser and adapts the strength to your image's resolution - the pack's own code comments call it an "approximation." That's not a knock on the node; NLM is a perfectly good denoiser and the resolution-aware tuning here is genuinely useful. It's just not what the name promises, and if you came here specifically wanting block-matching 3D filtering, that's the separate BM3D Denoising node (and its sibling, BM3D Profile Comparison), which import the real bm3d library.
What it actually does
This node is built for one specific job: cleaning up film grain and digital sensor noise on high-resolution images (think 1–20 megapixels) without the strength scaling with the file size the way a fixed-sigma denoiser would. It calculates your image's megapixel count and automatically dials the denoising strength down as resolution climbs - a preset that looks "medium" on a 2MP scan gets quietly reduced on an 8MP one, because a fixed sigma value hits large images much harder than small ones. It also adapts the patch size and search distance for the same reason. None of this needs a GPU or a model file; it's classical image processing end to end.
Inputs and outputs that matter
Just two things you actually set:
grain_strength- a preset dropdown:ultra_lightfor barely-there cleanup on already-sharp high-res images,light,mediumfor general balanced denoising,heavyfor aggressive removal, orcustomto set your own sigma.custom_sigma- only read whengrain_strengthiscustom. The tooltip's own guidance: 3–5 for very light touch on high-res, 15–20 for medium, 25–35 for heavy.preserve_texture(boolean, default on) - trims the effective sigma further to keep the film's natural grain character instead of scrubbing it flat. Turn it off if you want maximum noise removal and don't care about texture.
It outputs denoised_image and a processing_info string that reports the megapixel count it detected, the scale factor it applied, and the final effective sigma it used - useful for understanding why the same preset looks different on two images of different sizes.
Installing it
Through ComfyUI Manager, search Eric's Image Processing Nodes. By hand:
cd ComfyUI/custom_nodes
git clone https://github.com/EricRollei/Eric_Image_Processing_Nodes
cd Eric_Image_Processing_Nodes
pip install -r requirements.txt
Restart ComfyUI. This particular node doesn't need the bm3d package (unlike its BM3D-named siblings), doesn't need CUDA, and doesn't download any model weights - it's the low-friction option in the pack if you just want grain control that works immediately.
Where people get burned
The main trap is expectation, not a bug: if you're chasing the specific look of real BM3D collaborative filtering - its particular way of preserving fine repeating texture by borrowing from similar patches elsewhere in the frame - this node won't get you there, because it isn't running that algorithm. Use it when you want a resolution-aware grain cleanup that "just works" on a batch of variously-sized scans, and reach for the actual BM3D Denoising node when the specific algorithm matters to you.
The other thing worth knowing: preserve_texture and grain_strength interact multiplicatively (texture preservation shaves the effective sigma by roughly 20% on top of whatever the preset already set), so if heavy with texture preservation on still looks too aggressive, that's the resolution scaling doing its job on a smaller image - try medium before reaching for custom.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| grain_strength | COMBO | medium | Film grain strength preset: • ultra_light: Minimal grain removal (high-res images) • light: Subtle grain removal • medium: Balanced denoising • heavy: Strong grain removal • custom: Use manual sigma value |
| custom_sigmaopt | FLOAT | 15.01–80 | Custom noise standard deviation (only used with 'custom' preset): • 3-5: Very light denoising (high resolution) • 8-12: Light denoising • 15-20: Medium denoising • 25-35: Heavy denoising |
| preserve_textureopt | BOOLEAN | true | Preserve film texture characteristics: • True: Maintain natural film look • False: Maximum noise removal |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| denoised_image | IMAGE | — |
| processing_info | STRING | — |