MaskFromRGB_KMeans
Auto-Segment an Image Into Color Regions, No Clicking
- image
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- combined
Want to say "everything that's roughly this color range" without hand-painting a mask? MaskFromRGB_KMeans clusters the colors in your image and hands you one mask per cluster - up to eight of them, plus a combined one. It's the fast, dumb, automatic way to split a reference image into regions: sky vs. building, skin vs. background, foreground vs. everything.
The mechanism is a proper K-means fit, and it's done in LAB color space, not RGB. That's the detail that makes it work: LAB was designed so that Euclidean distance roughly matches how humans perceive color difference, so the clusters land where your eye would put them. It converts your image to LAB, runs K-means (with a deterministic, content-derived seed, and it subsamples if the image is big enough to be slow), sorts the cluster centers by luminance, and hard-assigns every pixel to its nearest cluster. Each output mask gets a Gaussian blur whose width is controlled by softness, then normalized so the per-cluster masks sum to one.
The inputs that matter
image- what you're segmenting.n_color_clusters- 2 to 10, default 6. The real knob. Too low and distinct regions get merged; too high and you start cutting single objects into shards. Start at 6 and move one way or the other.softness- the feather on the mask edges. Higher = softer transitions, which matters if the masks feed something that can't handle hard edges.equalize_areas- a bias that pushes clusters toward equal pixel counts. Set it above 0 when one cluster (say, a huge uniform sky) is swallowing everything and you'd rather the other regions get fairer masks.
What comes out
Nine MASK outputs. Outputs 1 through 8 are the individual clusters, sorted by luminance (so 1 is your darkest cluster, 8 the brightest) - if you asked for fewer than 8 clusters, the extras come out as zero masks, which is normal, not a bug. The combined output is a single grayscale mask where each cluster got a different intensity value - it's a compact "here's the whole segmentation in one tensor" view, handy for previewing or for feeding a node that wants one mask.
This node shows up in Eden's own texture-flow demo, where the region masks feed separate IP-Adapter applications so different parts of an image get different styles. Same idea works for anything region-aware.
Installing it
Part of the Eden.art nodesuite. ComfyUI Manager β search "Eden" β install, or clone:
cd ComfyUI/custom_nodes/
git clone https://github.com/edenartlab/eden_comfy_pipelines.git
cd eden_comfy_pipelines
pip install -r requirements.txt
Restart, under Eden π±. The pack's shared requirements include scikit-learn, which is where the K-means machinery comes from.
Common issues
Two things bite people. First, remember the masks are soft - they're blurred and normalized, so they're not clean 0/1 selections, and downstream nodes expecting binary masks may need a threshold. Second, K-means is unsupervised: cluster number 3 today is not guaranteed to be the same visual region tomorrow, so don't hardcode expectations about which output is "the sky." And for a batch input, each frame gets clustered independently, so the same semantic region can shift cluster indices between frames - a real consideration for video work.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| n_color_clusters | INT | 62β10 | β |
| softness | FLOAT | 1.000.001β10 | β |
| equalize_areas | FLOAT | 0.000β1 | β |
Outputs (9)
| Name | Type | Description |
|---|---|---|
| 1 | MASK | β |
| 2 | MASK | β |
| 3 | MASK | β |
| 4 | MASK | β |
| 5 | MASK | β |
| 6 | MASK | β |
| 7 | MASK | β |
| 8 | MASK | β |
| combined | MASK | β |