ComfyUI Node

Desaturation

Three-channel mean, with a mix knob

By CoiiChan·Created about a year ago·Updated about a year ago· 2
Desaturation
  • imga
  • IMAGE
formuladesaturate = np.sum(imga , axis=-1)/3 makergb = np.stack([desaturate, desaturate, desaturate], axis=-1) result = makergb * pfloat1 + (1-pfloat1)*imga
pfloat11.00

Desaturation turns a color image grayscale using the simplest method there is - average the three color channels at every pixel. No Rec.601 luma weights, no perceptual cleverness, just (R + G + B) / 3. The README is upfront about it: "desaturation of image using three channel mean method." It's the honest, predictable grayscale - and because it's an average, it behaves slightly differently than the "official" luma formula (which weights green more heavily because human eyes do). Expect a marginally brighter, flatter result than a color-managed desaturate. For masks and math, that's usually a feature.

The formula is where the mix knob lives:

desaturate = np.sum(imga, axis=-1) / 3
makergb = np.stack([desaturate, desaturate, desaturate], axis=-1)
result = makergb * pfloat1 + (1 - pfloat1) * imga

pfloat1 (0–1, default 1.0) is the desaturation amount. At 1.0 you get full grayscale; at 0.0 the output is the original color image unchanged; in between it's a smooth blend. That single parameter turns the node from "grayscale-only" into "saturation control," which covers most of what you'd want a saturation-adjust node to do.

Why you'd use it

  • Masks from color. The pack's whole ecosystem runs on grayscale decision images - ifFunction compares, Distance measures, Outline traces. Desaturation is how you convert a color image into a decision image you can feed those nodes.
  • A neutral base for tinting. Grayscale it, then multiply by a solid color (Contant3Vector) to tint. That's a classic and it's three nodes.
  • Fixing over-saturated generations at a partial setting, without reaching for a full color-grading node.

Inputs and outputs

  • formula - the desaturation script, pre-filled and editable.
  • imga - the image to desaturate.
  • pfloat1 - desaturation strength, 0–1, default 1.

One IMAGE output.

Install

ComfyUI Manager → search "FuncAsTexture", or:

cd ComfyUI/custom_nodes
git clone https://github.com/CoiiChan/ComfyUI-FuncAsTexture-CoiiNode
# restart ComfyUI

No models, no requirements.txt. Category: FunctionAsTexture.

Notes

  • Mean method, not luma. If you're going to compare grayscale results to Photoshop's, this won't match exactly - Photoshop uses weighted luma. The mean method is flatter and slightly brighter in greens. For masks, exactness rarely matters; for final B&W output, you might prefer a luma formula (the pack's CustomScript-NumPy makes that a one-line swap: 0.299*R + 0.587*G + 0.114*B).
  • The output is grayscale data in an RGB container - all three channels carry the same value, which is exactly what downstream math nodes want.
  • It's the reference node for the pack's other color ops. Chroma_Key_Alpha internally compares each pixel's color to a key; Desaturation is the same "read the channels, combine them" school of thought, minus the keying.

It's a two-line node with a slider that makes it flexible, and it slots perfectly into the pack's grayscale-first philosophy. When your workflow needs "a decision image," this is where color goes to become one.

CategoryFunctionAsTexture

Inputs (3)

NameTypeDefaultDescription
formulaSTRINGdesaturate = np.sum(imga , axis=-1)/3 makergb = np.stack([desaturate, desaturate, desaturate], axis=-1) result = makergb * pfloat1 + (1-pfloat1)*imga
imgaoptIMAGEOptional ,Reference size ,Default =(1,512,512,3)
pfloat1optFLOAT1.000–1Optional,Floating-point parameter passed to the script.

Outputs (1)

NameTypeDescription
IMAGEIMAGE