Nodes/opencv-comfyui/OpenCV dft_0
ComfyUI Node

OpenCV dft_0

Fourier transforms in ComfyUI — the deep end, done properly

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV dft_0
  • src
  • dst
  • nparray
flags
nonzeroRows

dft_0 runs OpenCV's discrete Fourier transform on an image - it takes the spatial-domain pixels and decomposes them into frequency-domain components (real and imaginary parts), which is the mathematical raw material for a whole class of image processing that has no spatial-domain equivalent. Blur detection, watermarking, phase correlation, Wiener deconvolution, notch filtering: all of them live here. It's also the hardest node in this pack to use casually, so let's be honest about what you're signing up for.

The mechanism: cv2.dft computes the DFT of a single-channel array. For image work you feed it a grayscale image and it returns a 2-channel complex array - channel 0 is the real part, channel 1 the imaginary - which is not something you can look at as a picture. The famous "frequency spectrum" image you've seen is the magnitude (sqrt(real² + imag²)) of that, often log-scaled, which requires further math this pack doesn't give you directly. So dft_0 is a building block, not a viewable result.

The inputs that matter:

  • src - NPARRAY. This is where most people hit the wall: cv2.dft wants a single-channel float32 image, so your typical uint8 BGR image from Image2Nparray will trip an assertion (src.type() == CV_32F-ish). You'll need to convert to grayscale (cvtColor with code 6) and cast to float32, which means a numpy node from another pack in your path. The README's img.type() == CV_8UC1 error is the mild cousin of this.
  • flags - INT, and this one genuinely matters. The useful values are 16 (DFT_COMPLEX_OUTPUT, return real+imag as 2 channels - the default for forward transforms), 1 (DFT_INVERSE, inverse transform), 2 (DFT_SCALE, divide by N - you want this combined with inverse to reconstruct), and 32 (DFT_REAL_OUTPUT, assume the input was conjugate-symmetric and return only the real part). For a plain forward transform: 16.
  • nonzeroRows - a performance hint for when only the top rows of the input are nonzero. Leave it 0.

Optional dst is an out-parameter - skip it, per the pack README. Output: one nparray, the complex spectrum, which you'd feed into divSpectrums_0 or an inverse dft to close the loop.

Why you'd bother: mostly, you wouldn't, unless you're building something specific. The one pattern that shows up in real workflows is frequency-domain filtering - transform, multiply or divide the spectrum (that's divSpectrums_0's job), inverse transform. Doing that correctly requires the float32 pipeline above and a solid grip on why you're in frequency space at all. For the 99% case - "I want my image sharper" - a spatial filter like detailEnhance_0 is what you actually want.

Install: ships in geroldmeisinger/opencv-comfyui (Manager → search "OpenCV", or git clone https://github.com/geroldmeisinger/opencv-comfyui into custom_nodes), restart, needs opencv-contrib-python. The pack-wide conflicting-wheels error (Cannot import name 'guidedFilter' ...) will block all of it if it bites. dft_1 is this same node under the overload-suffix scheme - identical.

Categoryimage/OpenCV

Inputs (4)

NameTypeDefaultDescription
srcNPARRAY
flagsINT
nonzeroRowsINT
dstoptNPARRAY

Outputs (1)

NameTypeDescription
nparrayNPARRAY