Getting Started

This guide walks through the basics of generating blob patterns and calibration boards.

Installation

With pixi (recommended)

Pixi handles all dependencies (Julia, Python, Ghostscript) automatically:

git clone https://github.com/VisualGeometryToolkit/BlobBoards.jl
cd BlobBoards.jl
pixi install
pixi run julia --project=.

Manual setup

Requirements:

  • Julia 1.12+
  • Ghostscript ≥ 10.07 (writes the PDF/X-4 print master; pixi provides it — distro packages are often older, e.g. Ubuntu 24.04 ships 10.02, which is refused loudly)

Install Ghostscript:

  • Ubuntu/Debian: sudo apt install ghostscript
  • macOS: brew install ghostscript
  • Fedora: sudo dnf install ghostscript
  • Windows: Download from ghostscript.com

Then install Julia packages:

git clone https://github.com/VisualGeometryToolkit/BlobBoards.jl
cd BlobBoards.jl
julia --project=. -e 'using Pkg; Pkg.instantiate()'

Author your first board

Board authoring needs CairoMakie, a weak dependency that the package's own --project=. cannot load. Use the checkout's authoring/ environment:

julia --project=authoring -e 'using Pkg; Pkg.instantiate()'
julia --project=authoring
using BlobBoards, CairoMakiebundle = blob_board("A4", 300dpi; seed = 0xBEEF, dir = "./output")

This writes blob_board_<uid>.pdf (print it at 100%) and its JSON sidecar. The Authoring a Board guide covers the environment, sizes, frames and rulers, output formats and printing; blob_board lists every keyword.

Detect boards and estimate pose

find_boards finds known boards in an image and returns each one's homography or pose. See Detection and Pose.

Generating Patterns Only

For training data or custom layouts, generate just the pattern:

using BlobBoardsusing VisualGeometryCore: px# Generate a 800x600 pixel patternpattern, blobs, config = blob_pattern(800, 600; blob_sizes=(12px, nothing), seed=0x1234)# Save to diskpattern, blobs, config = blob_pattern(800, 600; blob_sizes=(12px, nothing), dir="./output")

Extracting Blob Coordinates

From Board Files

bundle, image = load("blob_board.json")# Physical coordinates (mm) relative to pattern originb = blobs(bundle, :pattern; units=mm)# Physical coordinates relative to board origin (includes frame)b = blobs(bundle, :board; units=mm)# Pixel coordinates (COLMAP convention, convert as needed)b = blobs(bundle, :pattern)

From Pattern Files

bundle = load("blob_pattern.json")# Pixel coordinates (COLMAP convention)b = blobs(bundle)

World Coordinates for 3D Calibration

bundle, image = load("blob_board.json")# Get blobs in world frame (centered, y-up, unitless mm)world = blobs(bundle, :world)# Lift to 3D points on z=0 planeusing GeometryBasics: Point3X = [Point3(b.center..., 0.0) for b in blobs]

Loading Saved Boards

# Load from any paired file (JSON, PNG, or PDF)bundle, image = load("blob_board_abc_12345.json")bundle, image = load("blob_board_abc_12345.pdf")# Access configurationconfig = pattern_config(bundle)board = board_config(bundle)

Available Paper Sizes

Standard sizes include:

ISOANSICommon Names
A0-A5ANSI A-E1Letter, Legal
Tabloid, Ledger
# List all available sizeskeys(BlobBoards.PRINT_SIZES)

Next Steps