OpenCV matMulDeriv_0
The matrix-derivative node that has no idea it's in a diffusion tool
- A
- B
- dABdA
- dABdB
- nparray_0
- nparray_1
If you've landed on matMulDeriv_0, you are not looking for a way to make prettier images. You're looking for the analytic derivative of a matrix product, inside a node graph that mostly thinks about latents and noise schedules. Be honest with yourself about that before you wire anything up, because this node is here for one reason: the opencv-comfyui pack auto-generates a node for every top-level OpenCV function it can express, and cv2.matMulDeriv was one of them. It exists because it exists.
That's not a knock on the pack. Gerold Meisinger's opencv-comfyui wraps ~635 standalone cv2 functions, and the README opens with "Expect dragons!" for exactly this reason - you get the full surface of OpenCV, ugly and un-curated, including the 10% that makes sense only in a computer-vision grad course.
What it actually computes
cv2.matMulDeriv(A, B) computes the partial derivatives of the matrix product C = A·B with respect to each factor, and returns them as a pair:
dABdA- ∂(AB)/∂AdABdB- ∂(AB)/∂B
The math, if you're into that sort of thing: ∂C/∂A applied to an input is Bᵀ and ∂C/∂B is Aᵀ - the derivatives come straight from the shapes of the two matrices, which is why OpenCV can hand you the whole Jacobian in one call. In the wider CV world this is the workhorse of nonlinear least-squares calibration loops and bundle-adjustment-ish pipelines, where you need the Jacobian of a re-projection error with respect to the unknowns.
The inputs and outputs that matter
Both inputs are NPARRAY - the pack's internal type for numpy arrays, not ComfyUI's IMAGE:
- A and B - the two matrices you're multiplying.
- dABdA and dABdB - these are optional
NPARRAYinputs, and here's the trap: in OpenCV they're out-parameters, preallocated buffers the function fills. The pack passes them straight through, so you should leave them disconnected. The README says this explicitly: "Avoid the optional out-parameters (usually calleddst)."
The outputs are nparray_0 (dABdA) and nparray_1 (dABdB), the two derivative matrices. Both are matrices, not images - do not route them into Nparrays2Image or you'll get the classic 'NoneType' object has no attribute 'shape' because a matrix isn't a picture.
What about matMulDeriv_1?
The _0/_1 suffix is the pack's way of numbering overloads - OpenCV's stub file lists matMulDeriv twice, once for MatLike and once for UMat arguments, and the generator emitted one node per overload. Practically, _0 and _1 are the same node with the same inputs, outputs, and behavior. Pick either. The UMat overload would be the GPU-accelerated path, but the pack has no Image2UMat node, so everything runs on CPU nparrays anyway.
Installing
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
Or just search "opencv-comfyui" in ComfyUI Manager and hit install. The pack needs opencv-contrib-python, numpy, and torch (check the requirements.txt). If your ComfyUI already has OpenCV from another custom node, you're probably fine; the classic failure is Cannot import name 'guidedFilter' from 'cv2.ximgproc', a version conflict between two nodes wanting different OpenCV builds.
Real talk: unless you're building an odd analytical-optimization workflow in the graph, you won't reach for this. If you are - it's a clean wrapper, and the out-param advice above is the difference between it working and it throwing at you.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| A | NPARRAY | — | |
| B | NPARRAY | — | |
| dABdAopt | NPARRAY | — | |
| dABdBopt | NPARRAY | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| nparray_0 | NPARRAY | — |
| nparray_1 | NPARRAY | — |