OpenCV kmeans_0
Clustering and color quantization, the raw way
- data
- bestLabels
- centers
- float
- nparray_1
- nparray_2
OpenCV kmeans_0 wraps cv2.kmeans, the classic unsupervised clustering algorithm - and it's one of the genuinely interesting nodes in this pack, because it's the engine behind a trick a lot of people want: color quantization. K-means finds K representative colors for your data, and for an image that means "these K colors best summarize the palette." The KB's post-processing essay calls this out explicitly - palette reduction for pixel art and limited-palette looks is k-means applied to an image's pixels.
So the alluring use case is real. The catch is that this pack exposes cv2.kmeans raw: data has to be a 2D float array of shape (samples, dimensions), and your (H, W, 3) image is neither flat nor float. To quantize an image you'd reshape pixels to an N×3 float32 array first - which needs a scripting/reshape node, because this pack has no reshape node. If you can provide the right-shaped array, you get a proper clustering node in your graph. If not, you'll spend an afternoon fighting shapes for a result simpler palette tools give you directly.
How it works
cv2.kmeans(data, K, bestLabels, criteria, attempts, flags, centers) runs Lloyd's algorithm: pick K initial centroids, assign every sample to the nearest one, move each centroid to the mean of its cluster, repeat until criteria is met. It returns three things: the compactness (sum of squared distances of samples to their centroids - lower is tighter), the per-sample cluster index array, and the final centroids. Because the initial centroids are random, attempts runs the whole thing multiple times and keeps the best result.
Inputs and outputs
data- NPARRAY,(N, dims)float32 samples. For color quantization that's pixels as(N, 3).K- INT, number of clusters (the palette size).bestLabels- NPARRAY, required input even though it's an output - a quirk of this auto-generator: the stub didn't type it| None, so you must connect something (any array of the right shape) and it gets overwritten.criteria- STRING, a Python literal parsed withast.literal_eval. It's aTermCriteriatuple(type, maxCount, epsilon), e.g.(3, 10, 1.0)- type3= EPS+MAX_ITER, stop after 10 iterations or when movement < 1.0.attempts- INT, restarts with different random seeds.flags- INT:0KMEANS_RANDOM_CENTERS,1KMEANS_USE_INITIAL_LABELS,2KMEANS_PP_CENTERS(k-means++ initialization - better quality, costs a bit more).centers- optional NPARRAY out-parameter; returned anyway.- Outputs:
float(compactness),nparray_1(labels, one per sample),nparray_2(centroids,K × dims).
Installing
From opencv-comfyui:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
cd opencv-comfyui
pip install -r requirements.txt
or ComfyUI Manager → "opencv-comfyui". No models; deps are opencv-contrib-python, numpy, torch.
Gotchas
Three things will bite you, in order. (1) The criteria string must be valid Python literal syntax or you get the pack's signature invalid syntax (<unknown>, line 0) - the README's convention is parentheses, so write it like (3, 10, 1.0), a tuple of (type, maxCount, epsilon). (2) data must be float32 and 2D; feeding an image-shaped array throws. (3) bestLabels is required even though you never set it meaningfully - connect a placeholder nparray and read the real result off nparray_1. Set flags=2 (k-means++) for the best palette quality, and kmeans_0 vs kmeans_1 are identical overload duplicates as always.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| data | NPARRAY | — | |
| K | INT | — | |
| bestLabels | NPARRAY | — | |
| criteria | STRING | — | |
| attempts | INT | — | |
| flags | INT | — | |
| centersopt | NPARRAY | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| float | FLOAT | — |
| nparray_1 | NPARRAY | — |
| nparray_2 | NPARRAY | — |