locus-tag
Locus detects AprilTag and ArUco markers, as well as AprilGrid and ChArUco boards. It's implemented in Rust with zero-copy Python bindings. It targets a balance of low latency, high pose accuracy and high recall.
[!WARNING] Experimental: pre-1.0, not recommended for production yet.
- The API may break until 1.0.0. The road to 1.0 is a smaller API surface and validation on real-camera (not just synthetic) data. Contribution of permissively licensed real datasets greatly appreciated (open an issue to chat about it)!
- Distortion-model support is experimental and slated for a redesign.
- The shipped tag families are intentionally minimal.
Some Features
- Zero-copy ingestion: images cross the Rust↔Python boundary through the NumPy Buffer Protocol; no copies.
- Releases the GIL during detection, so it parallelizes cleanly across Python threads.
- 6-DOF pose: an IPPE-Square seed refined by a weighted Levenberg–Marquardt solver, and internal-edge based optional refinement.
- Allocation light: per-frame arena allocation, no
mallocinsidedetect().
Supported markers & requirements
- Tag families: AprilTag (
16h5,36h11) and ArUco (4x4_50,4x4_100,6x6_250). More can be registered: Add a dictionary. - Boards: AprilGrid and ChArUco layouts over those families.
- Python: 3.10+ (abi3 wheels).
- Platforms: prebuilt wheels for Linux (x86_64 / aarch64, glibc + musl), macOS (Intel + Apple Silicon), and Windows (x64).
Installation
pip install locus-tag
The PyPI wheel targets rectified (pinhole) imagery. For unrectified cameras (Brown–Conrady, Kannala–Brandt fisheye), see Install with distortion support.
Quick start
Detect markers
import cv2
import locus
img = cv2.imread("tags.jpg", cv2.IMREAD_GRAYSCALE)
detector = locus.Detector(families=[locus.TagFamily.AprilTag36h11])
batch = detector.detect(img) # parallel NumPy arrays
print(batch.ids) # (N,)
print(batch.corners.shape) # (N, 4, 2)
Estimate 6-DOF pose
from locus import Detector, CameraIntrinsics
intrinsics = CameraIntrinsics(fx=800.0, fy=800.0, cx=640.0, cy=360.0)
batch = detector.detect(
img,
intrinsics=intrinsics,
tag_size=0.10, # physical side length, meters
)
if batch.poses is not None:
print(batch.poses[0]) # [tx, ty, tz, qx, qy, qz, qw]
Configuration is nested and Pydantic-validated: start from a shipped profile, edit the group you care about, and hand it back to the detector. The detection guide walks through the DetectorConfig API.
Performance
Profiles are selected by name and embedded in the wheel:
profile |
Best for | Notes |
|---|---|---|
"standard" |
General detection | Balanced recall and precision; highest recall on small/distant tags. |
"grid" |
ChArUco / AprilGrid boards | 4-connectivity recovers touching tags that "standard" merges. |
"high_accuracy" |
Metrology, AV pose | Best pose accuracy and rotation-tail control. Needs camera intrinsics + tag_size. |
On our high-fidelity render-tag suite (1080p, single-thread), high_accuracy leads both the translation and rotation tails while running ~13× faster than OpenCV's best-accuracy configuration:
| Detector | Rot p99 | Trans p99 | Latency |
|---|---|---|---|
Locus (high_accuracy) |
0.249° | 20.1 mm | 15.2 ms |
OpenCV (cv2.aruco, apriltag) |
0.376° | 55.3 mm | 195.8 ms |
Full results — both benchmark suites (render-tag + ICRA 2020), every percentile, methodology, and hardware — are in the performance docs.
Visual debugging
Built-in integration with the Rerun SDK emits intermediate pipeline stages:
batch = detector.detect(img, debug_telemetry=True)
if batch.telemetry:
print(batch.telemetry.subpixel_jitter)
Documentation
- Detection guide for end-to-end usage and the config API
- Python API reference
- Performance & benchmarks
- Architecture & memory model
- Coordinate conventions
Contributing
See the engineering workflow for the dev setup and PR gates.
License
Dual-licensed under Apache 2.0 or MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file locus_tag-0.7.1.tar.gz.
File metadata
- Download URL: locus_tag-0.7.1.tar.gz
- Upload date:
- Size: 390.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59d4554e5bacdb65556fd967a08957ffd5383b4dc2c980889e30e2ceee17f980
|
|
| MD5 |
6be3b744e8fb4fe83e13b1ed68e091e0
|
|
| BLAKE2b-256 |
90df778281c1a3e2326fa56907906f87518094959008557147a2978f45e3d5be
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1.tar.gz:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1.tar.gz -
Subject digest:
59d4554e5bacdb65556fd967a08957ffd5383b4dc2c980889e30e2ceee17f980 - Sigstore transparency entry: 2203229175
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type:
File details
Details for the file locus_tag-0.7.1-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: locus_tag-0.7.1-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 588.7 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aab28aaaad79ac3c69cf99959169a30c5400060c3b1b4bc735f5eedf900f9ec5
|
|
| MD5 |
1de2cb3f4ea296a6a6c4c86160712fbb
|
|
| BLAKE2b-256 |
00a5889b381cfd6626ab9716d77c5acf7402a5b913a91d814111975405ac9ba8
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1-cp310-abi3-win_amd64.whl -
Subject digest:
aab28aaaad79ac3c69cf99959169a30c5400060c3b1b4bc735f5eedf900f9ec5 - Sigstore transparency entry: 2203229249
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type:
File details
Details for the file locus_tag-0.7.1-cp310-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: locus_tag-0.7.1-cp310-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 917.2 kB
- Tags: CPython 3.10+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c68ee55eff243cfcfe894f5d37d4dd2d77824db48ab6579accbb2b76975c2881
|
|
| MD5 |
c9844a72ac206f9a276d5c4fb182910f
|
|
| BLAKE2b-256 |
42c122aed49c0fcdeae546d6f1c84399b18e1dbc8eeffc76630b67308c4d6a61
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1-cp310-abi3-musllinux_1_2_x86_64.whl:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1-cp310-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
c68ee55eff243cfcfe894f5d37d4dd2d77824db48ab6579accbb2b76975c2881 - Sigstore transparency entry: 2203229227
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type:
File details
Details for the file locus_tag-0.7.1-cp310-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: locus_tag-0.7.1-cp310-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 821.3 kB
- Tags: CPython 3.10+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
22d8ec3c733116f55f57317ecc80965bb14105e45e54c3fd018db7937b83545d
|
|
| MD5 |
37ed871ee9999161124db6e3cb161070
|
|
| BLAKE2b-256 |
61e816e5f69ad4c032f684b7c109378e48cd1bb336e020eb13e82d3455cef8bf
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1-cp310-abi3-musllinux_1_2_aarch64.whl:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1-cp310-abi3-musllinux_1_2_aarch64.whl -
Subject digest:
22d8ec3c733116f55f57317ecc80965bb14105e45e54c3fd018db7937b83545d - Sigstore transparency entry: 2203229331
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type:
File details
Details for the file locus_tag-0.7.1-cp310-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: locus_tag-0.7.1-cp310-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 701.4 kB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7832306c43e11c657279caf48eab7cb371370db925389516de4cb185601e5177
|
|
| MD5 |
efd26dd7365aad06015f690fb417c94e
|
|
| BLAKE2b-256 |
7d87a027d377c26d89534c20f20cf223a29cf9601a1ac185b55a96c0ab5e709a
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1-cp310-abi3-manylinux_2_28_x86_64.whl:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1-cp310-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
7832306c43e11c657279caf48eab7cb371370db925389516de4cb185601e5177 - Sigstore transparency entry: 2203229208
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type:
File details
Details for the file locus_tag-0.7.1-cp310-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: locus_tag-0.7.1-cp310-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 644.5 kB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73eead0406a61044c0287a58722c71381929acce1324c1994d7de07fe8088f8e
|
|
| MD5 |
12ff58fba16c71a2b027733f204b7765
|
|
| BLAKE2b-256 |
36908281432f8f6513ba22e2b7994ba64213443413daa492c3b3463cf59c130b
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1-cp310-abi3-manylinux_2_28_aarch64.whl:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1-cp310-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
73eead0406a61044c0287a58722c71381929acce1324c1994d7de07fe8088f8e - Sigstore transparency entry: 2203229305
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type:
File details
Details for the file locus_tag-0.7.1-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: locus_tag-0.7.1-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 641.0 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e89ba21702643e5440f3c7ec3d812541e25985d3f2fccb6e69952490a967146b
|
|
| MD5 |
6cb10b1c040e3feefcc6f042a4b753f9
|
|
| BLAKE2b-256 |
98ae61372dec22dfd735d0d533e45e1ad1eeeddc29ea12664f8610cc5cc4f291
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
e89ba21702643e5440f3c7ec3d812541e25985d3f2fccb6e69952490a967146b - Sigstore transparency entry: 2203229272
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type:
File details
Details for the file locus_tag-0.7.1-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: locus_tag-0.7.1-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 664.8 kB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9edf179334d7fb6718006d6a3ed0d6b6a47b1aac58f5cd71b4eeffc645affa42
|
|
| MD5 |
fa66a1a563b052a57e153ce0517c0132
|
|
| BLAKE2b-256 |
ac91df4f10b0ce63d3f6932f138cc1a7847aaa9b02b450ebb5d1a9003c919166
|
Provenance
The following attestation bundles were made for locus_tag-0.7.1-cp310-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on NoeFontana/locus-tag
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
locus_tag-0.7.1-cp310-abi3-macosx_10_12_x86_64.whl -
Subject digest:
9edf179334d7fb6718006d6a3ed0d6b6a47b1aac58f5cd71b4eeffc645affa42 - Sigstore transparency entry: 2203229292
- Sigstore integration time:
-
Permalink:
NoeFontana/locus-tag@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Branch / Tag:
refs/tags/v0.7.1 - Owner: https://github.com/NoeFontana
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4e4a0267a42833dc0da03d4c5bc7eb3d0ea0d566 -
Trigger Event:
push
-
Statement type: