Skip to main content

No project description provided

Project description

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). 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 → 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.
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

  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["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_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

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

calib_targets-0.7.3.tar.gz (466.1 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.7.3-cp310-abi3-win_amd64.whl (870.2 kB view details)

Uploaded CPython 3.10+Windows x86-64

calib_targets-0.7.3-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.7.3-cp310-abi3-macosx_11_0_arm64.whl (999.9 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

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

File metadata

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

File hashes

Hashes for calib_targets-0.7.3.tar.gz
Algorithm Hash digest
SHA256 59fcdba9ab9bba69bd6027c8aacd9f7f618f661b548823def6a2c22829503e3c
MD5 3552219090dced23e54682044bd7afa0
BLAKE2b-256 0ec5adb2504be4aa1b664c50b2b79acd9b32966f6df31bc2e85ecfa1c2d9e1cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.7.3.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.7.3-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for calib_targets-0.7.3-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 51def54eaeb604d4fa87b45a8de60ca2b8a5b0a55eb5d8c6d986da1101e01246
MD5 3ea386e5ba41bfc08f98f314301a8ab9
BLAKE2b-256 45d16c0ba590e3b9f0c8d4310cbdd4b1209237169542e30088b019287233d436

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.7.3-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.7.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for calib_targets-0.7.3-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0729d9d5fe413039276272d1e013d31b94ac721ff458c705d053671399f38149
MD5 80590898079193e26207850fcb6274e9
BLAKE2b-256 286ef6622cae5088ed9e9e11f106318162af7f6263b48e88e3017129f1010cfa

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.7.3-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.7.3-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for calib_targets-0.7.3-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ed0729dc506d4decfc508dd2f1f2ba5d1ac666c4081a76844e609409daacd72e
MD5 ec604206d334003cb5633c6de6686c92
BLAKE2b-256 2296c55b273f2bc69eca478a152a16dd40f53ad818136b3964cfcb7811d99e5b

See more details on using hashes here.

Provenance

The following attestation bundles were made for calib_targets-0.7.3-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.

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