Nodes/ComfyUI_PhaseStretchTransform/Phase Stretch Transform
ComfyUI Node

Phase Stretch Transform

The edge detector that thinks your image is a light wave

By bemoregt·Created 5 months ago·Updated 5 months ago· 1
Phase Stretch Transform
  • image
  • edge_image
  • phase_image
lpf_sigma0.21
phase_strength0.48
warp_strength12.1
min_thresh-0.350
max_thresh0.350
morph_flagfalse
output_modegrayscale

The name makes it sound like a physics lab gone rogue, which is honestly closer to the truth than most node names. Phase Stretch Transform (PST) is a real edge-detection algorithm from UCLA's Jalali lab that treats your image like a light wave passing through a dispersive medium, and this pack drops it into ComfyUI as one clean node under image → processing. There's essentially zero community buzz around it - we checked the usual forums and found nothing - so you're early. Whether that's exciting or a warning sign depends on how much you like fiddling with frequency-domain math. If you just want edges, Canny exists. PST is for when you want different edges.

Why you'd reach for it

When a ControlNet needs structural conditioning, most people grab Canny: thin, hard, reliable, boring. PST is the interesting alternative in the preprocessor pile. Instead of gradients and hysteresis, it works in the frequency domain and pulls edges out of the phase of a warped wave. That gives it a different failure-and-success profile - it's less twitchy about photographic noise, and it tends to catch edges Canny smooths away, especially in textured or low-contrast areas. For architecture or mechanical subjects you'll probably stay on Canny. For noisy photos, organic subjects, or just variety in a line-art or sketch workflow, PST is worth a look.

How it works

The node grayscales your image, FFTs it, applies a Gaussian low-pass in the frequency domain, then multiplies by a "warped phase ramp" kernel - a pure-phase filter that warps the spectrum according to the warp_strength parameter. Inverse FFT, take the phase angle, threshold it, and you've got edges. Toggle morph_flag and it runs a binary closing/opening pass to tidy the map into clean connected lines.

One honest gotcha: this runs on CPU via numpy/scipy, looping frame-by-frame in Python. Great for a single still; don't feed it a video batch and expect speed.

The knobs that matter

You'll set three of them 90% of the time:

  • lpf_sigma - Gaussian low-pass FWHM (yes, FWHM, not sigma - the code follows the reference implementation). Higher = more smoothing up front, fewer false edges from noise.
  • phase_strength (S) - how hard phase variations get amplified. More edges, including weak ones.
  • warp_strength (W) - how aggressively the frequency spectrum is warped. Higher values emphasize finer, sharper edges.

Then min_thresh/max_thresh slice the phase into the binary map (only used when morph_flag is on), morph_flag switches between binary-with-cleanup and a soft continuous map, and output_mode picks white-edges-on-black versus red-overlay-on-original.

Outputs and where they go

You get two IMAGE outputs. edge_image is the white-on-black map - hand that straight into a ControlNet Apply node, since canny-style ControlNet models are trained on exactly that format, or use it for line-art styling. phase_image is the raw normalized phase, a soft gradient map that's handy for debugging or as a gentler conditioning input. Both are three-channel, so nothing in the wiring fights you.

Install

ComfyUI Manager → search "PhaseStretchTransform", or the manual way:

cd ComfyUI/custom_nodes
git clone https://github.com/bemoregt/ComfyUI_PhaseStretchTransform
cd ComfyUI_PhaseStretchTransform
pip install numpy scipy

Restart ComfyUI. No model files to download, MIT licensed, done.

Troubleshooting

  • ImportError: scipy - ComfyUI ships numpy but scipy isn't guaranteed. pip install scipy and restart.
  • The README is out of date. It lists min_thresh -1.0, max_thresh 0.003, morph_flag True; the shipped code defaults to -0.35, 0.35, False. Trust the node's own defaults - the README numbers produce a noticeably thicker, noisier map.
  • Edges look messy - raise lpf_sigma and tighten the thresholds toward zero rather than cranking the strength knobs.
Categoryimage/processing

Inputs (8)

NameTypeDefaultDescription
imageIMAGE
lpf_sigmaFLOAT0.210.01–1Gaussian LPF FWHM (same unit as reference code). Higher = more smoothing before PST.
phase_strengthFLOAT0.480–10PST phase strength (S). Higher = stronger edge response.
warp_strengthFLOAT12.10–100PST warp strength (W). Controls frequency warping.
min_threshFLOAT-0.350-3.15–0Lower phase threshold for binary edge map (morph_flag=True only)
max_threshFLOAT0.3500–3.15Upper phase threshold for binary edge map (morph_flag=True only)
morph_flagBOOLEANfalseTrue = binary edges with morphological clean-up; False = soft continuous edge map (|phase| normalised)
output_modeCOMBOgrayscalegrayscale = white edges on black; rgb_overlay = edges overlaid in red on original

Outputs (2)

NameTypeDescription
edge_imageIMAGE
phase_imageIMAGE