cv2.SVDecomp
The singular values are the interesting part
- src
- w
- u
- vt
cv2.SVDecomp factors a matrix: M = U · diag(w) · Vᵀ. If your linear algebra is rusty, the practical summary is that w tells you how much each direction of the matrix actually matters, and u/vt tell you which directions those are. Throw away the small w values and you've denoised or rank-truncated the thing; keep everything and you've got a stable inverse.
That's why this pairs so tightly with cv2.SVBackSubst: decompose, edit or just accept w, then back-substitute to solve a system. And why the source array has to be a float matrix - this node is for data, not pictures.
One of roughly 470 auto-generated raw cv2.* wrappers in ComfyUI CV (bmad4ever/comfyui_cv). Uncurated by definition: the LLM-generated wrappers map cv2's signature onto sockets and stop there.
Inputs and outputs
src is NPARRAY-only, and the tooltip is explicit: "a data array (points / matrix), NOT an image". Build it with Parse Matrix (paste a text table), CV Camera Matrix, CV Matrix Multiply's output, CV Eye, or any node that emits an ndarray. cv2 wants CV_32F or CV_64F here, and integers will get rejected - CV Cast Array is the fix.
flags is a dropdown of OpenCV's SVD bits, and the pack's tooltip spells out what each one does: SVD_NO_UV skips computing u and vt (singular values only, faster), SVD_FULL_UV forces full-size square u and vt, and SVD_MODIFY_A lets the decomposition clobber the input - "safe here", as the tooltip notes, because the wrapper passes cv2 a copy. The default is none (0), which gives you the reduced form.
Three outputs: w (the singular values), u and vt. All NPARRAY. The most useful one is usually w - read it with Inspect CV Data or CV Array To Text and you can see the rank of a matrix, spot a degenerate homography, or watch a covariance's condition number blow up.
The recipe people actually want
Least-squares solve with rank truncation, in four nodes:
- Parse Matrix or another array source → your
A. cv2.SVDecompwith flagsnone (0)→w,u,vt.- Those three plus
rhs(yourb, also anNPARRAY) → cv2.SVBackSubst. - The
nparrayoutput isx, the solution.
Between steps 2 and 3 you can threshold w - zero out the small singular values with the array arithmetic nodes and you've built a truncated-SVD denoiser, which is the single most common reason to decompose anything. If the solve comes back the wrong shape or garbage, set SVD_FULL_UV on the decomposition: OpenCV's back-substitution wants the full u and vt when the right-hand side has as many rows as the smaller dimension.
The inspection use case
Honestly, half the real-world value is diagnostic. Decompose a homography and look at w: two healthy singular values of similar magnitude plus a tiny third is what a sane projective transform looks like. Decompose a design matrix and the gap in w tells you the engineering rank before you try to invert a singular system and get infinities. The pack's 56_matrix_decomposition.json workflow is the general form of this idea - it builds matrices from known parts, decomposes, reassembles, and compares, and the note on its canvas makes the point that a decomposition which doesn't reconstruct is one you've misread.
Installing the pack
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
cd comfyui_cv && pip install "opencv-contrib-python-headless~=5.0.0.93"
Or Manager → search ComfyUI CV → install → restart. Requires Python ≥ 3.12 and a ComfyUI on the V3 node API. The OpenCV wheel must be contrib - all four distributions share one site-packages/cv2, so installing plain opencv-python over it empties the contrib submodules; tools/repair_opencv_contrib.py --check/--apply is the pack's repair path. Behaviour is curated against 5.0.0.93, and support is explicitly not promised.
Where it bites
Integer inputs throw an OpenCV depth error - cast to float first. Signature confusion between u and vt costs people an hour: OpenCV returns the transpose of V, which matters enormously if you're multiplying factors back together by hand and not at all if you're feeding SVBackSubst, which expects exactly this. And nothing here accepts an IMAGE: if your matrix came from a picture, go through Image → CV Array.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY | - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| flagsopt | STRING | none (0) | - - - cv2.SVDecomp flags: one of none (0) plus any of SVD_MODIFY_A, SVD_NO_UV, SVD_FULL_UV, pipe-joined (e.g. "none (0) | SVD_MODIFY_A"). In the UI this renders as a dropdown with one toggle per flag. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| w | NPARRAY | — |
| u | NPARRAY | — |
| vt | NPARRAY | — |