OpenCV dft_0
Fourier transforms in ComfyUI — the deep end, done properly
- src
- dst
- nparray
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.dftwants a single-channel float32 image, so your typical uint8 BGR image fromImage2Nparraywill trip an assertion (src.type() == CV_32F-ish). You'll need to convert to grayscale (cvtColorwith code 6) and cast to float32, which means a numpy node from another pack in your path. The README'simg.type() == CV_8UC1error is the mild cousin of this.flags- INT, and this one genuinely matters. The useful values are16(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), and32(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 it0.
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.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY | — | |
| flags | INT | — | |
| nonzeroRows | INT | — | |
| dstopt | NPARRAY | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |