ComfyUI Node

Noise Estimation

That 'texture' might just be noise. Here's how to measure it

By ThatGlennD·Created about a year ago·Updated about a month ago· 23
Noise Estimation
  • image
  • noise_score
  • noise_map
block_size32
visualize_noise_maptrue

Grain and noise are the classic "AI image looks wrong" culprits, and they're also the easiest thing to mistake for detail. Noise Estimation separates the two with one of the cleanest tricks in signal processing: blur the image, subtract the blur from the original, and whatever's left over is noise. Measure how much of that residual is floating around, and you've got a noise score plus a map of exactly where the grain lives.

It's part of ThatGlennD's ComfyUI-Image-Analysis-Tools pack, sitting naturally next to Entropy Analysis and Edge Density Analysis - the three of them together are your "is this texture real or is it garbage?" toolkit. (Entropy can't tell signal from noise, and edge density reads noise as edges; this node is the tie-breaker.)

How it works

The image goes grayscale, gets a 5×5 Gaussian blur (the "smoothing" the README mentions), and the blurred version is subtracted from the original. A smooth, clean image survives that subtraction with almost nothing left. A noisy one leaves a residual full of high-frequency speckle. That residual is then measured block by block - block_size, 8–128, default 32 - using the variance of each block as its noise level, and the mean of all blocks becomes noise_score. Higher = noisier. There's no interpretation string on this node; the number and the map carry the whole message.

The noise_map output (when visualize_noise_map is on) is a jet heatmap labeled "Noise Strength (Variance)", resized back up to the original dimensions. Bright regions are the noisy ones. It's genuinely useful for spotting where a problem lives: skin texture that's actually grain, banding in a sky gradient, or a patch of compression artifacts that shouldn't be there.

Block-size guidance from the README holds up: small blocks (16) capture fine noise like skin grain and background speckle, and are more sensitive (and slower); large blocks (64+) capture broad structure like banding and sky gradients, but smooth over fine grain.

Where it earns its keep

  • Diagnosing under-denoised output - the "did this sampler actually finish the job" check, or comparing samplers/schedulers on how clean their output lands.
  • Debugging compression artifacts in a post-processing chain.
  • Verifying a grain pass worked - add grain intentionally, then measure it to confirm you added what you think you added.

The reading direction is worth stating once: low = clean. If you wire this into an automated pipeline, your "keep" branch is the low-score branch.

Install

Manager (search "Image Analysis") or:

cd ComfyUI/custom_nodes
git clone https://github.com/ThatGlennD/ComfyUI-Image-Analysis-Tools
cd ComfyUI-Image-Analysis-Tools
pip install -r requirements.txt

Restart ComfyUI. Dependencies: numpy, opencv-python, matplotlib, scikit-learn, Pillow, torch. No models, no downloads, CPU-fast.

Common gotchas

  • Pack won't load: scikit-learn is imported at module load by the Color Harmony Analyzer, so a missing scikit-learn disables the whole pack. Windows portable: python_embeded\python.exe -m pip install scikit-learn.
  • comfy_api import error: update ComfyUI - the pack uses the newer node API.
  • First frame only: batches are scored on frame 0; feed video frames one at a time.
  • The score mixes real grain and JPEG artifacts. If you're comparing images, compare like-for-like - a PNG and a heavily compressed JPEG of the same render will score very differently, and that difference is the JPEG, not your sampler.

One honest limitation: the method is a blunt instrument. A 5×5 Gaussian is a fixed smoothing kernel, so texture that's finer than that kernel gets counted as noise even when it's legitimate detail. Use it as a relative meter between similar images, not an absolute quality verdict - and when a score surprises you, look at the map before you trust the number.

CategoryImage Analysis

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
block_sizeINT328–128
visualize_noise_mapBOOLEANtrue

Outputs (2)

NameTypeDescription
noise_scoreFLOAT
noise_mapIMAGE