Skip to main content

RapidTag

PyPI version Python versions Wheels License: Apache-2.0 Release Built with Rust Platforms

⚠️ Work in progress — not production-ready. RapidTag is under active development and pre-1.0. APIs, behavior, and results may change without notice. Use it for research, evaluation, and prototyping, and validate it against your own data before relying on it for anything critical.

Fast, pure-Rust fiducial marker detection for realtime. RapidTag is a from-scratch Rust reimplementation of OpenCV's ArUco / AprilTag marker detector, exposed to Python via maturin / PyO3 — with no OpenCV runtime dependency. It reproduces OpenCV's detections down to the pixel while running substantially faster.

Why RapidTag

  • ⚡ Faster than OpenCV — ~1.6× faster for realtime single-camera detection, and up to ~3.4× faster for multi-camera and offline batches (scales across cores).
  • 🎯 A true drop-in for accuracy — corners match OpenCV to 0.0000 px, so any downstream pose or tracking is identical (see below).
  • 🧵 Scales with your cores — a batch API processes many frames (a stereo pair, or a whole recording) across all cores with the GIL released.
  • 📦 No OpenCV needed at runtime — the detection pipeline and marker dictionaries are implemented in pure Rust on top of image / nalgebra.

Performance

Measured on real dual-camera data (1280×800 monochrome, AprilTag 36h11):

Workload Speed vs OpenCV
Realtime, single camera 1.57× faster
Multi-camera / offline batch (all cores) up to ~3.4× faster

Same detections, less time — the speedup comes from a leaner detection pipeline, not from skipping work.

Heterogeneous (big.LITTLE) ARM CPUs

On big.LITTLE SoCs, RapidTag pins its worker pool to the fast cores automatically. Every detect call waits on its slowest parallel task, so letting the OS place even one task on a little core caps the whole batch at little-core speed — on a Radxa Dragon Q6A (QCS6490: 4× A55 @1.9 GHz + 4× A78 @2.4–2.7 GHz) auto-pinning takes a single 1280×800 detect from 68 fps to 211 fps, and a dual-camera pair from 66 to 134 pairs/s. The calling thread and any capture/IO threads are left unpinned, keeping the little cores for them. Homogeneous CPUs and non-Linux hosts are unaffected.

Override with RAPIDTAG_CORES: an explicit core list (4-7, 0,2,4) or all to disable pinning. RAYON_NUM_THREADS still controls pool size when set.

Two further board-level settings are worth it on embedded targets:

  • build for the exact CPU with scripts/build-board.sh (-C target-cpu=native)
  • switch the fast cores' cpufreq governor to performance — bursty per-frame work never keeps schedutil clocked up (on the Q6A this is another ~1.7×: 123 → 211 fps single, 102 → 134 pairs/s dual)

Accuracy — verified as a drop-in replacement

Because RapidTag's corners are pixel-identical to OpenCV's, feeding them into the exact same pose pipeline (cv2.solvePnP) yields the same trajectory. Across a ~1,700-frame stereo recording of a moving AprilTag, the recovered position from RapidTag vs OpenCV corners is indistinguishable — a median difference of 0.00 mm on both cameras.

OpenCV vs RapidTag pose comparison

Install

pip install rapidtag

Prebuilt wheels are published for:

OS Architectures libc
Linux x86_64, aarch64 (arm64) glibc (manylinux) + musl (Alpine)
macOS x86_64 (Intel), arm64 (Apple Silicon) —
Windows x64 —

Wheels are abi3 (one wheel works on CPython 3.9+). If no wheel matches, pip builds from the source distribution (needs a Rust toolchain).

Building from source in your own project (opt-in)

By default uv add rapidtag / pip install rapidtag install the prebuilt portable wheel — no Rust toolchain needed. There is no package-side flag or extra (e.g. rapidtag[native]) that changes this; forcing a source build is always an installer-side opt-in on your side, and it needs a Rust toolchain (rustc/cargo) installed.

To make your project always compile rapidtag from source, add this to your pyproject.toml before installing:

[tool.uv]
no-binary-package = ["rapidtag"]

Then, to get CPU-native codegen for the machine you're installing on, set RUSTFLAGS at install time:

RUSTFLAGS="-C target-cpu=native" uv sync

Without RUSTFLAGS this still compiles a portable binary — functionally the same as the prebuilt wheel, just slower to install. The target-cpu=native build is not portable; don't redistribute it.

pip equivalents: pip install rapidtag --no-binary rapidtag, optionally prefixed with the same RUSTFLAGS.

Usage

import cv2            # only to load/generate images
import rapidtag

img = cv2.imread("scene.png")          # HxWx3 BGR, or HxW grayscale uint8

# --- realtime: one frame ---
corners, ids = rapidtag.detect_markers(img, "DICT_APRILTAG_36h11")
# corners: list of 4x2 [(x, y), ...] per marker (clockwise)
# ids:     list of marker ids, aligned with corners

# --- multi-camera / batch: process many frames across all cores ---
results = rapidtag.detect_markers_batch([cam0, cam1], "DICT_APRILTAG_36h11")
(c0, i0), (c1, i1) = results

# --- tunable parameters (same names/defaults as cv2.aruco.DetectorParameters) ---
p = rapidtag.DetectorParameters()
p.adaptive_thresh_constant = 7.0
p.detect_inverted_marker = True
corners, ids = rapidtag.detect_markers(img, "DICT_6X6_250", p)

print(rapidtag.predefined_dictionaries())   # list supported dictionary names

# --- generic calibration chessboard (9 columns x 6 rows of interior corners) ---
found, chessboard_corners = rapidtag.find_chessboard_corners(img, (9, 6))

# --- robust board / multi-marker pose with bad-correspondence rejection ---
pose = rapidtag.solve_pnp_ransac(
    object_points, image_points, camera_matrix, dist_coeffs,
    iterations=100, reprojection_error=3.0, confidence=0.99, seed=0,
)
if pose is not None:
    rvec, tvec, inlier_indices, reprojection_rmse = pose

# --- reusable rigid-body geometry; construct once from your calibration ---
marker_ids = sorted(int(marker_id) for marker_id in rigid_body_config["markers"])
body = rapidtag.RigidBody(
    rigid_body_config["meta"]["tag_size_m"],
    marker_ids,
    [rigid_body_config["markers"][str(i)]["rotation_marker_to_reference"]
     for i in marker_ids],
    [rigid_body_config["markers"][str(i)]["translation_marker_to_reference_m"]
     for i in marker_ids],
)
body_pose = rapidtag.estimate_rigid_body_pose(
    corners, ids, body, camera_matrix, dist_coeffs,
    iterations=100, reprojection_error=3.0,
)
if body_pose is not None:
    print(body_pose.rvec, body_pose.tvec)
    print(body_pose.used_marker_ids, body_pose.inlier_marker_ids)

Documentation

Python signatures are also shipped in rapidtag.pyi for IDEs and type checkers. Maintainers can build the internal Rust documentation with cargo doc --no-deps --document-private-items --open.

Supported dictionaries: all DICT_{4,5,6,7}X{4,5,6,7}_{50,100,250,1000}, DICT_ARUCO_ORIGINAL, DICT_ARUCO_MIP_36h12, and AprilTag DICT_APRILTAG_{16h5,25h9,36h10,36h11}.

Status

Implemented:

  • ArUco / AprilTag marker detection with none, subpixel, contour, and AprilTag 2 quad candidate modes, including decimated search with full-resolution crop refinement
  • Generic chessboard detection with sub-pixel corners (findChessboardCorners)
  • ChArUco board detection using local marker homographies
  • Iterative PnP, RANSAC PnP, rigid-body multi-marker pose, Rodrigues, point projection, and ChArUco board pose estimation

Not yet implemented: grid boards, camera calibration, refineDetectedMarkers, and ChArUco's camera-aware interpolation path.

Build from source

maturin develop --release        # dev install into the current virtualenv
maturin build --release          # or build a wheel

The committed build uses portable CPU baselines so one wheel works everywhere. For a max-performance build tuned to your own machine (not portable — don't redistribute it):

RUSTFLAGS="-C target-cpu=native" maturin build --release

For a wheel tuned to a specific ARM64 board, use ./scripts/build-board.sh (it picks the right CPU flags so the published portable wheels stay CPU-agnostic).

Tests

python tests/crosscheck.py     # cross-validate vs cv2.aruco on synthetic scenes
python tests/crosscheck_chessboard.py  # generic chessboard parity vs OpenCV
python tests/crosscheck_charuco.py     # ChArUco parity vs OpenCV
python tests/crosscheck_pnp.py         # geometry and end-to-end pose parity
python tests/bench.py          # benchmark + parity on real camera data
python scripts/bench_ransac_dome.py    # multi-marker RANSAC benchmark on dome recordings

The verification figures above are reproduced by the scripts in scripts/ (pnp_opencv_vs_rapidtag.py, pnp_sanity.py).

Metadata

Release files for rapidtag 0.1.12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rapidtag 0.1.12
File Size Uploaded
rapidtag-0.1.12.tar.gz 1.1 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for rapidtag 0.1.12
File
rapidtag-0.1.12-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
rapidtag-0.1.12-cp39-abi3-musllinux_1_2_x86_64.whl CPython 3.9 abi3 Linux musl 1.2+ x86-64 Details
rapidtag-0.1.12-cp39-abi3-musllinux_1_2_aarch64.whl CPython 3.9 abi3 Linux musl 1.2+ ARM64 Details
rapidtag-0.1.12-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
rapidtag-0.1.12-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
rapidtag-0.1.12-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
rapidtag-0.1.12-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 6.8 MB

Release files / rapidtag-0.1.12.tar.gz

Download URL rapidtag-0.1.12.tar.gz
Size 1.1 MB
Tags Source
SHA-256 checksum
How to use checksums
d073bf6b613419319c1097e35062bf1269ef1fdd418d922a143173d3fff4d015
BLAKE2b-256 checksum
How to use checksums
636ec235fe4373f3a6269d0abc67a9966f9bbc9349be899b8949cebaa7bd603c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / rapidtag-0.1.12-cp39-abi3-win_amd64.whl

Download URL rapidtag-0.1.12-cp39-abi3-win_amd64.whl
Size 675.3 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
d121f908d52680780fe6e5ce9206fa1afe3428d9e81df667a8340eff9db9e17c
BLAKE2b-256 checksum
How to use checksums
6c4714cf4d1e02ea3d67e61646f5ea39354f38cd6ba3ede6ecd52e45004bce49
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / rapidtag-0.1.12-cp39-abi3-musllinux_1_2_x86_64.whl

Download URL rapidtag-0.1.12-cp39-abi3-musllinux_1_2_x86_64.whl
Size 1.0 MB
Tags CPython 3.9 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
c8f55060c1d59c95a58fc357c21eef4909adb3bd21ccb992b5dc0a04138c67af
BLAKE2b-256 checksum
How to use checksums
7dba2425436b016ba7da5542522ea7a200041a050c2bcd750757457f9eab37de
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / rapidtag-0.1.12-cp39-abi3-musllinux_1_2_aarch64.whl

Download URL rapidtag-0.1.12-cp39-abi3-musllinux_1_2_aarch64.whl
Size 957.8 kB
Tags CPython 3.9 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
1f209ac4d2ca480a43192e097ae356114b63a4f9fde89b43125735c693723d01
BLAKE2b-256 checksum
How to use checksums
16591702af5b1dce39cbb6229e9858aa8ab2a84d1cb88ca1dc1ed941ed2afb38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / rapidtag-0.1.12-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL rapidtag-0.1.12-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 804.7 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
e3cd920650ca5cb92c3dba8023ae3baa3ea14627c71562eb7e3f38e8a5e5efda
BLAKE2b-256 checksum
How to use checksums
77ac6a348042972ce03da97d94833847a8446478bb394774287ff470672e5b64
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / rapidtag-0.1.12-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL rapidtag-0.1.12-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 779.0 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
4987d80fe6b2ddff63c0d5e8a1380fbf320d08442b86ca873c9d6e853a30641e
BLAKE2b-256 checksum
How to use checksums
a501372a11ea5bb9ea1eb8f96769e6c723f0927c514143310be172aaee71d092
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / rapidtag-0.1.12-cp39-abi3-macosx_11_0_arm64.whl

Download URL rapidtag-0.1.12-cp39-abi3-macosx_11_0_arm64.whl
Size 733.5 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
17c54a2fd438c7d04beba3780a12a696436f76b1ecee50bf0c33e5c1c6c84032
BLAKE2b-256 checksum
How to use checksums
6f63b09cbb1f636bf5cfda8b0d817a29e367da80d1d09b01c7afd00c7e6f91ef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release files / rapidtag-0.1.12-cp39-abi3-macosx_10_12_x86_64.whl

Download URL rapidtag-0.1.12-cp39-abi3-macosx_10_12_x86_64.whl
Size 758.3 kB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
acd9e7f5724466179a6152a8a7ccd1b9971c739a43a4dcb09d31ebe4d8f700cb
BLAKE2b-256 checksum
How to use checksums
5e4b6ed40a58f6bfb8079700d054b79f831c99f1c9901849f5c9791069df600f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.12 This release

8 release files

0.1.11

8 release files

0.1.10

8 release files

0.1.9

8 release files

0.1.7

8 release files

0.1.5

8 release files

0.1.4

8 release files

0.1.3

8 release files

0.1.0

8 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page