Skip to main content

calib-targets — Python bindings

Book

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 + DXF). 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.corners)} corners")

End-to-end round-trip per target type

Each snippet covers: generate a printable target → load the PNG → detectexport 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.
chess_cfg = ct.ChessConfig(threshold=15.0)
configs = [
    ct.ChessboardParams(),
    ct.ChessboardParams(min_labeled_corners=12),
    ct.ChessboardParams(max_components=1),
]
result = ct.detect_chessboard_best(image, configs, chess_cfg=chess_cfg)

# 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(),
    min_marker_inliers=4,
)
result = ct.detect_charuco(image, params=params)   # raises on failure
print(len(result.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),
)
board = ct.MarkerBoardSpec(rows=6, cols=8, cell_size=1.0, circles=circles)
params = ct.MarkerBoardParams(board=board, chessboard=ct.ChessboardParams())
result = ct.detect_marker_board(image, params=params)

MarkerBoardSpec is also exported under its previous name MarkerBoardLayout (a backward-compatible alias that stays live this release).

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.corners[0].id
# Soft-mode scoring evidence is available from detect_puzzleboard_with_diagnostics().

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, written.dxf_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

  1. Replace detect_* with detect_*_best and pass a 3-config sweep — this is the recommended default.
  2. Increase rasterisation / input resolution if cells are smaller than ~20 px across.
  3. 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["corners"] result.corners
json.dumps(result_dict) json.dumps(result.to_dict())

Dict-based configuration is rejected in the new API; use the typed dataclasses.

ChessboardParams keeps the per-stage tuning knobs flat for ergonomics, but to_dict() now nests everything except the four stable fields (graph_build_algorithm, min_labeled_corners, max_components, min_corner_strength) under an "advanced" block — matching the Rust wire format. These advanced knobs are not covered by semver. The unused projective_line_tol_rel knob was removed (it was a no-op); drop it from any ChessboardParams(...) call that set it.

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_dict round-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

Download files

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

Source Distribution

calib_targets-0.11.0.tar.gz (696.5 kB view details)

Uploaded Source

Built Distributions

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

calib_targets-0.11.0-cp310-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.10+Windows x86-64

calib_targets-0.11.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.5 MB view details)

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

calib_targets-0.11.0-cp310-abi3-macosx_11_0_arm64.whl (1.3 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file calib_targets-0.11.0.tar.gz.

File metadata

  • Download URL: calib_targets-0.11.0.tar.gz
  • Upload date:
  • Size: 696.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for calib_targets-0.11.0.tar.gz
Algorithm Hash digest
SHA256 15c0eeb627df39f459a5d3c9d3bc9126f85941f5f403f3e7f6941c0a7f671a0e
MD5 4cea2d694cd73cc136359dd0419b6d40
BLAKE2b-256 669e16e0ffc1b8fe6073505c4adccf19be1b7b6bc1c9a806697812dbf8a0826b

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.11.0.tar.gz:

Publisher: release-pypi.yml on VitalyVorobyev/calib-targets-rs

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

File details

Details for the file calib_targets-0.11.0-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for calib_targets-0.11.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 6197452503763e4612ebece6af4ce2faba4c22a8cb081e3e81dca2ebdc84cbb4
MD5 719ec59ff295ac527852ea0de8a0dfb9
BLAKE2b-256 d83da65d12d227f26ac8cc59f9958fccf01e9166b345ab1238f2cab2da48b54d

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.11.0-cp310-abi3-win_amd64.whl:

Publisher: release-pypi.yml on VitalyVorobyev/calib-targets-rs

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

File details

Details for the file calib_targets-0.11.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for calib_targets-0.11.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 acc6594b7ac396f6e7c644d4f95501800482c57450663ddf79f20daead5a0387
MD5 dcaf955209da1972f6209a497f4d6ba3
BLAKE2b-256 0b981eddcd997fa93154a5bbfaf94b925d89efa4a1d1b61017e33fa76f3f660c

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.11.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release-pypi.yml on VitalyVorobyev/calib-targets-rs

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

File details

Details for the file calib_targets-0.11.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for calib_targets-0.11.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 bf5ce68f6d56dfc276647b932ecacd22fa98a9a51b7105cc89b19479ae62682a
MD5 6bf1734d50b3859e1eddb83689d6be36
BLAKE2b-256 83a15c4c51cad43e91837cc9ef9f82f752f5dcdeca6628805f0c4aa98be45c90

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.11.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release-pypi.yml on VitalyVorobyev/calib-targets-rs

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

Release history Release notifications | RSS feed

0.13.0

4 files

0.12.1

4 files

0.12.0

4 files

0.11.2

4 files

0.11.1

4 files

This release

0.11.0 This release

4 files

0.10.1

4 files

0.10.0

4 files

0.9.0

4 files

0.8.0

4 files

0.7.3

4 files

0.7.2

4 files

0.7.1

4 files

0.7.0

4 files

0.6.0

4 files

0.5.3

4 files

0.5.2

4 files

0.5.1

4 files

0.5.0

4 files

0.4.2

4 files

0.4.0

4 files

0.3.2

4 files

0.3.1

4 files

0.2.5

4 files

0.2.4

4 files

0.2.3

4 files

0.2.2

4 files

0.2.1

3 files

0.2.0

2 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