Planar Intrinsics with Real Data
[COLLAB] This chapter requires user collaboration for dataset-specific details, data collection advice, and practical tips.
This chapter walks through the planar_real example, which calibrates a camera from real chessboard images.
Dataset
The example uses images from data/stereo/imgs/leftcamera/:
- Pattern: 7×11 chessboard, 30 mm square size
- Images: Multiple PNG files (
Im_L_*.png) - Camera: Standard industrial camera (specific model TBD)
Workflow
1. Corner Detection
The example uses the chess-corners crate for chessboard detection:
#![allow(unused)] fn main() { use chess_corners::{ChessboardParams, ChessConfig, detect_chessboard}; let board_params = ChessboardParams { rows: 7, cols: 11, square_size: 0.03, // 30 mm }; }
Each image is processed independently. Failed detections are skipped — the workflow continues with the views that succeed.
2. Dataset Construction
Detected corners are assembled into CorrespondenceView structures with matched 3D board points:
#![allow(unused)] fn main() { let views: Vec<View<NoMeta>> = images .iter() .filter_map(|img| { let corners = detect_chessboard(img, &config)?; let obs = CorrespondenceView::new(board_3d.clone(), corners); Some(View::without_meta(obs)) }) .collect(); let dataset = PlanarDataset::new(views)?; }
3. Calibration
The pipeline is identical to the synthetic case:
#![allow(unused)] fn main() { let mut session = CalibrationSession::<PlanarIntrinsicsProblem>::new(); session.set_input(dataset)?; step_init(&mut session, None)?; step_optimize(&mut session, None)?; let export = session.export()?; }
Interpreting Results
Key outputs to examine:
- Focal lengths (, ): Should match the expected value based on sensor size and lens focal length. For a 1/2" sensor with 8mm lens: pixels.
- Principal point (, ): Should be near the image center. Large offsets may indicate a decentered lens.
- Distortion (, ): Negative indicates barrel distortion (common). suggests a wide-angle lens.
- Reprojection error: <1 px is good. >2 px suggests problems with corner detection or insufficient view diversity.
Comparison with Synthetic Data
| Aspect | Synthetic | Real |
|---|---|---|
| Corner accuracy | Exact (no detection noise) | ~0.1-0.5 px (detector dependent) |
| Distortion | Known ground truth | Unknown, estimated |
| View coverage | Controlled | May have gaps |
| Typical reprojection error | <0.01 px | 0.1-1.0 px |
Practical Tips
- Use 15-30 images with diverse viewpoints
- Cover the full image area — points only near the center poorly constrain distortion
- Include tilted views — not just frontal. Rotation around both axes constrains all intrinsic parameters
- Check corner ordering — mismatched 2D-3D correspondences cause calibration failure
- Start with
fix_k3: true— only estimate if reprojection error is high and you suspect higher-order radial distortion
Running the Example
cargo run -p vision-calibration --example planar_real
The example prints per-step results including initialization accuracy, optimization convergence, and final calibrated parameters.