calib-targets-print
Printable-target generation for the calib-targets workspace. A single
JSON document describes a target (chessboard, ChArUco, PuzzleBoard, or
marker board) plus a page size; the renderer emits a matching .json +
.svg + .png bundle. Same API is re-exported from the facade as
calib_targets::printable.
Canonical user guide: printable-targets book chapter.
Install
[]
= "0.13"
Quickstart
Render a pre-made JSON spec from testdata/printable/ to a JSON + SVG +
PNG bundle:
use ;
Or build the document in-code:
use ;
For ChArUco / marker-board / PuzzleBoard specs it's easier to start from
the JSON templates in
testdata/printable/
and load them via PrintableTargetDocument::load_json.
Inputs
[PrintableTargetDocument] is a single JSON-serialisable document:
| Field | Type | Purpose |
|---|---|---|
schema_version |
u32 |
Currently 1. |
target |
[TargetSpec] |
Discriminated union: Chessboard, Charuco, MarkerBoard, PuzzleBoard. |
page |
[PageSpec] |
size (A4 / Letter / Custom), orientation, margin_mm. |
render |
[RenderOptions] |
debug_annotations, png_dpi. |
All physical dimensions are in millimetres. The renderer errors if the board does not fit inside the printable area after margins.
Target specs
| Variant | Main fields |
|---|---|
[ChessboardTargetSpec] |
inner_rows, inner_cols, square_size_mm |
[CharucoTargetSpec] |
rows, cols, square_size_mm, marker_size_rel, dictionary, border_bits, marker_layout |
[MarkerBoardTargetSpec] |
inner_rows, inner_cols, square_size_mm, circles: [MarkerCircleSpec; 3], circle_diameter_rel |
[PuzzleBoardTargetSpec] |
rows, cols, square_size_mm, origin_row, origin_col, dot_diameter_rel |
Outputs
write_target_bundle(doc, stem)— writes<stem>.json,<stem>.svg,<stem>.pngand returns a [WrittenTargetBundle] with the three paths.render_target_bundle(doc)— returns a [GeneratedTargetBundle] with the three payloads in memory (for tests and roundtrip pipelines).
The written JSON is a normalised pretty-printed copy of the exact
document rendered; feeding it back through load_json reproduces the
same SVG/PNG bit-for-bit.
Canonical starting specs
Ready-to-use JSON templates live under
testdata/printable/:
| File | Target |
|---|---|
chessboard_a4.json |
7 × 9 inner-corner chessboard, A4 |
charuco_a4.json |
31 × 31 DICT_4X4_1000 ChArUco, A4, 600 DPI |
marker_board_a4.json |
3-circle checkerboard marker board, A4 |
puzzleboard_small.json / puzzleboard_mid.json |
PuzzleBoard reference specs |
Tuning print quality
- DPI.
render.png_dpidefaults to 300. Raise to 600 for small ChArUco markers or fine PuzzleBoard dots; drop to 150 for preview renders. - Page fit. Margins and orientation are honoured; if the board does
not fit, switch
page.orientationto landscape or move toPageSize:: Custom { width_mm, height_mm }. - Debug annotations.
render.debug_annotations = trueoverlays corner IDs and cell indices — useful for visual sanity checks before printing. - Print at 100 %. All downstream detectors assume the printed
dimensions match
square_size_mm. Scale-to-fit in a print dialog will silently break calibration.
Hardware handoff (DXF)
Every bundle additionally writes a <stem>.dxf alongside the JSON /
SVG / PNG. The DXF is tuned for chrome-on-glass photolithography
producers:
- AutoCAD R2000 ASCII (
AC1015),$INSUNITS = 4(mm), 6-decimal coordinates (1 nm precision). - Y-up cartesian, origin at the bottom-left of the page — what LibreCAD, KLayout, FreeCAD, and CAM350 read by default.
- Single layer
PATTERN(color 7) carrying only theFill::Blackregions of the scene — these are the chrome features for a typical chrome-on-glass workflow. Debug annotations never reach the DXF, even whenrender.debug_annotations = true. - Rectangles emit as closed
LWPOLYLINEs with 4 vertices; circles emit as nativeCIRCLEentities (no polygonal approximation). - Polarity inversion, board outline, fiducials, and traceability text are intentionally absent — confirm with the producer whether they need the chrome or clear side and add downstream.
The DXF output is deterministic and covered by a golden-snapshot regression test.
Limitations
- No PDF. Convert from SVG if needed.
- Single target per document. No tiling of multiple boards on one page.
- Deterministic render. No randomisation seed; identical input produces identical output.
- DXF carries pattern only. No board outline, registration fiducials, or traceability text — add downstream or open a ticket if your producer needs them in-file.
Facade vs this crate
The workspace facade [calib-targets] re-exports this crate as
calib_targets::printable, so detection-code users typically
use calib_targets::printable::... rather than depending on
calib-targets-print directly.
Related
- Book: printable targets — canonical guide
- Book: getting started
- CLI —
cargo install calib-targets(Rust binary) orpip install calib-targets(Python console script) ships acalib-targets gen {chessboard,charuco,puzzleboard,marker-board}workflow backed by this crate