Nodes/opencv-comfyui/OpenCV pyrMeanShiftFiltering_0
ComfyUI Node

OpenCV pyrMeanShiftFiltering_0

Flatten an image into poster-like color blobs with OpenCV mean shift

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV pyrMeanShiftFiltering_0
  • src
  • dst
  • nparray
sp
sr
maxLevel
termcrit

This is the node you reach for when you want a photo to stop looking like a photo. pyrMeanShiftFiltering is OpenCV's edge-preserving "flattening" filter: it collapses nearby pixels into big flat regions of nearly-identical color while keeping the hard edges between them. Run it on a portrait and you get a stylized, almost watercolor or posterized look that survives a normal img2img pass far better than raw noise. It's also the classic pre-step for segmentation - find the big blobs first, then let everything else work on a clean, low-entropy image.

The name is a mouthful, so unpack it: mean shift looks at each pixel and replaces it with the average of its neighbors, but only neighbors that are both spatially close and similar in color. Repeat that a few times and smooth gradients collapse into plateaus while actual boundaries (where color changes hard) stay put. The result is a cartoon-ish flat image with intact edges. That's the whole trick.

What you actually set

Like every node in this pack, this one speaks nparray, not ComfyUI IMAGE. So the wiring is Image2Nparray in front, Nparrays2Image after - the pack's two conversion nodes do the RGB↔BGR and tensor↔numpy dance for you. Inside, the inputs that matter:

  • src - your NPARRAY image, BGR and 0–255 uint8 after Image2Nparray.
  • sp (spatial radius) and sr (color radius) - the two tuning knobs. sp is how far out (in pixels) the filter looks; sr is how big a color difference still counts as "the same". Small sp/sr ≈ subtle smoothing; crank both up (think 20–40) and you get the strong flat-poster look.
  • maxLevel - how many pyramid levels to use. 0 keeps it simple; 1 gives a noticeably cleaner result for the same radii.
  • termcrit - a Python-literal string for OpenCV's TermCriteria, written (type, maxCount, epsilon). (3, 10, 1) is the sane default: type 3 means "stop after 10 iterations OR when the change is under 1", whichever comes first.

dst is an optional out-parameter - leave it unplugged, per the README's "avoid the optional out-parameters" advice.

Wiring and gotchas

termcrit is parsed with ast.literal_eval, so if the syntax is wrong you'll get an invalid syntax (<unknown>, line 0) error and the node will sit there smug. Use a tuple: (3, 10, 1).

You'll also notice pyrMeanShiftFiltering_1 sitting right next to this one in the menu. They're the same function, same inputs, same output - the generator couldn't tell the two OpenCV overloads apart. Pick either; nothing changes.

Install

No models, no weights, no downloads. The pack is just auto-generated wrappers around OpenCV, so the only real dependency is OpenCV itself (plus numpy/torch, which ComfyUI already has):

cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
pip install opencv-contrib-python

Or just search "OpenCV" in ComfyUI Manager. Restart, and the nodes appear under image/OpenCV. If install throws Cannot import name 'guidedFilter' from 'cv2.ximgproc', you have a conflicting OpenCV install - known issue, fix by aligning your opencv-contrib-python versions (see the LayerStyle issue the README links).

One more thing: the pack only handles batch_size==1 images, so if your workflow feeds a batch, drop an ImageFromBatch (length=1) in front. Then flatten away.

Categoryimage/OpenCV

Inputs (6)

NameTypeDefaultDescription
srcNPARRAY
spFLOAT
srFLOAT
maxLevelINT
termcritSTRING
dstoptNPARRAY

Outputs (1)

NameTypeDescription
nparrayNPARRAY