Nodes/ComfyUI CV/cv2.accumulateSquare
ComfyUI Node

cv2.accumulateSquare

Variance without a second pass

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.accumulateSquare
  • 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.

Categoryimage/CV/low-level/cv2 A

Inputs (3)

NameTypeDefaultDescription
srcNPARRAY,IMAGE,MASKInput 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.
dstNPARRAY,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.
maskoptNPARRAY,IMAGE,MASKOptional 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)

NameTypeDescription
nparrayNPARRAY—