Skip to main content

A high-performance fiducial marker detector for robotics.

Project description

locus-tag

CI Docs License: MIT OR Apache-2.0

Locus detects AprilTag and ArUco markers as well as AprilGrid and ChArUco boards. The library is implemented in Rust and provides zero-copy Python bindings.

[!WARNING] Experimental Status: API is subject to breaking changes until 1.0.0 ships. The main workstreams towards 1.0.0 are reducing the API surface and validating against non-synthetic data. Until then, this library isn't recommended for production systems. The support for distortion models is experimental and requires a ground-up redesign. Addition of default tag families may happen on request, the current defaults were chosen to be minimal and support most commonly used tags.

Technical Capabilities

  • Zero-Copy Ingestion: Accesses NumPy arrays via the Python Buffer Protocol.
  • Parallel Execution: Releases the Python GIL during detection to allow multi-threaded use.
  • Vectorized Results: Returns a DetectionBatch with parallel arrays for IDs, corners, and poses.
  • Memory: Uses bumpalo arena allocation for zero heap allocations in the detection loop.
  • Solvers: 6-DOF recovery using IPPE-Square or weighted Levenberg-Marquardt with corner uncertainty.

Performance Profiles

Locus optimises for high recall, low corner RMSE, and low latency. Profiles are selected by name; the three shipped profiles are authored as JSON files and embedded in the wheel.

profile Primary characteristic
"standard" Production default; balanced recall + precision.
"grid" 4-connectivity for touching tags — ChArUco / AprilGrid boards.
"high_accuracy" EdLines + axis-imbalance gate + adaptive PPB; prioritises pose precision and tail-rotation control.

ICRA 2020 Forward (community benchmark)

ICRA 2020 Forward is the closest thing the AprilTag community has to a neutral benchmark. The 50-frame subset we report on is synthetic (not real-camera), but it's public, peer-reviewed, and the basis for prior detector comparisons — we report on it for continuity with the literature.

Detector Recall Corner RMSE
Locus (standard) 96.2 % 0.315 px
AprilTag 3 (UMich) 62.3 % 0.22 px
OpenCV (cv2.aruco) 33.2 % 0.92 px

render-tag (high-fidelity Blender + PSF)

render-tag is our in-house render suite — Blender with calibrated PSF, exposure, sensor noise, and lens distortion models. The detection scenes carry pixel-accurate ground truth for both corners and 6-DOF pose, which lets us report translation / rotation percentiles in addition to recall. Numbers below are from the 2026-04-25 SOTA snapshot on the 1080p 50-scene subset (see docs/engineering/benchmarking/render_tag_sota_20260425.md for methodology).

Detector Recall Trans p50 Trans p99 Rot p50 Rot p99 Latency
Locus (high_accuracy) 100 % 0.4 mm 25.6 mm 0.058 ° 1.897 ° 11.67 ms
Locus (standard) 100 % 3.5 mm 50.3 mm 0.288 ° 27.248 ° 19.24 ms
AprilTag-C (pupil) 100 % 2.9 mm 54.4 mm 0.061 ° 65.365 ° 25.54 ms
OpenCV (cv2.aruco) 100 % 3.4 mm 141.4 mm 0.113 ° 1.228 ° 44.45 ms

Per-percentile is load-bearing: AprilTag-C's median rotation is the best in class (0.06 °) but its p99 explodes to 65 ° on the symmetric-tag IRLS branch-ambiguity failures.

Installation

pip install locus-tag

The PyPI wheel is compiled for rectified (pinhole) imagery. For unrectified cameras (Brown-Conrady polynomial, Kannala-Brandt equidistant fisheye), see Install with distortion support.

Quick Start

Basic Detection

import cv2
import locus

img = cv2.imread("tags.jpg", cv2.IMREAD_GRAYSCALE)
detector = locus.Detector(families=[locus.TagFamily.AprilTag36h11])

# batch contains parallel NumPy arrays
batch = detector.detect(img)
print(f"IDs: {batch.ids}")
print(f"Corners: {batch.corners.shape}") # (N, 4, 2)

6-DOF Pose Estimation

from locus import Detector, CameraIntrinsics

# fx, fy, cx, cy
intrinsics = CameraIntrinsics(fx=800.0, fy=800.0, cx=640.0, cy=360.0)

# Returns [tx, ty, tz, qx, qy, qz, qw] for each tag
batch = detector.detect(
    img,
    intrinsics=intrinsics,
    tag_size=0.10,  # physical side length in meters
)

if batch.poses is not None:
    # First tag translation
    print(batch.poses[0, :3])

Configuration Overrides

Settings are nested and validated by Pydantic. Start from a shipped profile, edit the group you care about, and hand it back to the detector:

