cv2.ximgproc.contourSampling
Turn an edge map into a fixed number of points
- src
- nparray
Here's a problem that comes up the moment you try to compare shapes: contours have no fixed length. One outline is 412 points, the next is 87, and every shape descriptor, classifier and distance function downstream wants a vector of fixed size. cv2.ximgproc.contourSampling walks the contours in a binary map and resamples them down to a requested number of points, roughly evenly distributed along the curve. Variable-length geometry in, fixed-length point set out.
The classic pipeline it slots into is shape classification: Canny edge map → sample to N points → compare against templates (cv2.matchShapes, or a Fourier descriptor) → decide. The pack ships all the pieces: cv2.Canny, this node, cv2.matchShapes, and CV Quality-style scoring to check whether a match is actually close.
Inputs and output
src- the contour/edge image. AnIMAGE,MASKorNPARRAY. Worth being deliberate here: this wants a single-channel binary-ish map, so the safest wire is aMASK(which arrives single-channel) or an array fromImage → CV Arrayset to gray - anIMAGEreaching cv2 as 3-channel BGR isn't what the function expects, and this wrapper doesn't auto-grayscale for you.nbElt- how many points you want. This is your fixed vector length, so pick it to match whatever consumes it: 100 is a reasonable default for a shape signature, more if the contours are gnarly.
One NPARRAY comes out - the sampled points, which is the pack's general-purpose data socket. From there, CV Points To Contour converts it back into a contour if a cv2 function expects one, CV Points To Polar switches to (r, θ) about an origin, or CV Scale Points re-normalises them for scale-invariant comparison. Since the whole point is comparing shapes, the normalisation step is often the one that actually makes the comparison work.
Why a fixed point count fixes things
A shape descriptor that takes N points lets you do arithmetic: average two shapes, interpolate between them, feed them to a classifier, compute a distance. The pack leans into that with its own example exercises - the HOG shape classifier examples in the repo's workflows/ folder are literally "sample contours, extract features, predict a class" - and CV Deep Features / CV Predict Classifier are the end of that road if you want to train something.
There's a subtlety worth knowing before you trust the sampling: resampling a curve to equal point spacing is not the same as equal arc length spacing, and cv2's sampling is approximate. For shape matching that's usually fine - you're comparing like with like, since both shapes went through the same sampler. For measurement (perimeter, curvature) it isn't; use cv2.arcLength and analytic geometry instead.
Installing it
Contrib module, shipped in ComfyUI CV. Manager → search ComfyUI CV, or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
# restart ComfyUI
Python ≥3.12 and a recent, V3-API ComfyUI.
What goes wrong
nbEltleft at 0 - the default is zero points, so nothing useful comes out. This is one of those parameters with no useful OpenCV default that the wrapper still has to show you.- Empty output. There were no contours in the input - usually because the edge map was inverted, or the threshold threw everything away. Preview the Canny result before feeding it in.
- Fewer points than you asked for. Sampling is bounded by the contour's own pixel count; a tiny contour can't yield 500 distinct samples.
- Multi-channel input. Give it a single-channel map. If you're unsure which you have,
Inspect CV Datareports the shape. ximgprocmissing from the menu. Contrib-only submodule, and all fouropencv-python*distributions share onesite-packages/cv2- a non-contrib wheel leaves the submodules as empty stubs.tools/repair_opencv_contrib.py --checkin the pack repo reports it,--applyrepairs it.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY,IMAGE,MASK | - - - 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. | |
| nbElt | INT | 0-2147483648–2147483647 | - - - |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |