cv2.accumulateSquare
Variance without a second pass
- src
- dst
- mask
- nparray
cv2.accumulateSquare does dst += src². With cv2.accumulate next to it, that's the two-pass-free way to get a variance: Var = E[x²] − (E[x])². One node gives you the sum of values, the other the sum of squares, and the division is yours.
It's a low-level primitive from comfyui_cv - one of ~470 auto-generated cv2.* wrappers the pack generates from the OpenCV type stubs - and like its siblings it's honest about being arithmetic, not an estimator. No state, no normalisation, no picture.
How it works
Each pixel's value gets squared and added into a float accumulator. The docstring's requirement is the same as the rest of the accumulation family: dst is 32-bit or 64-bit floating point with the same channel count as src, and an optional mask limits which elements update.
Squares of 8-bit data are large fast. 255² = 65025; over 60 frames that's 3.9 million in one accumulator cell. Float32 holds it comfortably - a uint8 dst doesn't exist as an option, which is why OpenCV specifies a float accumulator in the first place. Feed dst an IMAGE link and you're handing OpenCV uint8, so don't.
And as with the whole family: the wrapper passes OpenCV a private copy of dst, your input array is never mutated, and nothing carries over between executions. One square-accumulate per run.
Inputs and outputs
src(NPARRAY,IMAGE,MASK) - 1- or 3-channel, 8-bit or float.dst(NPARRAY,IMAGE,MASK) - your float accumulator. Build it with CV Constant Like (zeros) → CV Cast Array (float32).mask(optional) - accumulate only where it's set.- nparray - the updated accumulator.
What it's for
The honest answer: statistics that vision code computes about a region or a stack, not pictures.
- Noise estimation. Two accumulators over a static scene (sum, sum of squares), divide by N, subtract the squared mean. The result is a per-pixel variance map - which is a map of where the sensor is noisy and where the scene actually moves. That's a genuinely useful thing to have in a video pipeline.
- Temporal variance as a motion cue. Where variance is low you have a static background; where it explodes, motion. It's cruder than optical flow and about a thousand times cheaper.
- Feeding a covariance / PCA path.
Σx²is a diagonal term of the covariance matrix; the pack has PCA and matrix nodes downstream when you want the full thing. - Slice statistics via masks. Accumulate a region's sum of squares by masking that region.
The pairing to remember is cv2_accumulate for Σx and this for Σx². Neither is useful alone, and the pack ships both.
If what you actually want is a displayable square of an image, cv2_multiply (image × image) is the node; if you want a square root back, cv2_sqrt. This one is the accumulator.
Install
ComfyUI Manager → comfyui_cv / ComfyUI CV, or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Restart ComfyUI. Python ≥ 3.12 and a recent V3-API ComfyUI are required; behaviour is curated against OpenCV 5.0.0.93. The contrib wheel matters - a plain opencv-python installed over it silently strips contrib submodules and makes nodes disappear.
Where people get burned
uint8 dst. The recurring one. Cast to float32.
Reading the accumulator as an image. A Σx² map with values in the millions min-max normalises to a plausible-looking picture that tells you nothing about magnitude. If the number matters, Inspect CV Data or CV Array Statistic; if it doesn't, preview away.
Mixed depths. float64 sources against a float32 accumulator raise. Normalise the pair first with CV Cast Array.
Expecting accumulation over a batch. It doesn't work that way: the batch path gives every frame a fresh copy of the dst you supplied, so a 20-frame batch is 20 separate square-adds, not one sum. If you want one sum, collapse the frames into a single array first (CV Stack Batch), or accumulate in a loop you control.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY,IMAGE,MASK | Input image as 1- or 3-channel, 8-bit or 32-bit floating point. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| dst | NPARRAY,IMAGE,MASK | %Accumulator image with the same number of channels as input image, 32-bit or 64-bit floating-point. The low-level cv2 function writes its result into this array in place, but this wrapper passes cv2 a private copy, so your input array is never modified. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| maskopt | NPARRAY,IMAGE,MASK | Optional operation mask. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |