cv2.setIdentity
The Neutral Matrix Your Math Chain Starts From
- mtx
- nparray
Most nodes in this pack do something to an image. This one writes a matrix. cv2.setIdentity fills a matrix with an identity - 1s down the main diagonal, 0s everywhere else, or a constant s down the diagonal if you give it one - and it exists in the node menu because a graph that composes transforms needs a starting point that means "do nothing."
It's the same reason you keep CV Matrix Multiply, CV Compose Pose (Trajectory), cv2.invertAffineTransform and CV Matrix To Pose around: once you're building geometry inside ComfyUI, at some point you want a transform buffer that starts neutral, accumulates, and stays neutral if nothing upstream contributes. An identity matrix is that buffer. Multiply anything by it and you get the anything back.
Inputs and output
Two fields, one output:
mtx- the matrix to initialise, and it does not have to be square. The node takes the array, fills it, and hands it back.s(optional) - the value assigned to the diagonal elements, written as a cv2 Scalar literal."0.5"gives you a diagonal of 0.5s;"(0, 255, 0)"gives a per-component diagonal. A bare number broadcasts to every component, so"255"means(255, 255, 255, 255). Leave it blank for the OpenCV default (a diagonal of ones).nparray- the filled matrix. This socket isNPARRAYonly; the input is too. No IMAGE or MASK link is accepted on either side, and that's deliberate: this is array math, not picture math.
Worth being explicit about the shape, because it's where this node is easiest to misread: s sets the diagonal. It is not an off-diagonal fill, and it is not a scale on the whole matrix. s = 2 is a uniform 2× scaling matrix, which is either exactly what you wanted or a small edit away from it.
The pack's own note on dst-style parameters applies here in spirit - cv2 versions of these functions write into the array you pass, but the wrapper always hands cv2 a private copy, so nothing downstream in your graph gets silently mutated by a fill-in-place operation.
Where this actually shows up
- Seeding a matrix chain. Wire an identity into a
cv2.matMul/cv2.gemmaccumulate step as the neutral first term, so a looped or branched graph has a well-defined starting transform instead of an unconnected socket. - A known-good
Mfor a warp.cv2.warpAffine,cv2.warpPerspectiveand friends want a transform. If a branch might have no homography (no match found), an identity keeps the frame passing through unwarped instead of failing the run - the same failure-tolerant pattern the pack's curated nodes use with theirfoundflags. - Uniforms scaling in a pose chain.
s = 1for a rigid chain,s = scalewhen you want the matrix to carry a uniform scale. Combined with CV Pose To Matrix / CV Matrix To Pose, that's how you insert or strip uniform scale at a chosen point in a 3D chain. - Testing. When an affine estimate looks wrong, replace it with an identity and confirm the rest of the graph is innocent.
If you need an identity-like matrix of a specific size, build the shape with Parse Matrix (typed literals), Points Literal, or CV Scalar, then run it through this node so the diagonal is guaranteed correct rather than a literal you typo'd. And if you want something other than 1s and 0s, cv2.completeSymm and CV Cast Array are the neighbours worth knowing.
Install
Manager → search ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Restart ComfyUI afterwards. Python ≥ 3.12, recent V3-API ComfyUI, no models required.
Where people get burned
s is a Scalar literal, not a number input. The field is a STRING precisely so it can carry "(0, 255, 0, 64)"-style vectors; "(0, 1)" is not a matrix literal, and typing a Python tuple where the widget expects a cv2 Scalar's spelling is the usual parse error.
Why isn't this node in the menu? The pack builds its ~470 low-level wrappers at import time by probing the installed cv2. If the function isn't there, the node simply doesn't exist - no red box, no error. Before assuming a bug, check cv2.__version__ and that you have a contrib wheel: the four OpenCV distributions share one site-packages/cv2, and installing a non-contrib one over the contrib build quietly empties the contrib submodules. tools/repair_opencv_contrib.py --check diagnoses it.
Identity matrices don't fix a broken system. It's neutral, not correct - if your solve returns nonsense, an identity seed just makes the nonsense well-formed.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| mtx | NPARRAY | matrix to initialize (not necessarily square). A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here. | |
| sopt | STRING | value to assign to diagonal elements. cv2 Scalar as a literal, e.g. "(0, 255, 0)" (BGR) or "(0, 255, 0, 64)" (BGRA). A bare number broadcasts to every component, so "255" means (255, 255, 255, 255). Components past the target's channel count are ignored by OpenCV. Leave blank for the OpenCV default. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |