cv2.mulTransposed
The Gram matrix in one node
- src
- nparray
If you ever wondered what's underneath PCA, eigenfaces, the normal equations in a least-squares fit, or a covariance matrix of keypoint coordinates, the answer is usually this: multiply a matrix by its own transpose. cv2.mulTransposed is that operation as a node, with the transpose on whichever side you want.
Concretely, with aTa false it computes src · srcᵀ; with aTa true it computes srcᵀ · src; and scale multiplies the product. Which one you want is decided by which way your data is laid out - OpenCV's own documentation spells out the convenience cases (for a set of points stored as rows, the transposed form gives you the second-moment matrix you actually want in the small dimension).
Why it's here and not in your nightly workflow
In an image-generation graph this node is upstream of nothing popular. Its natural customers are the analysis nodes: cv2_SVDecomp (eigen-decompose the result for principal directions), cv2_PCACompute, cv2_eigen, and any least-squares solve. The pack's calibration and shape-matching pipelines are where that math lives - a N×2 array of keypoints goes in, a 2×2 structure tensor comes out, and the orientation of the dominant direction comes out of the eigenvector. Feed it a stack of flattened region descriptors and it's the Gram matrix behind a covariance/PCA feature reduction, which is the honest way to shrink a feature matrix before matching.
Two details from the author's own tooltip worth knowing. It takes a single-channel matrix, and unlike gemm it can multiply not only floating-point matrices - so you can hand it 8-bit or 16-bit integer data and let the output depth do the setting. And dtype is where you set that: the dropdown offers the whole depth list, but the valid choices here are CV_32F and CV_64F. Everything else will error or surprise you.
It does not subtract the mean. mulTransposed gives you a second-moment matrix; a covariance matrix also needs the mean removed first (cv2_subtract against the mean, or let cv2_calcCovarMatrix do both). If your PCA is giving you a principal direction that looks suspiciously like the data's overall magnitude, that's this mistake.
Inputs and outputs
src is a required NPARRAY - a data array, not an image; the socket won't take an IMAGE. aTa is a boolean, not optional: true means srcᵀ·src, false means src·srcᵀ. scale defaults to 1.0. dtype defaults to "same as input" and should be CV_32F or CV_64F for floating-point work. One output, nparray, holding the resulting matrix.
Getting the matrix in is the part that needs planning, because a graph isn't a script. The pack's type-bridge nodes are the answer: Parse Matrix for a delimited blob of text, CV Points for a literal point array, CV Concat Arrays to stack vectors, CV Reshape Array (required before cv2 arithmetic on (3,) rows), and CV Array To Numbers / Inspect CV Data on the other end to see what you got. And yes, the socket technically accepts an IMAGE link as a storable matrix - but a BGR uint8 picture is a nonsense Gram matrix, so don't.
Install
ComfyUI Manager → search ComfyUI CV → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Python ≥ 3.12, V3-node-API ComfyUI. Core cv2, no models, no contrib submodule.
Small print
- Layout decides
aTa. Get it backwards and you get a matrix of the wrong shape, usually without a clear error. Know whether your rows or columns are the samples. - Mean-centre before you call it a covariance.
dtypeis not a free choice.CV_32F/CV_64F; the dropdown's other entries are there because the same depth enum is shared across hundreds of wrappers.- The auto-generated wrappers carry no curated documentation of their own - for this one, OpenCV's own docs for
mulTransposedare the reference, and the README admits the generated layer is uncurated.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY | input single-channel matrix. Note that unlike gemm, the function can multiply not only floating-point matrices. A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| aTa | BOOLEAN | false | Flag specifying the multiplication ordering. See the description below. |
| scaleopt | FLOAT | 1.0000-1e+38–1e+38 | Optional scale factor for the matrix product. Preset to the OpenCV default (1.0). |
| dtypeopt | COMBO | same as input | Optional type of the output matrix. When it is negative, the output matrix will have the same type as src . Otherwise, it will be type=CV_MAT_DEPTH(dtype) that should be either CV_32F or CV_64F . |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |