FrFT Spectrum
A Fourier Transform With a Volume Knob
- image
- spectrum
You've probably seen a Fourier spectrum before even if you didn't know it: that point-symmetric smudge of bright dots you get when you decompose an image into its frequency parts. FrFT Spectrum is that, except it comes with a volume knob. Set the order to 1.0 and you get the standard FFT magnitude spectrum. Drop it to 0.0 and you get the input image back. Anything in between is a genuine blend of spatial and frequency content - that's the "fractional" in Fractional Fourier Transform.
So when would you reach for it? Frequency-domain analysis isn't a normal step in a generation workflow, and this node knows it. It's a debugging and curiosity tool. The classic move: run a rendered image through it and look at the spectrum for tell-tale spikes - checkerboard patterns, tiling seams, and resampling artifacts all leave fingerprints as bright off-center dots. It's also handy for comparing the noise structure of two latents or just getting an intuitive feel for what your denoiser is doing. It's the sort of thing you install out of curiosity, use twice to answer a question, and then it lives on your list of "analysis" nodes. That's fine - it's a one-node pack with no heavy dependencies, so it costs you nothing to keep.
How it works
This isn't a toy FFT wrapper. The pack implements the Ozaktas–Arikan–Kutay–Bozdagi (1996) fast discrete FrFT algorithm, the standard way to compute fractional orders on a finite signal. It's a three-step dance: reduce the order into the core range (0.5, 1.5) using ordinary FFT/IFFT steps, then a chirp premultiplication, an FFT-based convolution with a chirp kernel, and a chirp postmultiplication. The 2D transform is separable, so it runs 1D FrFTs along the rows and then the columns.
After the transform you get the magnitude, the zero-frequency is shifted to the center (the fftshift you know from any FFT display), and the result is normalized to [0, 1] as a displayable image. Nothing GPU-magic here: the node hands the tensor to numpy and does the math on CPU, which is fine for a one-off analysis and worth knowing before you batch a hundred images through it.
The inputs that matter
Of the five inputs, a beginner really touches three.
- order_x / order_y - the fractional orders along each axis.
0.0is identity,1.0is the plain FFT spectrum,2.0is the spatially reversed image,3.0is the inverse transform,4.0is back to identity. The interesting region is 0.5 to 1.5, where the spectrum starts curving into something that isn't quite spatial and isn't quite frequency. Setting x and y differently is a fun way to see the separable math in action, though for most questions you'll keep them equal. - log_scale - on by default, and leave it that way. Raw magnitude spectra are dominated by the bright low-frequency DC blob, which drowns everything else. The
log(1 + |F|)compression is what makes mid-range structure actually visible. Turn it off once to see the difference and you'll never turn it off again. - channel_mode -
luminanceconverts to grayscale (BT.601 weighted) and transforms once;per_channeltransforms each RGB channel independently. Luminance is the sane default for artifact spotting. Per-channel is mostly for when you suspect a problem lives in one color channel - and it's three times the compute, since each channel gets its own full 2D FrFT.
The single output, spectrum, is an IMAGE of shape [B, H, W, 3], so it plugs straight into any PreviewImage or SaveImage.
Installing it
The easiest path is ComfyUI Manager - search for ComfyUI_FrFT and install. Or, by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/bemoregt/ComfyUI_FrFT
Then restart ComfyUI. The node appears under image/transform as "FrFT Spectrum". The only dependency is numpy, which ships with ComfyUI already, so there are no model downloads and no virtualenv gymnastics. This is about as painless as a custom node gets.
Gotchas
The one thing worth knowing comes straight from the README: the algorithm is approximately unitary, and norm preservation error creeps up to ~15% near the boundary orders (0.5 and 1.5) because of finite-length discretization. That's expected behavior of the Ozaktas discrete FrFT - it doesn't affect the visual quality of the spectrum, so don't go chasing it as a bug. The additivity property (F_a ∘ F_b ≈ F_{a+b}) holds to within about 0.7% for smooth signals. If the node doesn't show up after install, restart ComfyUI properly (or hit rescan in Manager) - with a dependency this light, that's the only real failure mode. The pack has near-zero community footprint, so you're mostly on your own with it - but the README is honest and the source is short and readable if you want to check what a knob actually does.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| order_x | FLOAT | 1.000–4 | — |
| order_y | FLOAT | 1.000–4 | — |
| log_scale | BOOLEAN | true | — |
| channel_mode | COMBO | luminance | 2 options: luminance, per_channel |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| spectrum | IMAGE | — |