Nodes/ComfyUI CV/cv2.stylization
ComfyUI Node

cv2.stylization

The painterly filter that runs in milliseconds and needs no model

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
cv2.stylization
  • src
  • result
◄sigma_s60.0000►
◄sigma_r0.4500►

Before neural style transfer there was this: an edge-preserving recursive filter that flattens flat regions into brush-like plates while holding the boundaries between them. cv2.stylization is the oldest trick in the non-photorealistic-rendering drawer and it still holds up - as a quick painterly pass, as a base for a subsequent compositing step, or as the "make it look hand-made" button you apply to a render before you hand it to someone.

It costs milliseconds and no VRAM, which is the case for putting it in a graph at all. The KB's post-processing layer exists to say exactly this: a deterministic pixel operation beats burning a diffusion pass on work a filter does perfectly.

This node is one of ~470 auto-generated raw cv2.* wrappers in ComfyUI CV (bmad4ever/comfyui_cv). Raw, uncurated, LLM-generated - the pack's own warning label.

Inputs and outputs

src is type-preserving and image-only: link an IMAGE, get an IMAGE back. MASK and LATENT links aren't accepted here, because the underlying filter wants an 8-bit 3-channel picture. That no-conversion-needed property is the nice part: you can drop this node between any two image sockets in an existing graph and it just works. Batched IMAGEs are looped frame by frame and re-stacked, so a video batch is one call.

Two knobs, both straight from OpenCV and both boringly well-behaved:

  • sigma_s, default 60, range roughly 0–200 - the spatial extent. Bigger means larger flat areas, more "brush". Push it up and the image starts to look airbrushed rather than painted.
  • sigma_r, default 0.45, range 0–1 - how different two colours have to be before the filter refuses to smooth across them. Lower keeps more edges crisp; higher blends right through them and you lose the drawing.

The defaults are a sane starting point, which is unusual for this pack's raw wrappers. Nudge sigma_r first; it has the bigger visual effect per unit of change.

Where it sits in a workflow

The pack's NPR filters playground (16_npr_filters_playground.json) is the reference: it lines up stylization against pencilSketch, detailEnhance, edgePreservingFilter, xphoto.oilPainting, and the ximgproc smoothers on one photo. If you're choosing between them, that graph saves you an hour of guessing.

On its own, the usual pattern is stylization → blend back over the original at partial opacity, or stylization as the low-frequency layer in a frequency separation, with the original's high frequencies added back so you keep texture. One pass alone reads as "filter". One pass plus a partial-strength blend reads as intentional.

And it's a good complement to a generative pass rather than a replacement for one: run it after an img2img pass to unify the surface, or as the base plate for a ControlNet-free painterly look. It won't invent detail. It does not hallucinate. Sometimes that's what you want.

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 ComfyUI built on the V3 node API are hard requirements. Keep the contrib OpenCV wheel: all four distributions share one site-packages/cv2, so installing plain opencv-python over the contrib build silently empties the contrib submodules - tools/repair_opencv_contrib.py --check diagnoses it, --apply repairs it. Behaviour is curated against 5.0.0.93.

Watch out for

Feeding it a MASK or a LATENT - the socket won't take either, because this filter has colour semantics. Expecting it to be fast on huge inputs: it's recursive, and on 8K plates it's no longer "milliseconds" in the way it is on 1024². And don't judge it from a single full-strength pass; the interesting settings are the ones you dial back.

Categoryimage/CV/low-level/cv2 S

Inputs (3)

NameTypeDefaultDescription
srcCOMFY_MATCHTYPE_V3Input 8-bit 3-channel image. The image output(s) echo this input's format. 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.
sigma_soptFLOAT60.0000-1e+38–1e+38%Range between 0 to 200. Preset to the OpenCV default (60.0).
sigma_roptFLOAT0.4500-1e+38–1e+38%Range between 0 to 1. Preset to the OpenCV default (0.45).

Outputs (1)

NameTypeDescription
resultCOMFY_MATCHTYPE_V3Echoes the 'src' input's format: an IMAGE link comes back as IMAGE, MASK as MASK, NPARRAY stays NPARRAY.