Nodes/ComfyUI CV/cv2.arcLength
ComfyUI Node

cv2.arcLength

Perimeter in pixels, and the four things it feeds

By bmad4ever·Created 4 months ago·Updated 17 days ago· 1
cv2.arcLength
  • curve
  • float
◄closedfalse►

cv2.arcLength returns the length of a curve - its perimeter, if the curve is closed. Two inputs, one float out. It is the least glamorous node in the pack and one of the few that answers a question you can act on immediately.

Because that's the thing about perimeter: it's a measurement. Not a score, not a map, not a feature vector - a number in pixels you can convert to millimetres, compare against a threshold, or use to calibrate everything else in the graph.

How it works

It walks the point chain and sums the distances between consecutive points (using the straight-line distance for each segment). With closed = True, the segment from the last vertex back to the first is included; with closed = False, it isn't. That single boolean changes the answer, and it's the one parameter here.

The curve has to be a point set: curve is NPARRAY-only, no image sockets. The pack's CV Contour To Points bridges a contour from CV Find Contours into the shape this wants, and the output is a plain float - a FLOAT socket you can wire into anything numeric.

Inputs and outputs

  • curve (NPARRAY) - the point chain.
  • closed (BOOLEAN) - connect the last point back to the first.
  • float - the length in pixels.

What it's actually for

1. You need an epsilon for cv2_approxPolyDP. This is the everyday use. Get the perimeter, scale it by 1–2%, feed that in as the tolerance. It's the difference between guessing at simplification and choosing it.

2. Size filtering. A contour's perimeter is how you say "big enough to care about" without hard-coding a bounding box. The pack's CV Filter Contours does this for you across measured properties, but knowing the number is how you pick the range.

3. Scale calibration. Measure a known object once - a coin, a sheet of paper, an ArUco board edge - and the ratio of pixels to millimetres converts every other measurement in the frame. The pack's measure-and-export workflow is built around that idea, and this is the value that anchors it.

4. Shape descriptors. 4π·Area / Perimeter² is circularity: 1.0 for a perfect circle, ~0.79 for a square, lower for anything ragged. Area comes from cv2_contourArea, perimeter from here. It's an old, cheap, robust shape feature, and it works fine.

Install

ComfyUI Manager → comfyui_cv (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. Requires Python ≥ 3.12 and a recent ComfyUI on the V3 node API; behaviour is curated against OpenCV 5.0.0.93. Keep the contrib wheel: a non-contrib opencv-python installed over it silently empties the contrib submodules.

Where people get burned

closed flipping between two contours. A four-vertex square reports four sides' worth of length when closed and three when not. Use the same convention everywhere or your ratios quietly drift by one edge.

Measuring after you resized. The number is in pixels of the current image. Downscale a frame for speed and every length scales with it. Measure at native resolution, or carry the scale factor explicitly.

Comparing lengths across different resolutions. Same trap wearing a different hat: two contours from two differently-sized crops are not comparable without a scale.

Confusing it with area. Perimeter is not a size in any useful spatial sense - a long thin curl can out-measure a fat blob. If you mean "how big", you want cv2_contourArea or cv2_boundingRect.

Passing pixels as a curve. If the array has image dimensions rather than a point chain, you get a nonsense number rather than an error. CV Array Shape is the ten-second check.

Categoryimage/CV/low-level/cv2 A

Inputs (2)

NameTypeDefaultDescription
curveNPARRAY - - - A data array (points / matrix), NOT an image - only an NPARRAY link is accepted here.
closedBOOLEANfalse - - -

Outputs (1)

NameTypeDescription
floatFLOAT—