No project description provided
Project description
calib-targets — Python bindings
Native-feeling Python API for the calib-targets Rust workspace.
Detects chessboards, ChArUco, PuzzleBoard, and marker boards, and
generates printable target bundles (JSON + SVG + PNG). Built with
PyO3 + maturin.
Python package name: calib_targets (the Rust crate is
calib-targets-py).
Install
# From source — this repo:
uv pip install maturin
uv run maturin develop --release -m crates/calib-targets-py/Cargo.toml
# Or from PyPI (pre-built wheels):
pip install calib-targets
Hello world
import numpy as np
from PIL import Image
import calib_targets as ct
image = np.asarray(Image.open("board.png").convert("L"), dtype=np.uint8)
result = ct.detect_chessboard_best(image, [ct.ChessboardParams()])
if result is not None:
print(f"labelled {len(result.detection.corners)} corners")
End-to-end round-trip per target type
Each snippet covers: generate a printable target → load the PNG → detect → export detection to JSON.
Runnable scripts at
crates/calib-targets-py/examples/. Use any of
them as a starting point.
Chessboard
import io, json
import numpy as np
from PIL import Image
import calib_targets as ct
# 1. Generate target.
doc = ct.PrintableTargetDocument(
target=ct.ChessboardTargetSpec(inner_rows=7, inner_cols=9, square_size_mm=20.0),
page=ct.PageSpec(size=ct.PageSize.custom(width_mm=220.0, height_mm=180.0), margin_mm=10.0),
render=ct.RenderOptions(png_dpi=150),
)
bundle = ct.render_target_bundle(doc)
# 2. Load as grayscale numpy array.
image = np.asarray(Image.open(io.BytesIO(bundle.png_bytes)).convert("L"), dtype=np.uint8)
# 3. Detect — prefer *_best for robustness.
result = ct.detect_chessboard_best(image, [
ct.ChessboardParams(),
ct.ChessboardParams(chess=ct.ChessConfig(threshold_value=0.15)),
ct.ChessboardParams(chess=ct.ChessConfig(threshold_value=0.08)),
])
# 4. Export detection to JSON.
print(json.dumps(result.to_dict(), indent=2)[:200])
Runnable: examples/chessboard_roundtrip.py.
ChArUco
import calib_targets as ct
# (synthesise PNG as above; build matching board spec)
board = ct.CharucoBoardSpec(
rows=5, cols=7, cell_size=1.0, marker_size_rel=0.75,
dictionary="DICT_4X4_50", marker_layout=ct.MarkerLayout.OPENCV_CHARUCO,
)
params = ct.CharucoParams(
board=board, px_per_square=60.0,
chessboard=ct.ChessboardParams(),
max_hamming=2, min_marker_inliers=4,
)
result = ct.detect_charuco(image, params=params) # raises on failure
print(len(result.detection.corners), "corners,", len(result.markers), "markers")
Runnable: examples/charuco_roundtrip.py.
Marker board
circles = (
ct.MarkerCircleSpec(i=3, j=2, polarity=ct.CirclePolarity.WHITE),
ct.MarkerCircleSpec(i=4, j=2, polarity=ct.CirclePolarity.BLACK),
ct.MarkerCircleSpec(i=4, j=3, polarity=ct.CirclePolarity.WHITE),
)
layout = ct.MarkerBoardLayout(rows=6, cols=8, cell_size=1.0, circles=circles)
params = ct.MarkerBoardParams(layout=layout, chessboard=ct.ChessboardParams())
result = ct.detect_marker_board(image, params=params)
Runnable: examples/markerboard_roundtrip.py.
PuzzleBoard
params = ct.default_puzzleboard_params(rows=10, cols=10)
params.decode.search_mode = ct.PuzzleBoardSearchMode.fixed_board()
params.decode.scoring_mode = ct.PuzzleBoardScoringMode.soft_log_likelihood()
result = ct.detect_puzzleboard(image, params=params)
# Every corner has an absolute master ID: result.detection.corners[0].id
# Soft mode also exposes result.decode.score_margin and the runner-up hypothesis.
Runnable: examples/puzzleboard_roundtrip.py.
Inputs
image: numpy.ndarray[uint8]with shape(h, w). Grayscale only; convert RGB upstream (Image.convert("L")).chess_cfg: ChessConfig | None— overrides the default ChESS corner detector.params: *Params— typed dataclass matching the detector. Dict inputs are rejected; use the typed classes.
Outputs
Every detection result is a typed dataclass with full attribute access,
editor autocomplete, and type stubs. Round-trip through JSON with
to_dict() and from_dict(...) — the dict schema matches the Rust
crate's serde_json output byte-for-byte.
payload = json.dumps(result.to_dict())
# ... later, elsewhere:
restored = ct.ChessboardDetectionResult.from_dict(json.loads(payload))
Every config / result type has these methods — ChessConfig,
ChessboardParams, CharucoParams, PuzzleBoardParams,
MarkerBoardParams, PrintableTargetDocument, and all result types.
Printable targets
One-liner helpers with sensible defaults (A4 portrait, 10 mm margins, 300 DPI):
doc = ct.charuco_document(rows=5, cols=7, square_size_mm=20.0,
marker_size_rel=0.75, dictionary="DICT_4X4_50")
written = ct.write_target_bundle(doc, "out/charuco_a4")
print(written.json_path, written.svg_path, written.png_path)
Other helpers: chessboard_document, puzzleboard_document,
marker_board_document. Each accepts optional page= / render=
overrides. For full control, construct PrintableTargetDocument
directly with one of the target specs (ChessboardTargetSpec,
CharucoTargetSpec, MarkerBoardTargetSpec, PuzzleBoardTargetSpec).
CLI
pip install calib-targets installs a calib-targets console script
that mirrors the Rust CLI:
calib-targets gen puzzleboard --rows 8 --cols 10 --square-size-mm 15 \
--out-stem puzzle
calib-targets list-dictionaries
calib-targets init chessboard --out spec.json \
--inner-rows 6 --inner-cols 8 --square-size-mm 20
calib-targets generate --spec spec.json --out-stem my_board
See testdata/printable/*.json for ready-made
spec files; every file is PrintableTargetDocument.from_dict( json.load(open(path)))-compatible.
Tuning difficult cases
- Replace
detect_*withdetect_*_bestand pass a 3-config sweep — this is the recommended default. - Increase rasterisation / input resolution if cells are smaller than ~20 px across.
- Open the per-detector README for deeper guidance: chessboard, ChArUco, PuzzleBoard, marker. Python passes all parameters through to Rust, so tuning advice applies identically.
Limitations
- One target instance per image. Multiple simultaneous boards are not detected; pass cropped sub-images per target.
- Pinhole-ish optics only. Moderate radial / perspective distortion is handled gracefully; fisheye is not supported.
- Grayscale uint8 numpy arrays only. No torch tensors, no GPU.
- Board PNG / SVG generation for chessboard, ChArUco, marker board, and PuzzleBoard is supported; other target kinds are not.
Migration from pre-0.7 dict-based API
| Old | New |
|---|---|
detect_chessboard(img, params={"min_corner_strength": 0.5}) |
detect_chessboard(img, params=ChessboardParams(min_corner_strength=0.5)) |
detect_charuco(..., params={"board": {...}}) |
detect_charuco(..., params=CharucoParams(board=CharucoBoardSpec(...))) |
result["detection"]["corners"] |
result.detection.corners |
json.dumps(result_dict) |
json.dumps(result.to_dict()) |
Dict-based configuration is rejected in the new API; use the typed dataclasses.
Feature parity vs Rust facade
detect_chessboard/_all/_best/_debug— ✔detect_charuco/_best,detect_puzzleboard/_best,detect_marker_board/_best— ✔- Printable targets for all four target kinds — ✔
to_dict/from_dictround-trip on every config + result type — ✔
Implementation note
The compiled Rust module is internal (calib_targets._core). Public
API stability is guaranteed only for top-level calib_targets exports.
Links
- Book (getting started + per-target chapters): https://vitalyvorobyev.github.io/calib-targets-rs/
- Rust facade crate: https://docs.rs/calib-targets
- Source + issue tracker: https://github.com/VitalyVorobyev/calib-targets-rs
Project details
Release history Release notifications | RSS feed
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 calib_targets-0.8.0.tar.gz.
File metadata
- Download URL: calib_targets-0.8.0.tar.gz
- Upload date:
- Size: 534.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3fa5149e3335bb54d917adf7d82994f87dbb69074af1cafc86fe3b49fe16c97
|
|
| MD5 |
f92e36f26756e89d77c70594c3e3432d
|
|
| BLAKE2b-256 |
1dd3f06b8310bb901a0567002f37e82737e114a4037153baecb81cbf457a2303
|
Provenance
The following attestation bundles were made for calib_targets-0.8.0.tar.gz:
Publisher:
release-pypi.yml on VitalyVorobyev/calib-targets-rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
calib_targets-0.8.0.tar.gz -
Subject digest:
a3fa5149e3335bb54d917adf7d82994f87dbb69074af1cafc86fe3b49fe16c97 - Sigstore transparency entry: 1397770476
- Sigstore integration time:
-
Permalink:
VitalyVorobyev/calib-targets-rs@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/VitalyVorobyev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Trigger Event:
push
-
Statement type:
File details
Details for the file calib_targets-0.8.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: calib_targets-0.8.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
293232a16c7f66804f47023948666c582baada4717d8c61f74b3e8e7f35949fe
|
|
| MD5 |
be73aa3095d7b8e6c9e0cc8b5d520ccd
|
|
| BLAKE2b-256 |
3698829521d7b1e6b610d16f0d25a9f8ac1c771da7cfeacf013da34665ce4714
|
Provenance
The following attestation bundles were made for calib_targets-0.8.0-cp310-abi3-win_amd64.whl:
Publisher:
release-pypi.yml on VitalyVorobyev/calib-targets-rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
calib_targets-0.8.0-cp310-abi3-win_amd64.whl -
Subject digest:
293232a16c7f66804f47023948666c582baada4717d8c61f74b3e8e7f35949fe - Sigstore transparency entry: 1397770611
- Sigstore integration time:
-
Permalink:
VitalyVorobyev/calib-targets-rs@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/VitalyVorobyev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Trigger Event:
push
-
Statement type:
File details
Details for the file calib_targets-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: calib_targets-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a913b6ae211f5649a5f04bce44ed4c2c0654c0a41b407279e92c80e41e7e89e
|
|
| MD5 |
bafaa155f0a005d8e66c0ce5fab5aab6
|
|
| BLAKE2b-256 |
718ad89a557ceac69635dff86fe26135f52b976f690064d168753a1abb02d45d
|
Provenance
The following attestation bundles were made for calib_targets-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release-pypi.yml on VitalyVorobyev/calib-targets-rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
calib_targets-0.8.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
2a913b6ae211f5649a5f04bce44ed4c2c0654c0a41b407279e92c80e41e7e89e - Sigstore transparency entry: 1397770670
- Sigstore integration time:
-
Permalink:
VitalyVorobyev/calib-targets-rs@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/VitalyVorobyev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Trigger Event:
push
-
Statement type:
File details
Details for the file calib_targets-0.8.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: calib_targets-0.8.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2a9fabce98ca0a322a24aedc6a91c7dad71fda9432ccd488b9d6f4437c22d784
|
|
| MD5 |
de33e1aa8f19414da383cf26c6a3714b
|
|
| BLAKE2b-256 |
ddd9d32566da965cf8ccdc8f016a8933a3a56dec382dc90f260a37d10725cb6a
|
Provenance
The following attestation bundles were made for calib_targets-0.8.0-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release-pypi.yml on VitalyVorobyev/calib-targets-rs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
calib_targets-0.8.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
2a9fabce98ca0a322a24aedc6a91c7dad71fda9432ccd488b9d6f4437c22d784 - Sigstore transparency entry: 1397770545
- Sigstore integration time:
-
Permalink:
VitalyVorobyev/calib-targets-rs@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/VitalyVorobyev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@70ab0cb103f45c1a816eb44dc487284a6af9c8aa -
Trigger Event:
push
-
Statement type: