-
Notifications
You must be signed in to change notification settings - Fork 0
Calibration algorithm
Let
The registration step establishes two mappings for the behavior camera:
- Stage + pixel position → physical position:
$f_b:\ (x_t, y_t, r_b, c_b) \rightarrow (x_p, y_p)$ - Stage + physical position → pixel position:
$g_b:\ (x_t, y_t, x_p, y_p) \rightarrow (r_b, c_b)$
-
Arena spec. The arena PDF (
arena146_spec.pdf) encodes the physical (arena-space) positions of all AprilTag corners and the DataMatrix barcode center, in mm.ArenaConfigparses this and writesmetadata.yaml. -
Mapping board.
make_arena146_config.pygenerates a printable PDF (mapping_board.pdf) with AprilTag markers at the locations encoded in the spec, plus a DataMatrix barcode encoding an 8-character checksum of the full spec. The board is placed in the arena during the scan. -
Registration scan.
run-arena-registration-scanperforms the following:- Decodes the DataMatrix to verify the correct board is in place (checksum must match
metadata.yaml). - Computes the stage-to-arena offset from the stage position when the camera is centred on the DataMatrix.
- Moves the stage to each AprilTag's centre, acquires 10 consecutive frames, and records the stage position. Output:
mapping_scan/apriltag<id>_img<i>.jpgandapriltag_stage_positions.csv.
- Decodes the DataMatrix to verify the correct board is in place (checksum must match
-
Detection.
fit-arena-registrationdetects AprilTag corners in each image usingpupil_apriltags. Each detected corner gives a tuple$(x_t, y_t, r_b, c_b, x_p, y_p)$ where$(x_p, y_p)$ is known frommetadata.yaml. -
Outlier rejection. Within-burst outliers (the 10 frames per tag are near-identical because the stage is stationary) are removed by MAD filtering per (tag, corner) group. Overall outliers are then removed by RANSAC.
-
Linear fit. We assume the mapping is affine linear. For
$f_b$ , we fit$A_{f_b} \in \mathbb{R}^{2 \times 5}$ such that:
Two separate RANSAC regressors are fit (one per axis); only combined inliers are used for the final least-squares estimate.
-
Inverse.
$g_b$ (stage + physical → pixel) is derived analytically by partially inverting$A_{f_b}$ (the pixel block is$2 \times 2$ and thus invertible). Both matrices are saved incalibration_result.yamlin the YAML schema read byCalibrationParamsin the C++ recorder.
A good registration fit has:
- RMSE ≲ 0.1 mm (euclidean)
- R² ≈ 1.0 on both axes
- Very few RANSAC outliers (< 5%)
Check model/diagnostics.png after fitting to visually verify the residual distribution and spatial pattern.
The previous pipeline used an ArUco board scanned on a dense grid, detected with OpenCV, and fitted per-camera. The current pipeline uses:
- A sparse set of AprilTag markers (8 for arena146) at known positions in the PDF spec.
-
pupil_apriltagsfor detection (more robust than cv2.aruco for tag16h5). - Per-burst MAD filtering to exploit the repeated measurements per tag.
- A DataMatrix checksum to guard against mismatched boards.
- A single behavior-camera model (the muscle camera is aligned via a separate homography calibration if needed).