Spectral Whitening
The data-driven spectral flattening that doesn't assume a curve
- image
- image
Spectral whitening is the classic signal-processing move: measure the actual power at every frequency, then divide each coefficient by its measured power so every band ends up equally loud - the spectrum is "whitened." SpectralWhitening brings that to ComfyUI, but with a twist that makes it genuinely different from the pack's other radial node: it's fully data-driven, with no model assumption about what the spectrum "should" look like.
Compare it to RadialSpectrumNormalizer, which fits the 1/f^α law and nudges your spectrum toward it. That node assumes the curve. This one measures your image's actual radial power envelope and corrects whatever bias is really there - a bump, a hump, an unexpected shape - regardless of its form. The README positions it as more aggressive than RadialSpectrumNormalizer precisely because it corrects the actual measured bias rather than assuming a model shape. If your image has a weird spectral signature that no power-law model would capture, this is the node that can handle it.
How it works
The node bins the FFT magnitude into n_radial_bins rings, measures the mean power in each ring, and builds a gain curve that's the inverse of that envelope - dividing each coefficient by the actual power at its radius. Two modes:
flatten- true whitening: every radial band gets equal mean power. The source calls this aggressive, because a fully flat spectrum is not what natural images look like.target_1f(default) - data-driven reshape toward atarget_alphaslope (default 2.0, natural pink noise). Same measurement-and-correct mechanism, but aimed at the natural curve instead of full flatness. This is the sane default.
Safety rails: the DC coefficient is always protected, gains are clamped by min_gain/max_gain (so the noise floor can't be amplified without limit and near-DC bands can't be crushed), and smoothing Gaussian-smooths the gain curve to prevent per-ring ringing. Phase is never touched.
The inputs that matter
mode(defaulttarget_1f) -target_1fis the practical choice;flattenis the science experiment.target_alpha(default 2.0) - target slope fortarget_1fmode; 2.0 = natural pink noise. Ignored inflattenmode.strength(default 0.6) - blend between original and fully whitened. This is your main dial; the pack's style is "start low and verify."n_radial_bins(default 64) - radial resolution for power estimation. The tooltip's sweet spot is around 64.smoothing(default 0.08) - smoothing sigma for the gain curve, as a fraction ofn_radial_bins; 0.05–0.15 recommended.min_gain/max_gain(defaults 0.05 / 20) - the clamps. Leave them.
Plus the pack-standard tile_size/tile_overlap. One image output.
Installing it
Part of ComfyUI-Spectral-Preprocessing-Nodes - one install, all sixteen nodes under Spectral Preprocessing. ComfyUI Manager (search "ComfyUI-Spectral-Preprocessing-Nodes"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/EdoardoGuerriero/ComfyUI-Spectral-Preprocessing-Nodes
Restart. Only numpy and scipy (bundled); nothing to download.
Where people get burned
Two things. First, flatten mode is a trap for anyone who reads "whitening" and thinks "yes, maximum." A flat spectrum is not a natural image, and full whitening on strength 1.0 will make the output look odd and textureless - keep mode on target_1f unless you specifically want to see what flat looks like. Second, more aggressive than its model-based sibling means it can over-correct if the per-bin statistics are noisy: that's what smoothing is for, so don't drop it below ~0.05 on small images. The honest guidance from the pack's own framing: use RadialSpectrumNormalizer when your image is mostly healthy and you just want a gentle nudge toward natural; reach for SpectralWhitening when the spectrum has a shape no 1/f^α model explains. When in doubt, target_1f, strength 0.3–0.6, and the visualizer's radial-profile panel will tell you the rest.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| strength | FLOAT | 0.600–1 | 0 = no change, 1 = full whitening. |
| mode | COMBO | target_1f | 'target_1f' — reshape power spectrum to r^(−target_alpha). 'flatten' — true whitening: equal power at all radii (aggressive). |
| target_alpha | FLOAT | 2.00–4 | Target power spectral slope for 'target_1f' mode. 2.0 = natural pink noise (typical natural images). 0.0 = flat / white (same as 'flatten' mode). Values above 2 over-emphasise low frequencies. Ignored in 'flatten' mode. |
| n_radial_bins | INT | 648–256 | Number of radial bins for power estimation. More bins = finer correction but more sensitive to per-bin noise. 64 is a good default. |
| smoothing | FLOAT | 0.080–0.5 | Gaussian smoothing sigma for the radial gain curve, as a fraction of n_radial_bins. Higher values prevent per-bin ringing artifacts. 0.05–0.15 recommended. |
| min_gain | FLOAT | 0.050.001–1 | Minimum per-bin gain — prevents amplifying the noise floor beyond this. |
| max_gain | FLOAT | 201–200 | Maximum per-bin gain — prevents over-suppressing near-DC bands. |
| tile_size | INT | 00–2048 | Tile size for large images. 0 = whole image (recommended). |
| tile_overlap | INT | 640–512 | Tile overlap in pixels. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |