Spectral Angular Equalizer
When your image's energy leans one direction, equalize the angles
- image
- image
Some images have a directional bias you can feel before you can see: scanner line artifacts, JPEG block-grid energy piling up at 0° and 90°, fabric or architecture texture leaning horizontal-vertical, AI generators quietly preferring certain orientations. DirectionalArtifactSuppressor in this pack hunts isolated spikes in specific directions; SpectralAngularEqualizer does something broader and more systematic - it normalizes the entire angular energy distribution toward the isotropic mean, so no direction is dramatically louder than the others.
It's the angular counterpart to SpectralWhitening's radial equalization: where the radial nodes balance energy across frequency scales, this one balances energy across orientations. The source lists its targets bluntly: horizontal/vertical texture bias, scanner lines, JPEG block-grid artifacts, and AI-generation directional frequency preferences.
How it works
The FFT magnitude is binned into n_angle_bins angular sectors across 0–180°. For each sector, the node computes a gain that would pull that sector's mean energy toward the global mean. The equalize_power exponent controls how hard: at 1.0 every angle gets equalized to the same mean energy; at 0.5 you get a square-root gain - half the correction, softer, preserving more of the original bias; at 0.0 it's identity. Gains are clamped by min_gain/max_gain (so a near-silent direction can't be amplified into a 100× noise booster, and a dominant direction can't be crushed to nothing) and smoothed across adjacent bins so there are no sharp angular discontinuities. Phase untouched, and coefficients inside protect_radius are excluded entirely.
The inputs that matter
equalize_power(default 0.75) - the aggressiveness exponent, and the first knob to turn. The tooltip recommends starting at 0.5–0.75.n_angle_bins(default 36) - angular resolution (36 = 5° per bin). The tooltip's suggested range is 36–72; more bins = finer but noisier statistics.protect_radius(default 0.08) - normalized radius below which coefficients are excluded. This is the important safety valve: the source notes that low-frequency anisotropy is often real image content (a landscape is legitimately not isotropic at low frequencies), so it recommends 0.05–0.15.min_gain(default 0.1) - the floor on per-angle gain. At 0.1, the quietest direction can be boosted by at most 10×.max_gain(default 10.0) - the ceiling, preventing extreme suppression of dominant directions.strength(default 0.7) - overall blend between original and fully equalized.
Plus the pack-standard tile_size/tile_overlap for large images. 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 with ComfyUI); nothing to download.
Where people get burned
The failure mode is over-correcting real directionality into mush. An architectural shot should have strong vertical and horizontal energy - that's content, not artifact - and only protect_radius shields the low frequencies from your equalization. If you push equalize_power toward 1.0 on such an image, you'll start flattening that real structure. The useful differentiator the pack itself draws: use DirectionalArtifactSuppressor when you can point at a specific artifact direction, use this node when the bias is systemic across many angles (scanner grain, block grids). And check the visualizer's angular-profile panel before committing - a wide, smooth asymmetry is this node's target; a single needle is the suppressor's.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| strength | FLOAT | 0.700–1 | Blend between original (0) and fully equalized (1). |
| equalize_power | FLOAT | 0.750–1 | Exponent on the per-bin gain. 1.0 = full normalization (all angles equal energy). 0.5 = square-root gain (softer). 0.0 = no gain (identity). Start at 0.5–0.75. |
| n_angle_bins | INT | 368–180 | Number of angular sectors in [0°, 180°). 36 = 5° per bin. More bins = finer resolution but noisier statistics. 36–72 is a good range. |
| protect_radius | FLOAT | 0.080–0.5 | Normalised radius below which coefficients are excluded from equalization. Low-frequency energy reflects real image anisotropy (e.g. a landscape is not isotropic at low freq). 0.05–0.15 is recommended. |
| min_gain | FLOAT | 0.100.01–1 | Minimum per-angle gain. Prevents over-amplifying very quiet directions. 0.1 means the quietest direction can be boosted by at most 10×. |
| max_gain | FLOAT | 10.01–100 | Maximum per-angle gain. Prevents extreme suppression of dominant directions. |
| tile_size | INT | 00–2048 | Tile size for large images. 0 = whole image. |
| tile_overlap | INT | 640–512 | Tile overlap in pixels (used only when tile_size > 0). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |