Nodes/opencv-comfyui/OpenCV divSpectrums_0
ComfyUI Node

OpenCV divSpectrums_0

Frequency-domain division — the inverse filter's best friend

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV divSpectrums_0
  • a
  • b
  • c
  • nparray
flags
conjB

divSpectrums_0 divides one Fourier spectrum by another, element by element - cv2.divSpectrums(a, b, c, flags, conjB). It's the frequency-domain cousin of divide_0, and it exists for exactly one neighborhood of work: deconvolution, phase correlation, and any other operation that needs to divide in frequency space. If you don't already know you need this, you probably don't - but if you're building an inverse-filter or a phase-correlation chain, it's the missing primitive.

The mechanism first, because it dictates everything else about this node. A forward dft produces a complex spectrum (2 channels: real and imaginary). divSpectrums takes two such spectra, a and b, and computes a / b per element. The conjB flag - the interesting bit - conjugates b before dividing, and conjugating the denominator without dividing by its magnitude is exactly the phase-correlation trick that makes template matching invariant to brightness. With conjB off, you get plain complex division, which is the naive inverse filter: divide the blurred image's spectrum by the blur kernel's spectrum, inverse-transform, and the blur is (theoretically) undone. That "theoretically" is doing a lot of work - naive inverse filtering amplifies noise brutally, which is why people use Wiener filters - but the division primitive is where it all starts.

The inputs that matter:

  • a, b - NPARRAYs, both complex spectra (2-channel, same size, from dft_0). Feeding it plain spatial images will error or produce garbage.
  • flags - INT, the DFT flag family: 0 for the basic per-element division is the common case; you can combine with DFT_ROWS (4) if you're processing row-wise.
  • conjB - BOOLEAN. True = conjugate b first (phase correlation); False = straight complex division (inverse filtering).

Optional c is an out-parameter - skip it. Output: one nparray, the quotient spectrum, ready for an inverse dft to bring back to spatial domain.

The realistic workflow looks like: Image2Nparray → grayscale + float32 cast → dft_0divSpectrums_0 (with the kernel's spectrum) → inverse dft with DFT_SCALENparrays2Image. That's a lot of moving parts, and every one of them - especially the float32 requirement before dft - is a place to trip. This is the deep end of the pack, no two ways about it.

Install: ships in geroldmeisinger/opencv-comfyui - Manager → search "OpenCV", or git clone https://github.com/geroldmeisinger/opencv-comfyui into custom_nodes, restart, with opencv-contrib-python installed. The pack-wide Cannot import name 'guidedFilter' error from conflicting OpenCV wheels blocks the whole pack.

Honest framing: divSpectrums_0 is for people deliberately doing Fourier-domain image processing - it's not a casual utility. If that's your project, this is the right primitive. If it isn't, divide_0 in the spatial domain is probably what you actually wanted. divSpectrums_1 is the identical overload twin.

Categoryimage/OpenCV

Inputs (5)

NameTypeDefaultDescription
aNPARRAY
bNPARRAY
flagsINT
conjBBOOLEAN
coptNPARRAY

Outputs (1)

NameTypeDescription
nparrayNPARRAY