Nodes/comfyui_kmeans_filter/Apply Kmeans Filter
ComfyUI Node

Apply Kmeans Filter

Flatten Any Image to a Handful of Colors — K-Means, in One Node

By githubYiheng·Created 2 years ago·Updated 2 years ago· 0
Apply Kmeans Filter
  • image
  • image
k18

If you've ever wanted a clean, posterized, flat-color version of an image - pop-art style, low-poly sticker look, or a palette you can count on one hand - this is the node. ImageKmeansFilter ("Apply Kmeans Filter" in the node menu) takes any IMAGE and rebuilds it using exactly k colors, chosen automatically from the image itself. No Lora, no checkpoint, no model files: it's pure classic computer vision, and it runs in a second or two on a CPU.

It's the kind of tiny utility you didn't know you were missing until you need it. The obvious companion recipe is pixel art: downscale hard with a good resize, run this node at k=8–16, then nearest-neighbor upscale back up. That's a one-graph retro pipeline that used to take three separate tools. It's also genuinely handy before exporting if you're printing, screen-printing, or throwing something on a palette-limited platform.

How it works

Under the hood it's textbook k-means clustering, run with OpenCV. The image is flattened into one giant list of pixels, and cv2.kmeans groups them into k clusters using k-means++ initialization. Each pixel is then replaced by the average color of its cluster, and the image is rebuilt. Done - the output is the original image's colors, collapsed into the k most representative ones.

Two details worth knowing because they explain what you'll see. The clustering runs in BGR (PIL gets converted there and back), so there's no channel-order surprise to debug on your end. And it processes every image in the batch independently, so a batch of frames from a video or a grid of images all get the same treatment without any cross-contamination. It's deterministic enough to feel stable, but k-means uses a random start, so don't expect bit-identical output run to run.

The inputs and outputs that matter

The whole thing is two inputs and one output:

  • image (IMAGE) - anything you can wire in from a Load Image, a VAE Decode, or anywhere else.
  • k (INT, default 18) - the target color count. This is the only knob, and it's the whole node. Lower k = flatter, chunkier, more abstract. k=4–8 reads as stylized or retro; k=18 (the default) is a light flatten that keeps most of the image legible; k=32+ barely looks touched. For a first pass, start at 8 and see if you hate it.

The single output is image (IMAGE) - the posterized result, same resolution as the input. Wire it straight into a Save Image, or feed it forward into another node for further treatment. That's it. There are no secret settings hiding in an optional section; the author kept this gloriously simple.

Installing it

This pack is a single node with no README and no requirements.txt, so install is about as painless as custom nodes get:

cd ComfyUI/custom_nodes
git clone https://github.com/githubYiheng/comfyui_kmeans_filter

then restart ComfyUI. If you run ComfyUI Manager, search comfyui_kmeans_filter and hit Install instead. There are no model downloads, no config files, no weights - the only real dependency to care about is OpenCV, which the node imports as cv2 at load time.

Common issues

The one failure mode that's actually likely: ComfyUI refuses to start with an ImportError: No module named 'cv2'. ComfyUI ships with torch, numpy, and Pillow, but OpenCV isn't guaranteed in every install - clean and portable builds often skip it. Since there's no requirements.txt in the pack, nothing installs it for you. The fix, into the same Python environment your ComfyUI uses:

pip install opencv-python

Most existing ComfyUI installs already have it (lots of popular nodes pull it in), so you may never hit this - but if the node shows up red on startup with a cv2 error, that's the cause, and it's a 30-second fix. Beyond that, the only thing to trip over is misjudging k; too low and the image turns into blobs, so lean on the preview output while you dial it in.

CategoryTools

Inputs (2)

NameTypeDefaultDescription
imageIMAGE
kINT18

Outputs (1)

NameTypeDescription
imageIMAGE