cv2.accumulate
Cv2.accumulate is one +=, not a running total
- src
- dst
- mask
- nparray
cv2.accumulate adds one image into an accumulator: dst += src. It is the building block for frame averaging, temporal denoising and background modelling - and the first thing to know is that this node will not do those things on its own, because it holds no state between executions.
That surprises people, so let's be blunt about the mechanism before the use cases.
How it works
Two image inputs, one output: src gets added into dst, and the result comes back as an NPARRAY. dst is documented by OpenCV as a 32-bit or 64-bit float accumulator with the same channel count as src - an 8-bit dst is out of spec, and if you wire a plain IMAGE into it you're handing OpenCV a uint8 array. Don't.
The wrapper passes OpenCV a private copy of dst, which is good (your incoming array is never mutated) and bad (nothing persists). And per the pack's own batching notes, the accumulate family runs frame-by-frame with a fresh dst per frame - no cross-frame state by design. So feeding a 30-frame IMAGE batch gives you 30 independent src + dst sums stacked back up, not one running total. If you expected a temporal average out of a video batch, this is why you didn't get one.
What you do get: an unclamped float sum. That's not nothing. cv2.add saturates at the container's limits; accumulate into float accumulates 40 frames of noise without losing the headroom.
Inputs and outputs
src(NPARRAY,IMAGE,MASK) - the frame to add in. IMAGE becomes uint8 BGR, MASK becomes single-channel uint8.dst(NPARRAY,IMAGE,MASK) - the accumulator. Float32 is what you want.mask(optional) - only masked pixels contribute.- nparray - the new accumulator, as raw array.
To make a legitimate float accumulator: CV Constant Like (a constant-filled array - zeros) → CV Cast Array (to float32) → wire into dst. Then wrap the whole thing in a real iteration. ComfyUI has no native loop, so in practice you either use a pack that provides one, run the graph repeatedly by hand, or step back and ask whether you actually want temporal accumulation as a node at all.
What it's genuinely for
- Summing frames you already have as an array batch. Stack the frames into one NPARRAY (
CV Stack Batch) and accumulate in one pass, then divide - that's a mean image, and a mean image is a denoiser if the subject is static and the noise isn't. - Bias / illumination accumulation. Summing several shots of a static scene isolates sensor patterns.
- Feeding arithmetic that follows. Accumulate is the
Σxhalf of a statistic;accumulateSquareis theΣx²half.
If you want the stateful version of this - a model that learns a background over a clip and then reports foreground - the pack already has it, and it's the curated CV Background Subtract (Batch) (MOG/MOG2/KNN/GMG/CNT over a clip). That's the node to reach for when "accumulate" was really shorthand for background modelling. cv2_accumulateWeighted is the one-function relative of it.
Install
ComfyUI Manager → comfyui_cv / 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. Python ≥ 3.12, recent V3-API ComfyUI, behaviour pinned to OpenCV 5.0.0.93. Keep the contrib wheel: install plain opencv-python over it and contrib nodes disappear from the menus.
Where people get burned
A uint8 dst. Either an OpenCV error or silent nonsense, depending on the build. Cast to float32 first - that's CV Cast Array's whole job in this pack.
Expecting running state. See above. Two runs are two independent adds against whatever dst you fed.
Values beyond 255 looking "blown out". Your accumulator is legitimately holding 3000; it's the preview that min-max normalizes it. Inspect with Inspect CV Data or CV Array Statistic rather than trusting the thumbnail, and if you need to view it, divide or normalize first.
Silent nothing from the mask. A MASK that is mostly zeros contributes almost nothing - which is correct, and looks like a broken node if you forgot you wired one.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY,IMAGE,MASK | Input image of type CV_8UC(n), CV_16UC(n), CV_32FC(n) or CV_64FC(n), where n is a positive integer. 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, and a depth of CV_32F or CV_64F. 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 | — |