Nodes/ComfyUI CV/cv2.filter2Dp
ComfyUI Node

cv2.filter2Dp

Same maths, different door — and a raw output instead of an image

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
cv2.filter2Dp
  • src
  • kernel
  • nparray
◄anchorX-1►
◄anchorY-1►
◄borderTypeBORDER_DEFAULT►
◄ddepthsame as input►
◄scale1.0000►
◄shift0.0000►

Two convolution nodes in this pack, one letter apart. cv2.filter2Dp is the newer entry point and it is not a drop-in replacement - the parameter list is different, and so is the output socket type, which is the part that will actually cost you five minutes. If you want the practical story about kernels and ddepth, read the cv2.filter2D article; this one is about choosing between the two doors.

What's different in the signature

Same core operation: correlate the image with a single-channel floating-point kernel, one kernel applied across all channels. The reordering changes how you specify the filter:

  • anchorX and anchorY are separate INT widgets (-1 = centre) instead of a single CV_TUPLE. For an asymmetric kernel this is arguably nicer - two numbers where you can see both - and it's the main reason to prefer this variant.
  • scale (default 1.0) multiplies the convolution result, and shift (default 0.0) is added to it afterwards. The pack's own tooltip is explicit that this shift is "cv2's 'delta'" - same meaning, different name than in the sibling node. So scale 1/9 gets you a normalised box filter from an all-ones kernel, which is a genuinely clean way to write "average" without typing fractions.
  • borderType comes before ddepth, and ddepth still defaults to "same as input" - so the negative-coefficient clipping problem from the sibling node applies here too, unchanged.
  • src accepts an IMAGE, MASK or NPARRAY, and kernel is NPARRAY-only.

The output difference that matters

The sibling node echoes its input's format: an IMAGE link comes back as an IMAGE, a MASK as a MASK. This one doesn't. Its output is a plain NPARRAY named nparray - that's what the schema says, and it's consistent with this wrapper not being on the pack's list of image-props-preserving functions while filter2D is. The consequence is concrete: after filtering a picture, you need CV Array → Image in the graph before anything visual accepts it, and any MASK-flavoured chain gets an extra bridge on the way back.

Is that a bug? No - it's the honest state of a pack whose ~470 wrappers are auto-generated from OpenCV's type stubs, with the format-preserving behaviour curated on top for the entry points the author's workflows use. If you're doing array maths and the output goes on to CV Inspect CV Data, CV Array Statistic or another cv2 wrapper that takes NPARRAY, the plain output is exactly right and the echo would have been the inconvenience.

Which one should you wire?

Use cv2.filter2D unless you specifically want the separate anchor widgets or the scale/shift form in one node. Use this one when your graph is array-flavoured anyway and the extra image bridge is not a cost, or when you want a normalised box-style kernel written as integers plus a scale.

One caveat worth carrying: this pack's registry is generated from the type stubs of a newer OpenCV than the version its behaviour is curated against (contrib 5.0.0.93), and the source comments file filter2Dp among the entries cv2 5.x added. The README is upfront that a generated entry can exist whose implementation your installed build lacks - so if this node is in the menu and raises the moment it runs, check CV Build Information and fall back to the sibling node rather than rewriting your maths.

Installing it

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

ComfyUI Manager: search comfyui_cv, install, restart. Python ≥ 3.12 and a recent ComfyUI on the V3 node API - the pack won't load on an older one. Node path: image/CV/low-level/cv2 F.

Traps

Expecting the format echo (you'll get a link error on the next node and blame the wrong thing). Forgetting that shift here is delta, because "shift" reads like a translation. Negative-lobe clipping on an 8-bit depth, exactly as in the sibling node. And a non-float kernel - OpenCV wants a floating-point matrix here too, so build it with Parse Matrix or cast it before you wire it in.

Categoryimage/CV/low-level/cv2 F

Inputs (8)

NameTypeDefaultDescription
srcNPARRAY,IMAGE,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.
kernelNPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
anchorXoptINT-1-2147483648–2147483647 - - - Preset to the OpenCV default (-1).
anchorYoptINT-1-2147483648–2147483647 - - - Preset to the OpenCV default (-1).
borderTypeoptCOMBOBORDER_DEFAULT - - -
ddepthoptCOMBOsame as input - - -
scaleoptFLOAT1.0000-1e+38–1e+38 - - - Preset to the OpenCV default (1.0).
shiftoptFLOAT0.0000-1e+38–1e+38 - - - Preset to the OpenCV default (0.0).

Outputs (1)

NameTypeDescription
nparrayNPARRAY—