base = locus.DetectorConfig.from_profile("high_accuracy").model_dump()
base["quad"]["upscale_factor"] = 2
base["decoder"]["max_hamming_error"] = 1

detector = locus.Detector(config=locus.DetectorConfig.model_validate(base))

Visual Debugging

Built-in integration with the Rerun SDK:

batch = detector.detect(img, debug_telemetry=True)
if batch.telemetry:
    print(batch.telemetry.subpixel_jitter)

Documentation

License

Dual-licensed under Apache 2.0 or MIT.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

locus_tag-0.6.0.tar.gz (371.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

locus_tag-0.6.0-cp310-abi3-win_amd64.whl (535.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

locus_tag-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl (863.0 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

locus_tag-0.6.0-cp310-abi3-musllinux_1_2_aarch64.whl (775.9 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

locus_tag-0.6.0-cp310-abi3-manylinux_2_28_x86_64.whl (647.4 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

locus_tag-0.6.0-cp310-abi3-manylinux_2_28_aarch64.whl (597.8 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

locus_tag-0.6.0-cp310-abi3-macosx_11_0_arm64.whl (592.6 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

locus_tag-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl (610.1 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file locus_tag-0.6.0.tar.gz.

File metadata

  • Download URL: locus_tag-0.6.0.tar.gz
  • Upload date:
  • Size: 371.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for locus_tag-0.6.0.tar.gz
Algorithm Hash digest
SHA256 3e7d7b659a921b61d1b463e0906400cd33ba4349764b6221e3eab3b87daa896b
MD5 0613b93e4178753ecebd530060bb278a
BLAKE2b-256 67376239fe3b3ddf577d9b35a2ae2a7c449a62ea08af8f9d1a2028d1cc860f4f

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0.tar.gz:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file locus_tag-0.6.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: locus_tag-0.6.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 535.3 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for locus_tag-0.6.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 b69304b4d8e0ccf77547d39edfe318eb1763d931f7077bc13f6923a5ccb6803d
MD5 987d448da22f1002d0204afdc2355c09
BLAKE2b-256 f50e1839971f7fb03567f81338bc6a50df9b5acbed78f2af3db59ea5e9943783

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file locus_tag-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for locus_tag-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e56496b8c7282f89703c68c2d9d98f5d6470cf6aa11e50d1ba3409827fbdeeb3
MD5 f1d13cbd35fe1bb5a69b4066fc034af2
BLAKE2b-256 f45b4b01fdd41b2556e2de1bcc906dca7103963e63646a9a0e7c252c74aa52ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file locus_tag-0.6.0-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for locus_tag-0.6.0-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 bc5dd6627736aeaf8e24487944a44993b96ba725290126e63c0acb53d56f78a0
MD5 9c2eaad454adff866a42f300b2105f1a
BLAKE2b-256 87495590cda876205a48a40fa7394c6ccd15ec2b7265f8928570b4192950f7ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0-cp310-abi3-musllinux_1_2_aarch64.whl:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file locus_tag-0.6.0-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for locus_tag-0.6.0-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 1e1bb09f67b8dd6a4c6754b653ecf51a3a05c4b802e285e0a206b5f8641601f7
MD5 590611a24c629f444eee295a16c3332a
BLAKE2b-256 eac7d19f7d2d6bc871ea2435538a00a8ec3bebd81b4726da3f2e8a91fa35ba02

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0-cp310-abi3-manylinux_2_28_x86_64.whl:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file locus_tag-0.6.0-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for locus_tag-0.6.0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 414d51c16c790fec019cdbcd12aa27bbac51d62bac298e148e0b679725e12466
MD5 543add037bf89ae5fd1e0cffb2d99d18
BLAKE2b-256 55369d1aa1b987c1a74d9e73454499d08319388442a3b0f11b41002042d92281

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0-cp310-abi3-manylinux_2_28_aarch64.whl:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file locus_tag-0.6.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for locus_tag-0.6.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 123f6a78bddfaf4dd315e3282b757b5b64fcf0945de614e195f4ce3d50257c9c
MD5 25d44a7717d055a08c4a84af421258b5
BLAKE2b-256 205cb266b9df3dd7a533002db0fdfc6166041032a2c2628da48fdb33b395dc57

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file locus_tag-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for locus_tag-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9bfc6e57f367c9ed7fd7dec6168a80d528517d0ddf29923f187b34fa8213875d
MD5 a1d78b32344b1aaff8fc693e41459c6d
BLAKE2b-256 f21fac023443e9434b19f0fb5d139c41d6d38339e044e3eb2b4957d008cbcac4

See more details on using hashes here.

Provenance

The following attestation bundles were made for locus_tag-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on NoeFontana/locus-tag

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page