Nodes/ComfyUI CV/cv2.completeSymm
ComfyUI Node

cv2.completeSymm

The matrix half you didn't compute

By bmad4ever·Created 4 months ago·Updated 16 days ago· 1
cv2.completeSymm
  • m
  • nparray
◄lowerToUpperfalse►

The one-line pitch

cv2.completeSymm takes a square floating-point matrix, picks one triangle, and copies it into the other one - turning a half-filled matrix into a symmetric one. If that sounds narrow, it is. This is a data-plumbing node, in the same family as the rest of ComfyUI's invisible middle layer (comfyui-node-plumbing.md is the map of that layer), and it earns its spot in exactly one workflow shape: you computed or accumulated a symmetric quantity and only one half is actually filled.

It's a raw OpenCV wrapper from ComfyUI CV (bmad4ever/comfyui_cv), category image/CV/low-level/cv2 C.

How it works

OpenCV's completeSymm mirrors a triangle across the diagonal. Which triangle wins is the lowerToUpper flag: True copies the lower half up, False (the default) copies the upper half down. Values on and above/below the diagonal are overwritten accordingly - the half you kept is authoritative, the other half is discarded.

One behaviour worth knowing because the pack made it safe: in C++ this function writes into its argument in place. The wrapper hands cv2 a private copy, so the array you passed in - which may be another node's cached output - is never modified. You get a new NPARRAY out, the input stays as it was. If you were counting on mutation (you shouldn't be, in a graph), that's not how this works.

It requires a square floating-point matrix. Not an int matrix, not a non-square one.

Inputs and outputs that matter

  • m - required, NPARRAY only. A data array (the author's tooltip is explicit that a point set / matrix is expected and that a MASK or IMAGE link is rejected here). Square, float.
  • lowerToUpper - optional BOOLEAN, default False, and it's an advanced input so it's collapsed until you show advanced inputs. Set it to True only when you know the lower triangle is the populated one.

Output: nparray - the completed square matrix.

Where it fits in a real graph

The honest answer is that a beginner probably never needs this, and an intermediate user reaches for it when doing geometry by hand in NPARRAY space. The three cases that actually come up:

  1. Accumulated second-moment / covariance matrices. If a graph builds a matrix by writing one triangle at a time (a covariance, a Gram matrix, an information matrix), the other half is zeros and any downstream eigen-decomposition or inversion is silently wrong. This is the fix.
  2. Symmetrising an estimated matrix before decomposing it. A fundamental matrix or a projective quantity estimated from noisy points may be slightly asymmetric; symmetrising first makes eigen/determinant behaviour predictable.
  3. Round-tripping data between nodes that disagree about which triangle they write.

You do not need this to make a symmetric matrix symmetric - that's a no-op. If you're here because your matrix math is producing nonsense, check first whether the matrix is square and floating point; a shape error surfaces as an OpenCV assert, but an int matrix often fails more quietly than you'd hope.

Related nodes in the same pack worth knowing about: CV Matrix Multiply (left @ right) is how you'd actually combine matrices here, and CV Array Statistic / CV Slice Array are the inspection tools when the numbers look wrong. Preview CV Array has a heatmap mode, which is the fastest way to see whether your matrix is half-zeros before you go looking for a cause.

Installing the pack

Manager → search ComfyUI CV, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv

Restart ComfyUI. Python ≥ 3.12 and a V3 node API build are hard requirements; the dependencies are opencv-contrib-python-headless~=5.0.0.93, numpy and torch.

Where people get burned

  • Square and float, or nothing. The two most likely errors, and neither gives you a nice message. If you've got an integer array, cast it first (CV Cast Array).
  • The wrong half. With lowerToUpper=False on a matrix whose lower triangle holds the real values, you mirror the zeros up and lose the data. No error - just a wrong answer downstream, and usually several nodes later.
  • Reading the pack's own record. The README states that development leaned heavily on LLMs, that some workflows appear overfitted to their test examples (they cite the Hu-moment case), that updates are not planned, and that the pack shouldn't be used in production without your own review. Extremely obscure utilities like this one are the most likely place for an undetected mistake - so for calibration or 3D math you actually care about, verify against a numpy result rather than trusting the node. There's no Reddit corpus for this pack to fall back on: a search turns up nothing.
Categoryimage/CV/low-level/cv2 C

Inputs (2)

NameTypeDefaultDescription
mNPARRAYinput-output floating-point square matrix. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
lowerToUpperoptBOOLEANfalseoperation flag; if true, the lower half is copied to the upper half. Otherwise, the upper half is copied to the lower half. Preset to the OpenCV default (False).

Outputs (1)

NameTypeDescription
nparrayNPARRAY—