PSF Normalize (Auto-center)
The silent fixer that stops your convolutions shifting and blowing out
- image
- image
PSF Normalize (Auto-center) is the pack's unglamorous but essential prep node. PSF stands for point-spread function - the fancy name for a blur kernel, the little patch of brightness that describes how one point of light smears into a blob. If you want to convolve an image with a custom kernel (blur it, motion-blur it, or sharpen it), you feed the kernel's spectrum into FFTMultiply alongside the image's spectrum. And if you skip this node, two classic disasters await: your convolved image comes out shifted by half the canvas, and its brightness comes out wrong.
This node fixes both, and it's the reason the pack's convolution and deconvolution lessons (6 and 7) work at all. Its own docstring says it plainly: it's kept as an explicit step so the pipeline stays visible - PSF image → PSFNormalize → ImageFFT2D → FFTMultiply → ImageIFFT2D.
What it actually does
Two jobs, both automatic. First, auto-centering: it finds the kernel's centroid (the brightness-weighted center of mass) and rolls the image so that centroid lands at the origin [0, 0], matching np.fft.fft2's coordinate convention. That's the fix for the half-canvas shift. If you draw a blur kernel with its peak at the center of the canvas - which is the natural way to draw one - and FFT it without this step, the convolution treats the kernel as if its mass were at the corner, and your output slides diagonally. This node kills that.
Second, normalization: it divides each channel by its pixel sum so the kernel's total energy is 1. That's the fix for the brightness blow-up. A kernel that sums to more than one multiplies the image's overall brightness, and after an IFFT you get a washed-out result. Sum-to-one keeps the energy-preserving.
The single input is image (the kernel/PSF image); the single output is image, normalized and centered, ready for ImageFFT2D. It works per-channel but applies one shared spatial shift to all channels, so RGB kernels stay aligned.
When you'd reach for it
Any time you're doing convolution or deconvolution with a kernel you made or loaded rather than a canned one. The repo's own example, PSF_blur_640x480.png, goes through this node in the deconvolution lesson. The honest framing: this node exists because getting the kernel right is the difference between a working convolution and a debugging session, and the pack wants that step visible rather than hidden inside a transform.
How to install it
Standard for the pack. ComfyUI Manager → search ComfyUI-FFT-2D → install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/NobutakaKuroki/ComfyUI-FFT-2D
Restart ComfyUI. No pip dependencies beyond numpy and torch, no model files to download. It's part of Dr. Nobutaka Kuroki's MIT-licensed educational pack, and lesson_workflows/6_Convolution.json plus 7_Deconvolution.json are the workflows that show why this little node is worth remembering.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |