Nodes/ComfyUI CV/cv2.sqrBoxFilter
ComfyUI Node

cv2.sqrBoxFilter

Local energy in a box, and the depth setting that ruins it

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
cv2.sqrBoxFilter
  • src
  • ksize
  • anchor
  • nparray
◄ddepthsame as input►
◄normalizetrue►
◄borderTypeBORDER_DEFAULT►

There is no popular node that computes local image energy, which is why cv2.sqrBoxFilter exists in this pack's low-level set and nowhere else in your workflow. It squares every pixel and then sums those squares inside a box - read it as "how much signal is in this neighbourhood". Blur kernels average. This one accumulates the power.

That distinction is where the useful things come from. Take the square root of the output and you have a local RMS map. Subtract the square of a plain box-filter mean and you have a local variance map. Divide one image's square-box by another's and you're inside a normalized cross-correlation. If you're building a texture detector, a sharpness heatmap or a "which regions are actually flat" mask, this is one of the primitives you need, alongside CV Local Linear Fit for the pixelwise regression version of the same idea.

This node is one of ~470 auto-generated raw cv2.* wrappers in ComfyUI CV (bmad4ever/comfyui_cv) - a straight mapping of the cv2 call, no interpretation added. The pack's own disclaimers apply: LLM-written, uncurated, verify before you trust it in anything that ships.

The inputs that matter

src accepts a ComfyUI IMAGE or MASK directly, or an NPARRAY. An IMAGE resolves to 8-bit BGR. A MASK works too, and a batched IMAGE is processed frame by frame and re-stacked.

ddepth is the whole ballgame, and its default is a trap. It defaults to same as input, which for an 8-bit image means OpenCV stores squared sums in a CV_8U array: 255² is 65,025, and 65,025 clipped into a byte is 255. Set it to CV_32F and do your arithmetic in floating point. Integer depths are only sane when the box is tiny.

ksize is a single (w, h) value - wire it from a CV Tuple node or type it in place; unlike a stack blur it doesn't need odd numbers, and the two axes can differ. The default widget is (0, 0), which is not a legal kernel, so set it. normalize (on by default) divides by the box area, turning the sum into a mean of squares - usually what you want; turn it off when you want the raw total. anchor at (-1, -1) means the kernel centre, and borderType controls how OpenCV invents pixels outside the frame.

The single output nparray is always NPARRAY, even when you fed it an IMAGE. Convert back with CV Array → Image - with no echo of the input's nature, this node never hands you something a preview will accept.

Practical shape

Feed a grayscale IMAGE, get a CV_32F energy map, then go wherever the numbers need to go: CV Cast Array and CV Array → Image to look at it (use the RAW channel-order option, since the values far exceed 0..1), CV Array Statistic to read it numerically, or cv2.sqrt to turn mean-square into RMS. Because output is float ndarray, everything downstream of it is arithmetic rather than pixels - that's a feature; it's also why this node lives in the data half of the pack.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
cd comfyui_cv && pip install "opencv-contrib-python-headless~=5.0.0.93"

Or Manager → search ComfyUI CV → install → restart. Python ≥ 3.12 and a current ComfyUI (V3 node API) are hard requirements. Keep the OpenCV build contrib: all distributions share one site-packages/cv2, so installing plain opencv-python over the contrib wheel silently empties the contrib submodules; tools/repair_opencv_contrib.py --check/--apply is the fix. Behaviour is curated against 5.0.0.93.

Watch out for

Leaving ddepth on same as input with a uint8 image - you get a white rectangle and conclude the node is broken. Leaving ksize at (0, 0) and getting an OpenCV kernel-size error. And expecting a preview: no shipped workflow uses this node, so there's no example graph to copy, and its output is data. This one is a building block, and it's fine that it is.

Categoryimage/CV/low-level/cv2 S

Inputs (6)

NameTypeDefaultDescription
srcNPARRAY,IMAGE,MASKinput image 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.
ddepthCOMBOsame as inputthe output image depth (-1 to use src.depth())
ksizeCV_TUPLE0,0kernel size One value with 2 components (w, h) - it travels as a whole, so it cannot arrive half-connected. Wire it from 'CV Tuple' or type the components in place.
anchoroptCV_TUPLE-1,-1kernel anchor point. The default value of Point(-1, -1) denotes that the anchor is at the kernel center. One value with 2 components (x, y) - it travels as a whole, so it cannot arrive half-connected. Wire it from 'CV Tuple' or type the components in place.
normalizeoptBOOLEANtrueflag, specifying whether the kernel is to be normalized by it's area or not. Preset to the OpenCV default (True).
borderTypeoptCOMBOBORDER_DEFAULTborder mode used to extrapolate pixels outside of the image, see #BorderTypes. #BORDER_WRAP is not supported.

Outputs (1)

NameTypeDescription
nparrayNPARRAY—