add_metrology_object_circle_measure — MEASURE1D model op

• Data kinds: metrologymodel → scalar

• Call: import fullseye as fs; fs.ledger.add_metrology_object_circle_measure(model, row, col, radius, n: 'int' = 40) -> 'int' (to call the implementation directly, import metrology; metrology.add_metrology_object_circle_measure(model, row, col, radius, n: 'int' = 40) -> 'int'; from the registry, opsmeasure1d.get("add_metrology_object_circle_measure"))

Usage

Adds a circle metrology object (add_metrology_object_circle_measure).

Stacks the reference circle (centre (row, col), radius radius [px]) onto model["objects"] (the dict is updated in place). apply_metrology_model places points at the angles dividing the circumference into n equal parts, stretches a measuring line at each point radially (outward normal), takes the sub-pixel edge, and recomputes centre and radius by a least-squares circle fit.

• radius: reference radius [px]. The deviation from the real object must be within measure_length of apply (default ±6 px) -- edges farther out than that are not found.

• n: number of samples on the circumference (default 40). Increase it for circles with larger radius.

• Arguments are not validated here (a radius of 0 or less can be stacked but is meaningless).

• Returns: index of the added position (starting at 0). params of the apply result is row / col / radius, and rms is the radial residual from the circle [px].

Used for inspecting hole and pin diameters and for centring circular parts.

Choosing n (measured 2026-09-15 on synthetic discs blurred with σ=1 px): the bias does not depend on n (constant within ±0.005 px for R=8–128 px and n=6–240; the bias itself depends on R through edge rounding, −0.09 → −0.006 px). What n changes is the scatter: with noise σ=0.03, std·√n stays constant while the sample spacing 2πR/n on the circumference is about 3 px or more (= independent samples, std ∝ 1/√n), and denser sampling no longer lowers it (R=16: 0.0174 px at n=40, 0.0164 px at n=240). So going beyond n ≈ 2πR / 3 (40 at R=20 = the default, 130 at R=64, 270 at R=128) only costs time (22 ms at n=1000). With 25 % of the circumference missing, more n does not fix the bias (−0.005 → −0.020 px). If edges are merely not found on the missing side, rms actually drops (0.051 → 0.018); if false edges are picked up at the gap boundary, rms jumps — a gap is not visible in rms alone, so gate on the number of edge_points too (examples/example_inner_diameter_mm.py). The reference-radius offset is bounded by measure_length (default ±6 px): +5.5 px passes, +6.5 px gives params=None.

Empty input (model an empty dict) raises ValueError.

Detailed usage guide

• subpixel_measuring family guide

References (sample data, literature)

• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).

• Operator provenance and references — the sources of the research/methods this op family came from.

• The canonical algorithm (author, year) and its uses are named in the family usage guide above.

Runnable examples (verified samples that actually call this op)

• example_inner_diameter_mm — py -3.11 examples/example_inner_diameter_mm.py

• poc_calipers_under_illusion — py -3.11 examples/poc_calipers_under_illusion.py

• poc_dimensional_inspection — py -3.11 examples/poc_dimensional_inspection.py

• poc_telecentric_metrology — py -3.11 examples/poc_telecentric_metrology.py

Ops the type connects to (they accept scalar as input)

—

Same category (model)

create_metrology_model · add_metrology_object_line_measure · add_metrology_object_rectangle2_measure · add_metrology_object_ellipse_measure · add_metrology_object_generic


*Provenance: metrology.py — MEASURE1D operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.