Nodes/ComfyUI CV/cv2.decolor
ComfyUI Node

cv2.decolor

Grayscale that keeps what your eye actually sees

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
cv2.decolor
  • src
  • grayscale
  • color_boost

cv2.decolor is the contrast-preserving grayscale conversion from OpenCV's photo module, and it exists because plain luminance math is bad at one specific thing: two colours with nearly the same brightness. A red apple on green leaves collapses into mush under COLOR_BGR2GRAY - same luminance, no edge - but decolor keeps the boundary visible, because it solves for a grayscale image that best preserves the original's contrast rather than just averaging channels.

Inputs and two outputs

src takes a ComfyUI IMAGE (or an NPARRAY); it must be 8-bit, three-channel. Four channels or a single channel and you'll get an error - the algorithm needs colour to decide how to separate it.

There are two outputs, and this is the nice part:

  • grayscale - the decoloured result.
  • color_boost - a colour image with the separation pushed harder, which is the paper's "boosted" version. It's a punchy, slightly surreal saturation boost, not a colour correction.

Both echo the input format: wire an IMAGE in and you get IMAGEs back, so unlike most of the raw wrappers in this pack you can preview the result immediately without a CV Array → Image round trip. The pack classifies decolor as a type-preserving function, which is why the socket behaves this way.

Where it earns a slot

Grayscale conversion for conditioning and masks, mostly. If you're building a ControlNet-style line or depth conditioning pass by hand, or you want a clean luminance plate to threshold into a mask, decolor is the version that doesn't lose the edges between differently-coloured but equally-bright regions. That's the exact failure mode people blame on "the mask just doesn't separate the subject" - a red object on a green field going flat.

It also gives you a black-and-white conversion that reads better than the channel average for stylisation passes. And color_boost is a cheap "make it pop" output for a preview or a thumbnail, with the caveat that it's aggressive.

The honest take: this is not free. It's a small optimisation problem, so it's slower than cv2.cvtColor's one-line matrix multiply, and on images where the colours are already well separated in luminance it buys you nothing you'd notice. Reach for it when a grayscale conversion visibly loses something - not as a default replacement for BGR2GRAY. The wider point from our post-processing notes applies: reach for the cheap deterministic primitive first, and upgrade only when you can see the failure it fixes.

Install

Manager → Install Custom Nodes → search ComfyUI CV, or from the CLI:

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

Restart ComfyUI afterwards. Python ≥ 3.12 and a recent V3-API ComfyUI; the contrib headless wheel is the only real dependency and no models are needed. decolor is a core OpenCV function, but this pack as a whole assumes the contrib build - all four OpenCV wheels share one site-packages/cv2, so a stray pip install opencv-python empties the contrib halves and you'll find contrib nodes missing. python tools/repair_opencv_contrib.py --check (then --apply) repairs it. The pack is GPL-3.0, a fork of geroldmeisinger/opencv-comfyui, largely AI-generated, and the author's own disclaimer says don't put it in production without reviewing it.

Common issues

  • A channel/precision assertion on execution. You fed a mask or a four-channel image. Convert or drop the alpha first; the input must be 8-bit 3-channel.
  • The result looks uneven, with odd blotches in flat areas. That's the algorithm doing contrast-preserving work on a region where the "best" grayscale is genuinely ambiguous. On a busy photo it can look worse than a straightforward luminance conversion - compare both before committing.
  • You expected it to be a colour match. It isn't. cv2.decolor takes one image and gives you a gray plate plus a boosted colour version; matching one image's colour to another is a different job entirely.
Categoryimage/CV/low-level/cv2 D

Inputs (1)

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.

Outputs (2)

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