Latent Residue Cleaner (Advanced)
Every AI image carries an invisible noise fingerprint — this node scrubs it off
- image
- image
Diffusion models leave a thin coat of micro-noise on every image they decode - usually just 1–3 levels out of 255 per channel. Your eyes can't see it, but it's there, and it does two annoying things: it bloats your PNG/WebP file size, and it leaves a statistical fingerprint that AI-detection tools pick up on. Latent Residue Cleaner is a one-pass GPU node that scrubs that coat off with no visible quality loss. The name is a bit of a lie in one direction only - it doesn't touch latents at all. You feed it a decoded image, it gives you back a cleaner one.
Where it fits in the workflow
Treat this as a finishing node. It goes after the VAE decode and before saving, and the author's own advice is worth following: run it before final upscaling, because larger images are slower to process. The community's standing recipe agrees with that instinct - cleanup first, upscale after (the exact order is argued endlessly, but nobody puts a smooth pass last). It slots in right where you'd otherwise reach for a metadata-stripping or light post-processing step in pursuit of the "captured, not generated" look.
How it actually works
The pipeline runs three stages in sequence, all on CUDA with no OpenCV or extra dependencies:
- Latent Scrub - a guided filter plus a bilateral filter. Both are edge-preserving smoothers: they flatten the noise coat while keeping edges and detail intact. The guided filter (spatial sigma + color sigma) does the heavy lifting, then the bilateral pass cleans up what's left.
- Flat Snap - flood-fill finds connected regions of near-identical color (your typical sky or background) and snaps each one to a single uniform value. This catches micro-variations the bilateral pass misses.
- Hue Snap - near-white and near-black pixels carry invisible garbage hue. This unifies their hue to one consensus direction, which is exactly the tell that noise-detection plays pick up on.
Above 2048px it auto-tiles itself into a 2×2 grid with overlap so the guided filter doesn't freeze or blow up VRAM - a real gotcha this pack just handles for you.
The inputs that matter
The full list is long - honestly intimidating for what is conceptually a "clean up my image" button. Defaults are sane; you mostly touch these:
- image - the IMAGE tensor from your VAE decode (or Load Image).
- debug (default off) - turn this on once. You get a 2×2 grid: input vs final output on top, and the image after scrub and after flat snap on the bottom, all with the noise exposed. It's the only honest way to see whether the node is doing anything to your images.
- resolution_scaling (default off) - flip this on if you're feeding mixed megapixel sizes; it auto-scales the spatial parameters so settings tuned at one resolution don't overshoot at another.
- flat_snap_threshold and hue_snap_near_extreme - setting either to 0 disables that stage. If your image has no flat regions, Flat Snap does nothing; if it has no near-white/near-black, Hue Snap does nothing. Both are safe to disable if you're worried about them.
- bilateral_mode - defaults to "Separable Cross-Bilateral", which is the fast-and-accurate path. "Full 2D Bilateral" is an exact OpenCV match but slow; you rarely need it.
There's one output, image, and it flows straight into a Save Image or Preview Image node.
Installing it
It's a one-file pack, zero extra weight. In ComfyUI Manager, search Latent Residue Cleaner and hit install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/L33chKing/ComfyUI_LatentResidueCleaner
Then restart ComfyUI. No requirements.txt to resolve, no model downloads, no heavy dependencies - just torch and ComfyUI's own internals. That's genuinely rare in this ecosystem and worth appreciating.
Troubleshooting
- It's slow on big images. The README says a 4MP image takes ~5s on an RTX 3060. Lower
scrub_bilateral_dandscrub_bilateral_sigma_spaceto trade a bit of accuracy for speed, and run before upscaling. - You can't tell if it worked. That's what
debugis for. The before/after difference is invisible to the naked eye by design - the whole point is removing something you can't see. - It's CPU-capable but CUDA-first. The code falls back to CPU if you have no GPU, but the "~20× faster than OpenCV" claim assumes CUDA. On CPU you'll be waiting.
One honest caveat: this pack is young and tiny, with essentially no community footprint - no threads about it in the usual places, no battle-tested settings shared around. Trust the debug grid over any review: run it, zoom in, compare, and if your images don't show residue, you don't need it. For people shipping lots of images, the file-size reduction alone can be worth it - it's a legitimately clever little tool.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| resolution_scaling | BOOLEAN | false | When enabled, spatial parameters (kernel size, sigmas) are automatically scaled based on input resolution. Useful when processing images at different megapixel sizes. |
| scrub_edge_sigma_s | FLOAT | 1280–256 | Edge Preserving: spatial sigma. Auto-scaled by resolution. |
| scrub_edge_sigma_r | FLOAT | 0.010–1 | Edge Preserving: color sigma (0-1) |
| scrub_bilateral_d | INT | 2561–512 | Bilateral: pixel neighborhood diameter. Auto-scaled by resolution. |
| scrub_bilateral_sigma_color | FLOAT | 20–300 | Bilateral: sigma in color space |
| scrub_bilateral_sigma_space | FLOAT | 800–300 | Bilateral: sigma in coordinate space. Auto-scaled by resolution. |
| bilateral_mode | COMBO | Separable Cross-Bilateral | Separable Cross-Bilateral: iterative H+V cross-bilateral using original as color reference, fast and accurate. Bilateral Grid: iterative per-channel grid. Full 2D Bilateral: exact OpenCV match, slow. |
| bilateral_iterations | INT | 31–4 | Number of bilateral filter iterations. More iterations = closer to Full 2D quality but slower. 3 is recommended. Full 2D Bilateral ignores this. |
| flat_snap_threshold | INT | 10–25 | Max color difference (0-255) between adjacent pixels to be connected. 0 = disable Flat Snap entirely. |
| flat_snap_min_area | FLOAT | 0.010.001–100 | Minimum region size as percentage of the largest region found. E.g. 1.0 = regions must be at least 1% the size of the biggest region to be snapped. |
| flat_snap_max_spread | INT | 10–128 | Max color distance (0-255) from region mean to snap a pixel. 0 = no spread limit (snap all pixels in qualifying regions). |
| hue_snap_near_extreme | INT | 10–128 | How close to pure white/black (0-255) to snap hue. 0 = disable Hue Snap. |
| debug | BOOLEAN | false | Show 2x2 preview grid: top row = input vs final output, bottom row = after Latent Scrub vs after Flat Snap. All with noise-expose effect. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |