Coordinate Systems

BlobBoards uses three types of coordinate specifications. Understanding them is essential for correctly extracting and using blob positions.

TypeValuesPurpose
Image Origin:colmap, :opencv, :juliaPixel coordinate convention
Reference Frame:pattern, :board, :canvasSpatial origin on boards
Coordinate System:logical, :physical, :worldUnit system for transforms

Image Origins

Different software uses different conventions for where the "first pixel" is located. BlobBoards stores coordinates internally in :colmap convention.

OriginFirst Pixel CenterCommon Usage
:colmap(0.5, 0.5)COLMAP, SfM tools, BlobBoards internal
:opencv(0, 0)OpenCV, Python, NumPy
:julia(1, 1)Julia arrays, MATLAB

Visual Representation

     :colmap               :opencv               :julia
  corner at (0,0)       corner at (0,0)      corner at (0.5,0.5)
        ↓                     ↓                     ↓
   ┌─────────┐          ┌─────────┐          ┌─────────┐
   │(0.5,0.5)│          │  (0,0)  │          │  (1,1)  │
   │    •    │          │    •    │          │    •    │
   │  pixel  │          │  pixel  │          │  pixel  │
   └─────────┘          └─────────┘          └─────────┘

Converting Between Image Origins

using BlobBoardsusing CoordinateTransformations: Translation# Image-origin conversion is a Translation — composable, callable on points/Discs/blobsT = Translation(:colmap, :opencv)            # Translation(Vec2(-0.5, -0.5) * px)b = blobs(bundle, :pattern)                  # always in :colmap conventionb_opencv = T.(b)                             # shift every blob in placeT = Translation(:colmap, :julia)julia_point = T(colmap_point)# Strip units when composing with plain-Float64 mapsunitless = ustrip(T)

Reference Frames

For calibration boards, three nested reference frames define where the coordinate origin is located.

FrameOrigin LocationUse Case
:patternTop-left of pattern areaBlob detection, feature matching
:boardTop-left of board (includes frame)Full board image processing
:canvasTop-left of page (includes margins)Page layout, printing

Layout Diagram

    ◀──────────────────── canvas_size.width ────────────────────▶

    ┌───────────────────────────────────────────────────────────┐   ▲
    │ ○ :canvas origin                                          │   │
    │  (0,0)                                                    │   │
    │    ┌────────────────────────────────────────────────┐     │   │
    │    │ ○ :board origin                                │     │   │
    │    │  (0,0)                                         │     │   │
    │    │    ┌────────────────────────────────────┐      │     │   │
    │    │    │ ○ :pattern origin                  │      │     │   │
    │    │    │  (0,0)                             │      │     │   │
    │    │    │                                    │      │     │   │
    │◀─▶│◀──▶│        ┌───┐                       │◀────▶│◀───▶│   │
    │ m │ f  │        │ ● │  blob                 │  f   │  m  │   c
    │ a │ r  │        └───┘                       │  r   │  a  │   a
    │ r │ a  │                                    │  a   │  r  │   n
    │ g │ m  │                                    │  m   │  g  │   v
    │ i │ e  │                                    │  e   │  i  │   a
    │ n │    │        pattern_size                │      │  n  │   s
    │   │    │                                    │      │     │   _
    │   │    │                                    │      │     │   s
    │   │    └────────────────────────────────────┘      │     │   i
    │   │    ◀────── pattern_size.width ─────────▶       │     │   z
    │   │                                                │     │   e
    │   └────────────────────────────────────────────────┘     │   .
    │   ◀─────────────  board_size.width  ──────────────▶      │   h
    │                                                          │   e
    └──────────────────────────────────────────────────────────┘   i
                                                                   g
    Legend:                                                        h
    ○ = coordinate origin (top-left corner)                        t
    ● = blob center                                                ▼
    m = margin (canvas edge to board edge)
    f = frame_width (board edge to pattern edge)

Converting Between Reference Frames

bundle, _ = load("blob_board.json")# Get Translation between framesT = Translation(board_config(bundle), :pattern, :board)board_point = T(pattern_point)# Or extract blobs directly in desired frameb_pattern = blobs(bundle, :pattern)b_canvas = blobs(bundle, :canvas)

Coordinate Values Example

For a blob at pattern coordinates (80px, 120px) with frame_width=75px:

FrameBlob Center
:pattern(80px, 120px)
:board(155px, 195px)
:canvas(155px, 195px) (same if no margin)

Coordinate Systems

For transforms between pixel and physical units, use :logical, :physical, and :world:

SystemUnitsDescription
:logicalpxPixel coordinates (requires image_origin)
:physicalmmPhysical coordinates in pattern frame
:worldunitless mmCentered origin, y-axis up

Logical to Physical Transform

bundle, _ = load("blob_board.json")# Get affine transform from pixels to mmH = AffineMap(bundle, :logical, :physical; image_origin=:julia)# Transform a pixel point to physical coordinatesphysical_pt = H(Point2(100.0, 200.0))

Logical to World Transform

# Direct transform from pixels to world frameH = AffineMap(bundle, :logical, :world; image_origin=:opencv)world_pt = H(Point2(100.0, 200.0))

Blob Extraction

Unified API

The blobs function takes a reference frame (positional) and optional units:

bundle, _ = load("blob_board.json")# Pixel units (default) in pattern frameb = blobs(bundle, :pattern)# Pixel units in canvas frameb = blobs(bundle, :canvas)# Physical unitsb = blobs(bundle, :pattern; units=mm)b = blobs(bundle, :canvas; units=inch)

Saddle Points

For boards with checkerboard frames (:saddle style):

# Pixel unitssp = saddle_points(bundle, :pattern)# Physical unitssp = saddle_points(bundle, :pattern; units=mm)

World Coordinates

For 3D calibration (centered origin, y-up, mm):

b = blobs(bundle, :world)# origin at pattern center# x-axis right, y-axis up# units: mm (stripped to Float64)# Lift to 3D points on z=0 planeusing GeometryBasics: Point3X = Point3.(vcat.(centroid.(b), 0.0))

Bounding Rectangles

Get rectangles for different regions:

using GeometryBasics: Rectbundle, _ = load("blob_board.json")# Pattern bounds (origin at 0,0)rect = Rect(bundle, :pattern)# Board bounds (extends into negative in pattern coords)rect = Rect(bundle, :board)# rect.origin = (-frame_width, -frame_width) in pattern frame

Common Workflows

Feature Detection Pipeline

bundle, image = load("blob_board.json")# Detect blobs (your detector returns OpenCV convention)detected = detect_blobs(image)# Get ground truth, convert to OpenCV conventiongt = blobs(bundle, :canvas)gt_opencv = Translation(:colmap, :opencv).(gt)# Match and evaluatematches = match_blobs(detected, gt_opencv)

Camera Calibration

bundle, image = load("blob_board.json")# Get 3D points (world frame, z=0)b = blobs(bundle, :world)X = Point3.(vcat.(centroid.(b), 0.0))# Get 2D image points (from detection)x = detect_and_match(image, b)# Estimate camera posecamera = estimate_pose(X, x)

Unit Conversions

Convert between physical and logical units:

using BlobBoards                     # re-exports mm, px, dpiusing VisualGeometryCore: uconvertusing GeometryBasics: Point2bundle, _ = BlobBoards.load("blob_board.json")config = board_config(bundle)print_density = config.print_density  # e.g., 300 dpi# Use helper functionsscale = px_per_mm(print_density)  # pixels per mmscale = mm_per_px(print_density)  # mm per pixel (with units)# Physical to logicalphysical_point = Point2(10.0mm, 20.0mm)logical_point = uconvert.(px, physical_point .* print_density)# Logical to physicallogical_point = Point2(100.0px, 200.0px)physical_point = uconvert.(mm, logical_point ./ print_density)

Summary Table

WhatKeyword/ArgumentValuesDefault
Pixel conventionimage_origin (keyword):colmap, :opencv, :julia:colmap (internal)
Spatial originreference frame (positional):pattern, :board, :canvasrequired
Unit systemunits (keyword)px, mm, inch, etc.px