Nodes/ComfyUI CV/cv2.ft.FT02D_components
ComfyUI Node

cv2.ft.FT02D_components

The half of the fuzzy transform you can edit

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
cv2.ft.FT02D_components
  • matrix
  • kernel
  • mask
  • nparray

cv2.ft.filter runs the fuzzy transform forward and back in one go, which is what 95% of people want. cv2.ft.FT02D_components gives you the forward half on its own - the component coefficients - so you can do something to them before cv2.ft.FT02D_inverseFT rebuilds a picture. That "something" is the entire reason the ft module exists: coefficient-domain compression, thresholding, and analysis of the coarse structure of an image.

It's a raw wrapper in ComfyUI CV (bmad4ever), the pack that exposes OpenCV 5.0 to ComfyUI as ~470 auto-generated cv2.* nodes plus a curated layer. Expect OpenCV's parameters, NPARRAY sockets, and no hand-holding - but the mechanism is worth understanding, because it's a rare thing in a ComfyUI graph: a lossy image representation you can hold as data.

What a fuzzy transform actually is

The image is covered by overlapping membership functions on a grid whose spacing is the radius. For each block, the transform computes a coefficient summarising the image under that membership function - one number per channel per block. That set of coefficients is the transform's view of the image. The inverse transform ("defuzzifies") rebuilds a picture from them, and because the partition is coarse, what comes back is a piecewise-smooth approximation rather than the original.

So the pipeline is: image → components (small, coarse, few numbers) → [whatever you do to them] → image. The OpenCV sample use case is compression and denoising; in a ComfyUI graph the interesting version is inspection: if your rebuild is wrong, the coefficients are where you look, and the pack gives you the tools - Inspect CV Data for a shape/dtype/statistics summary, CV Array To Text for a table, Preview CV Array with its heatmap mode for a look at the values.

The sockets

  • matrix - the input image. IMAGE, MASK or NPARRAY; the wrapper converts an IMAGE tensor to a uint8 BGR ndarray (frame 0 of a batch).
  • kernel - the fuzzy kernel from cv2.ft.createKernel. Its radius defines the partition, and the kernel's channel count has to match the matrix's (3 for BGR, 1 for grayscale).
  • mask - optional. The author's tooltip: "Mask can be used for unwanted area marking. The function computes components using predefined kernel and mask." Leave it unconnected unless you specifically want to exclude regions from the transform - an unconnected optional socket simply isn't passed to cv2.
  • Output: nparray, the components, 32-bit float.

Round-tripping by hand

The pairing that matters: components out of this node → cv2.ft.FT02D_inverseFT with the same kernel and the target width / height, and you get your image back. Use the same kernel. A different radius describes a different partition, and the inverse has no way to know the coefficients came from somewhere else - you'll get a garbage reconstruction, not an error.

The zero-everything test is worth doing once: components straight into the inverse, same kernel, and compare against the input. That's your baseline. Threshold, drop, or quantise the coefficients afterwards and diff again, and you can see exactly what the coefficient-domain edit did to the picture - which is a much better experiment than guessing at filter parameters.

Install

ComfyUI Manager → ComfyUI CV, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install -r comfyui_cv/requirements.txt

Python ≥3.12, a current ComfyUI on the V3 node API, restart when done. The dependency is opencv-contrib-python-headless~=5.0.0.93, and contrib is load-bearing: cv2.ft doesn't exist in the plain wheel, so this node is simply absent on a non-contrib install. Since all four OpenCV distributions share one site-packages/cv2, an opencv-python install over the contrib wheel empties the contrib submodules with no error. The pack's tool is the check:

python ComfyUI/custom_nodes/comfyui_cv/tools/repair_opencv_contrib.py --check

Common issues

Kernel and matrix channel counts disagree. cv2 raises rather than guessing. Build a 3-channel kernel for a colour image and a 1-channel one for grayscale, and don't reuse a kernel across branches with different channel counts.

The reconstruction is nonsense. Wrong kernel (different radius from the one that produced the components), or components from a different image entirely. Both are silent until you look at the picture.

Radius 0. A 1×1 kernel means a degenerate partition; the components will be effectively the image itself and nothing interesting happens.

Shape surprises when you inspect the components. The layout isn't an image - don't try to preview it as one. Use Inspect CV Data and CV Array Shape rather than the image preview nodes; that's what they're for, and the pack keeps them deliberately separate from the drawing nodes.

Categoryimage/CV/low-level/ft

Inputs (3)

NameTypeDefaultDescription
matrixNPARRAY,IMAGE,MASKInput array. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
kernelNPARRAY,IMAGE,MASKKernel used for processing. Function `ft::createKernel` can be used. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.
maskoptNPARRAY,IMAGE,MASKMask can be used for unwanted area marking. The function computes components using predefined kernel and mask. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size.

Outputs (1)

NameTypeDescription
nparrayNPARRAY—