cv2.parallel.setParallelForBackend
A threading knob, not an image node
- bool
This is the odd one out in the pack. It takes no image, returns no array - it just asks OpenCV to swap the parallel-for implementation it uses internally and tells you whether it worked. One required string input, one optional flag, one boolean output.
If you're here because the name matched a search: no, it doesn't make your sampler faster. It changes how cv2 functions spread work across cores. And given how ComfyUI already saturates a CPU with PyTorch and its own thread pool, the honest reason to touch it is the opposite of what you'd guess - to see whether turning OpenCV's parallelism down improves throughput by cutting oversubscription.
What it actually does
OpenCV builds with one parallel framework baked in (TBB, OpenMP, pthreads, maybe GCD on macOS), and cv2.parallel in OpenCV 5 exposes a runtime call to switch which implementation parallel_for_ dispatches to. That's the whole mechanism. Consequences:
- The name has to match a backend this build actually carries.
"TBB"on a build without TBB doesn't magically enable it. - It's process-wide. You're setting a global; every subsequent cv2 call in that process inherits it.
- It returns a boolean, which is the wrapper's entire verdict: set or not set.
To find out what your build has before typing anything, use the pack's CV Build Information node (it's a path-redacted, safe version of cv2.getBuildInformation()) and look at the "Parallel framework" line. Its has_eigen output is the same idea for a different capability, and the pack deliberately exposes the banner that way because the raw getBuildInformation wrapper was blacklisted - it quotes the build machine's directory layout.
backendName is a plain string, and it arrives empty. An empty name is not "the default", it's an empty name. propagateNumThreads is even odder: it's a string field that accepts a Python literal (True, 3, (3, 3)), and leaving it blank means "use the OpenCV default". That's the pack's convention for optional parameters on raw wrappers - blank = library default - it just looks strange on a boolean-shaped argument.
The trap: nothing runs a node nothing needs
ComfyUI executes what the outputs require, driven by links. A node whose boolean goes nowhere may simply never execute. The pack knows this well enough that it gave its RNG-seed node a passthrough value on the wire precisely so it can't run too late - same hazard, opposite arrangement. So wire the bool output into something downstream (a core Preview Any is enough) if you want it to actually fire before the work you're trying to affect.
And here's the part that makes this knob less useful than it looks: the slow cv2 calls in this pack don't run in ComfyUI's process at all. calcOpticalFlowSF, calcOpticalFlowFarneback, fastNlMeansDenoising, pyrMeanShiftFiltering, seamlessClone, grabCut and the stitcher are all executed in a spawned worker subprocess - the pack pickles the arguments out, runs the call there, and polls for cancel. A backend you set in the ComfyUI process does not travel into a fresh interpreter that spawns with a pickled payload. So: set it, then measure only the in-process wrappers, and don't expect it to reach the slow ones.
Installing
ComfyUI Manager → search ComfyUI CV → Install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Python ≥ 3.12 and a recent ComfyUI (V3 node API). OpenCV 5.0's parallel namespace is what this wraps - the pack is curated against 5.0.0.93, and on an older OpenCV the entry won't exist and the node won't be generated at all. parallel is a contrib-namespace module, so the contrib wheel is mandatory here; note that OpenCV pip wheels share one site-packages/cv2, so installing plain opencv-python over a contrib build silently removes nodes like this one:
python ComfyUI/custom_nodes/comfyui_cv/tools/repair_opencv_contrib.py --check
Should you care?
Honestly, rarely. Copy the node in, set your backend, see whether the boolean comes back true, and if throughput doesn't move, take it back out - it's a session-level global with no image pipeline discipline around it, and it's not something anyone has tested against this pack's workflows. There is no community consensus to lean on here either: this pack is a one-person 2026 fork with essentially no discussion threads I could find, so any number you get out of it is yours.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| backendName | STRING | - - - | |
| propagateNumThreadsopt | STRING | - - - Optional - leave blank to use the OpenCV default. Accepts a Python literal, e.g. 3, 1.5, true, or (3, 3). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| bool | BOOLEAN | — |