CV Background Model (Update)
One step of temporal background subtraction with a single-Gaussian per-pixel model (MOG2 without the mixture). Given the running per-pixel 'mean' and 'variance' of the scene so far and the current 'frame', it flags pixels that deviate too far from the model as foreground, then updates the model toward the frame. Because cv2's BackgroundSubtractorMOG2/KNN are stateful objects that cannot travel through a graph (and would double-update under ComfyUI's output caching), the model IS the 'mean'/'variance' arrays - thread them node-to-node like 'CV Compose Pose' threads a trajectory, one node per frame. On the FIRST frame leave 'mean' and 'variance' unwired: the model is seeded from the frame and the foreground comes out empty (no history yet), so no success gate is needed. A pixel is foreground when its distance from the mean, in standard deviations averaged over the colour channels, exceeds 'threshold'. For a FIXED-camera clip you can skip the state chain entirely: precompute a background plate once with 'CV Temporal Reduce', wire it into 'mean', set learning_rate 0, and each frame is scored independently against that plate (which is what lets the detector run inside an Inspire foreach - the loop then carries only ONE accumulator, the output frames). Outputs data only - view the foreground with 'Preview CV Array' (image) or turn it into a MASK for 'CV Overlay Masks' / 'CV Array -> Mask'. Note: the model learns everywhere at 'learning_rate', so an object that stops moving is slowly absorbed into the background (ghosting) - lower the rate to remember longer. Works in LATENT space too: 'frame'/'mean'/'variance' accept a LATENT and echo that format, so the whole detector can run on VAE-encoded frames (the foreground then comes out at latent resolution, H/8 x W/8). BUT the variance/threshold defaults are uint8-intensity^2 scaled; latents are ~unit scale, so for a LATENT frame shrink 'init_variance' to ~1 and 'min_variance' to ~0.01 or the model is so tolerant that NOTHING ever flags.
- frame
- mean
- variance
- mean
- variance
- foreground
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| frame | COMFY_MATCHTYPE_V3 | Current frame: an ndarray (feed a ComfyUI IMAGE through 'Image -> CV Array', BGR uint8) or a LATENT (a single VAE-encoded frame). Compared against the running model; the model threads in whatever format arrives. | |
| learning_rate | FLOAT | 0.050–1 | How fast the model follows the scene, per frame (alpha): mean += alpha*(frame-mean). 0 freezes the model after the first frame; ~0.01-0.1 adapts to lighting while remembering a moving object for many frames; 1 makes every frame the new background. |
| threshold | FLOAT | 2.50–20 | Foreground cutoff in standard deviations: a pixel is foreground when its per-channel-averaged distance from the mean, divided by the model's standard deviation, exceeds this. ~2-3 is typical; raise to suppress noise, lower to catch faint motion. Scale-free (it is in std devs), so it needs no change in latent space. |
| init_variance | FLOAT | 100.000.001–100000 | Starting per-pixel variance (uint8 intensity^2 units; 100 = std 10) used to seed the model on the first frame and whenever 'variance' is unwired. Larger = more tolerant until the model settles. For a LATENT frame this is far too large (latents are ~unit scale): drop it to ~1 or the model starts hopelessly tolerant. |
| min_variance | FLOAT | 16.000.001–100000 | Floor on the variance (uint8 intensity^2 units; 16 = std 4) so a perfectly still pixel keeps a little noise budget and does not flag on 1-2 grey-level jitter (compressed / decoded video). For a LATENT frame lower it to ~0.01 - the uint8 floor of 16 (std 4) dwarfs latent deviations, so with the default NOTHING flags. |
| meanopt | COMFY_MATCHTYPE_V3 | Running per-pixel mean from the previous frame's node (same format as 'frame'). Leave UNWIRED on the first frame to seed the model from 'frame'. | |
| varianceopt | COMFY_MATCHTYPE_V3 | Running per-pixel variance from the previous frame's node. Unwired -> reset to 'init_variance'. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| mean | COMFY_MATCHTYPE_V3 | Updated per-pixel mean (float32, same shape and format as the frame) - wire into the next frame's node. |
| variance | COMFY_MATCHTYPE_V3 | Updated per-pixel variance (float32, same format as the frame) - wire into the next frame's node. |
| foreground | NPARRAY | uint8 0/255 foreground mask (moving / new pixels), one channel. For a LATENT frame it is at LATENT resolution (H/8, W/8) - upscale x8 (nearest) to overlay on pixels. Empty on the first frame. Convert to a MASK for overlay / morphology. |