StereoComplex

Getting started

  • Start Here
    • Recommended first step
    • Installation
    • Which path should I use?
    • What StereoComplex does today
    • Main validated results
      • OpenCV-compatible calibration improvement
      • Non-central rendered-image benchmark
      • Real CMO microscope case study
    • Notebook walkthroughs
    • Quickstart for your own stereo folders
    • Quickstart for the versioned synthetic dataset
    • Documentation map
    • Next steps
  • Tutorial: From zero to CMO calibration in 15 minutes
    • 1. Installation (2 minutes)
    • 2. Calibrate a standard stereo rig with OpenCV (3 minutes)
    • 3. Move to a central 3D ray‑field (3 minutes)
    • 4. Detect non‑centrality with a Zernike rayfield (5 minutes)
    • 5. Identify the physical optics (2 minutes)
    • 6. Build a compact CMO model (with real data)
    • Where to go next
  • From OpenCV to StereoComplex
    • 3-minute quickstart
    • Translation table
    • What you gain
    • Next steps
    • See also
  • Bring your own data
    • What you need
    • Minimal calibration from two folders
      • Option A: stay in OpenCV and compare raw vs Ray2D
      • Option B: fit the StereoComplex 3D backend
      • Option C: fit a non-central rayfield (validated on real CMO)
    • Later: load and triangulate
    • If you already have a dataset v0 scene
    • If you only want to improve OpenCV corners
    • Practical notes
    • Recommended first experiment
  • Fix my calibration (OpenCV + ChArUco)
    • Fast path on your own images
    • Step 1 — Export refined 2D corners
    • Step 2 — Calibrate with OpenCV (example)
    • What to do on real data?
  • Notebook walkthroughs
    • Open in Colab
    • Recommended reading order
      • A. Onboarding
      • B. Central rayfield and reconstruction
      • C. Non-central and physical model identification
      • D. Real-data case study
    • What to look for
      • 00 Getting started — from OpenCV to StereoComplex
      • 01 Ray2D vs OpenCV
      • 02 Ray3D
      • 03 Virtual rectification
      • 04 Parallel plate origin field
      • 05 Non-central calibration from images
      • 06 CMO model selection
      • 07 Model selection classification matrix
      • 08 Direct vs rayfield-mediated inversion (Synthèse)
      • 09 Pycaso real data — validation on a real CMO microscope
    • Open locally

ChArUco and 2D ray-field

  • ChArUco: 2D identification strategy (baseline)
    • Error measurement
    • Pixel-center convention (important)
    • Available methods (CLI --method)
      • 1) charuco (direct OpenCV)
      • 2) homography (2nd-pass planar geometry)
      • 3) pnp (2nd-pass parametric K + distortion)
      • 4) rayfield (2nd-pass non-parametric “smoothed field” on the board plane)
      • 4b) rayfield_tps and rayfield_tps_robust (recommended in this repo)
      • 4c) hessian_barycentre — subpixel refinement via the Hessian structure tensor
        • Mathematics
        • Otsu thresholding
        • Subpixel barycentre
        • Integration with Ray2D TPS
        • When to use
        • Limitations
      • 5) kfield (a “local K” field approximated by smoothed affines)
        • Linearization (Jacobian)
        • Construction (what the code does)
    • Assumptions per method (what it “assumes”)
    • Photometric refinements (CLI --refine)
    • Current recommendation
    • Paper comparison (reproducible script)
    • Worked example (raw OpenCV vs ray-field + plots)
  • Worked example: raw OpenCV ChArUco vs a ray-field second pass (errors + plots)
    • Prerequisites
    • Expected data
    • Theory recap: a planar ray-field (a non-parametric warp on the board plane)
      • Why a homography is a good base (planar board)
      • Distortion/aberrations: what a homography cannot explain
      • Estimation objective (data term + regularization)
      • Available measurements (ArUco)
      • Why this can reduce uncertainty without an optical model
      • Why not “just Gaussian blur the residuals”?
      • TPS variant (thin-plate splines) for residual reconstruction
      • What this corrects (and what it does not)
      • Important notes (what this “ray-field” is not)
    • Pipeline: what the example actually does
      • Where is the code?
      • Coordinate convention (important)
    • Running the example
    • Plots (examples)
      • ECDF (cumulative distribution of error)
      • Histograms
      • Sensitivity to \(\lambda\) (TPS)
      • Visualizing aberrations (residual amplitude)
      • Overlays (visual sanity checks)
      • Ideal vs realistic (why GT may look “off”)
        • Photometric bias at checkerboard corners
      • Micro-overlays (sub-pixel readability)
    • How to interpret results
    • Extensions (suggested exercises)
    • References (bibliography pointers)

Ray-based calibration and 3D

  • Stereo 3D reconstruction (OpenCV) and the impact of the ray-field
    • Why is this surprising on a pinhole dataset?
    • Evaluated pipeline
      • Used views (important)
      • Runtime (order of magnitude)
    • “Baseline error” in pixels (disparity-equivalent)
    • Reproducible script
    • Results (example)
      • Intrinsics and distortion vs GT (%)
      • Rectification: epipolar stability (vertical disparity)
      • Discussion: epipolar stability vs “parameter truth”
    • Theory: from baseline to ray intersection
      • 1) Two 3D rays associated with a 2D correspondence
      • 2) The practical case: skew lines
      • 3) Epipolar constraint and the role of the baseline
      • 4) Why this matters for robotics and stereo-DIC
      • Metric definitions (table columns)
      • Interpreting triangulation (mm) vs working distance
  • Reconstruction API (load model, triangulate points, optional image maps)
    • File format: model.json + weights.npz
    • API: load + triangulate
    • End-to-end demo on a dataset scene
      • Prerequisites
      • 1) Calibrate + export a reusable model (public API)
      • 2) Apply the model (reconstruction on detected corners)
    • The same workflow on your own folders
    • Code references
  • 3D ray-field (central) and ray-based calibration
    • What this enables (and what it does not)
    • Conventions and data
    • Central 3D ray-field model
    • Zernike basis (unit disk)
    • Part A — GT fit (ridge / Tikhonov regression)
    • Triangulation and metrics
    • Pinhole “oracle” baseline (reference)
    • Full GT example and comparison
      • Metrics (mm, px, %)
    • Code references
    • Part B — From images: detection + 2D ray-field, then reconstruction (GT-assisted)
      • Script
      • Results (example)
    • Compression stress-test (PNG lossless vs WebP lossy)
    • Part C — Ray-based calibration (no GT 3D): point↔ray bundle adjustment
      • Connection to the general imaging model (non-central cameras)
      • Geometric residual
      • Joint optimization (stereo)
      • Script (images → 2D ray-field → 3D ray-field bundle adjustment → stereo)
      • Results (example)
      • Discussion: (i) baseline, (ii) reprojection, (iii) triangulation
      • Discussion: why the ray-field calibration needs an “aligned” comparison
    • Post-hoc pinhole identification from the ray-field 3D reconstruction
    • Usage after identification (robotics / stereo-DIC)
      • Minimal inputs/outputs
      • Per-point computation and algorithmic cost
      • Real-time pipeline (robotics)
      • Two-time pipeline (stereo-DIC)
      • Model size (“parameter complexity”)
      • Code references
  • Virtual rectification for dense stereo
    • Drop-in workflow (pinhole-compatible)
    • Implementation overview (maps for cv2.remap)
    • End-to-end example
    • Visual sanity check (synthetic pinhole)
    • Notes and limits

Non-central and optical models

  • Non-central stereo calibration from image folders
    • What this fits
    • Minimal example
    • When to use this path
    • Reading the result
    • Status and limitations
    • Relation to Ray2D
  • Identify My Optics
    • Short version
    • Prerequisites
    • Mental model
    • Direct geometric reading from the rayfield
      • Step 1: read the sub-pupil positions
      • Step 2: read the sub-pupil depth
      • Step 3: read the working distance
      • Step 4: read the convergence angle
      • Step 5: compare across the field of view
      • Example: Pycaso CMO microscope
    • Read The Report Like An Engineer
    • Mathematical model catalogue
      • Common stereo geometry
      • Ray-space comparison
      • Candidate 0: central pinhole stereo
      • Candidate 1: central Brown-Conrady stereo
      • Candidate 2: pinhole stereo plus inclined parallel plates
      • Candidate 3: non-central polynomial surrogate channels
      • Candidate 4: physical CMO stereo model
      • Scientific background for the polynomial surrogate
      • Information criteria
    • Minimum example
    • How to read the report
    • Example result on the inclined-plate oracle
    • Adding a custom candidate model
    • Pitfalls
  • Optical model selection — CMO workflow and classification matrix
    • Why this is a separate notebook
    • ChArUco target policy
    • Shared physics: true CMO generation and CMO fitting
    • Generic Zernike rayfield measurement
    • Ray-space candidate models
    • Per-channel diagnostic selection
    • Complete rayfield fit: physical CMO vs polynomial surrogate
    • Notebook 06 interpretation
    • Full classification matrix
      • Three noise regimes
      • Key insight: graceful degradation
    • Current limitations
  • Rayfield mediation: separating measurement from optical interpretation
    • Why this page exists
    • The two inverse problems
      • Direct fitting — an estimator for a known model
      • Rayfield mediation — a diagnostic layer for model selection
    • Nuisance parameters and conditioning
    • What the current experiments show
      • Link to the model-selection benchmark
      • Direct fitting baseline (6-oracle sweep)
      • End-to-end ChArUco → Zernike → selection (notebook 08)
    • When to use which strategy
    • Infrastructure
    • Limitations
    • See also
  • Cahier des charges — Direct vs Rayfield-mediated inversion
  • Inclined parallel-plate oracle and Zernike origin-field identification
    • Why the central model should fail here
    • Theory: inclined parallel plate as an oracle
    • Theory: canonical origin field
    • Theory: direction field
    • Theory: fitting objective
    • Implementation details of the complete non-central BA
      • Frames and residuals
      • Objective and robust loss
      • Initialization and benchmark parameters
    • From geometric observations to image-based identification
    • Theory: reconstruction comparison
    • Reproduce
    • Reconstruction results
    • From measured rayfield to physical model: fitting a thin parallel plate
    • Ray-field comparison against the oracle
    • Stereo ray consistency
    • Rendered-image front-end
    • Generalization: held-out pose validation
    • Interpretation

Real-data CMO case study

  • Real CMO microscope calibration on Pycaso data
    • A rayfield-based case study with legacy ChArUco images
      • What this page is about, in one paragraph
      • What we measured
      • What this case study claims, and what it does not
    • Claims and evidence
    • What this case study does not evaluate
    • The dataset
    • Pipeline
      • The double TPS pass
      • Error metric
    • Step-by-step: from rayfield to physical model
      • Step 1 — The Zernike rayfield as observable
      • Step 2 — Perspective CMO: the baseline hypothesis
      • Step 3 — Telecentric CMO: matching the observed structure
      • Step 4 — Residual analysis: what is the model still missing?
      • Step 5 — Testing alternative hypotheses
      • Step 6 — SE(3) arm alignment: the breakthrough
      • Step 6b — Ablation: which SE(3) parameters are essential?
      • Step 7 — Autopsy of the 26p model and BIC model selection
      • Step 8 — Why the residual analysis was decisive
      • Step 9 — Direct corner refinement: how good is the rayfield initialisation?
    • The Ray2D → Ray3D feedback loop
    • Limitations
    • Methodology recap: the generalisable workflow
    • Stabilising the direct BA with a Schur-complement prior
      • The problem: pose–intrinsic coupling
      • The prior
      • Validation on the 2-cent coin specimen
      • Schur vs isotropic sweep
      • Interpretation
    • Saved artefacts
    • See also
  • Physical CMO Model
    • Optical Assumption
    • Parameters
    • Ray Construction
      • Effective vs physical distortion
    • Identifiability
    • Relation To The Polynomial Surrogate
    • Real microscope mapping
      • Physical CMO shared-rig model
      • Non-central polynomial surrogate
      • Decision flow
    • References
  • Pycaso-style depth sweep vs 3D ray-field
    • Soloff direct vs Soloff LM (LM identification)
    • Dataset: board slides in Z only
    • Benchmark protocol
    • Impact of rayfield_tps_robust pre-refinement
    • Results: Pycaso vs 3D ray-field
    • Compression stress test (lossy JPEG/WebP)
    • Pycaso example images (real): OpenCV ChArUco configuration
      • Board parameters
      • OpenCV ≥ 4.7 (CharucoDetector) note
    • Artefacts

Validation and benchmarks

  • Validation status
    • Test status
    • Reproducibility
  • Image compression and 3D reconstruction
    • Experimental design
      • Metrics
    • Codec quality sweep (WebP + JPEG)
      • Baseline error (px @ mean depth)
      • Stereo RMS reprojection (OpenCV)
      • Triangulation error (RMS, % mean depth)
    • Key finding: 3D ray-field is remarkably stable under compression
    • Discussion: why can compression sometimes “help” OpenCV, yet remain unstable?
    • Quantitative uncertainty comparison (planar-refined pinhole vs ray-field)
      • Why the 3D ray-field stays stable
  • Robustness sweep (board size, focal length, aberrations)
    • Sweep design
    • Results summary (18 cases)
    • Practical conclusion
    • Pinhole identification from ray-field 3D reconstruction (status)
    • Reproduce
    • Compression stress test (Pycaso vs 3D ray-field)
    • Z-sweep benchmark (ray-plane renderer + Pycaso-style throughput)
  • Roadmap — StereoComplex user-facing API
    • Current state (v0.5.x)
    • Phase 1 — OpenCV-user façade (~1 day)
      • 1a. compare_opencv_stereo_calibration()
      • 1b. “From OpenCV to StereoComplex” page
      • 1c. Shorter function aliases
      • 1d. Result export methods
    • Phase 2 — Quality gate (~0.5 day)
      • 2a. assess_calibration(result)
      • 2b. result.report.warnings and result.report.recommendations
    • Phase 3 — API surface cleanup (~0.5 day)
      • 3a. Tiered public API
      • 3b. Usage-oriented function index
    • Phase 4 — Notebook walkthrough (~0.5 day)
      • 4a. 00_getting_started.py
      • 4b. Link from README
    • Phase 5 — Packaging and CI polish (~0.5 day)
    • Effort estimate
    • Out of scope for this roadmap

Reference

  • API reference
    • Physical optical models — stereocomplex.physics
      • BrownConrady
        • BrownConrady.distort()
        • BrownConrady.undistort()
      • CMOChannelRayField
        • CMOChannelRayField.channel
        • CMOChannelRayField.common_aberration
        • CMOChannelRayField.name
        • CMOChannelRayField.from_parameter_vector()
        • CMOChannelRayField.n_parameters
        • CMOChannelRayField.parameter_dict()
        • CMOChannelRayField.parameter_vector()
        • CMOChannelRayField.ray()
      • CMOChannelSpec
        • CMOChannelSpec.name
        • CMOChannelSpec.intrinsics
        • CMOChannelSpec.origin_world_mm
        • CMOChannelSpec.R_cam_to_world
        • CMOChannelSpec.distortion
        • CMOChannelSpec.differential_aberration
        • CMOChannelSpec.sensor_warp
        • CMOChannelSpec.vignetting
        • CMOChannelSpec.origin
      • CMOIntrinsics
        • CMOIntrinsics.as_K()
        • CMOIntrinsics.from_focal_and_pitch()
        • CMOIntrinsics.norm_to_pixel()
        • CMOIntrinsics.pixel_grid()
        • CMOIntrinsics.pixel_to_norm()
      • CMOPhysicalChannelModel
        • CMOPhysicalChannelModel.from_parameter_vector()
        • CMOPhysicalChannelModel.n_parameters
        • CMOPhysicalChannelModel.parameter_dict()
        • CMOPhysicalChannelModel.parameter_vector()
        • CMOPhysicalChannelModel.project_point()
        • CMOPhysicalChannelModel.ray()
      • CMOPhysicalStereoFitResult
      • CMOPhysicalStereoModel
        • CMOPhysicalStereoModel.channel()
        • CMOPhysicalStereoModel.flat_parameter_dict()
        • CMOPhysicalStereoModel.from_parameter_vector()
        • CMOPhysicalStereoModel.n_parameters
        • CMOPhysicalStereoModel.parameter_dict()
        • CMOPhysicalStereoModel.parameter_vector()
        • CMOPhysicalStereoModel.principal_point_for_channel()
        • CMOPhysicalStereoModel.ray()
      • CMOPlanePose
        • CMOPlanePose.R
        • CMOPlanePose.t
        • CMOPlanePose.local_to_world()
        • CMOPlanePose.normal_world
        • CMOPlanePose.world_to_local()
      • CMOPlaneTargetSpec
        • CMOPlaneTargetSpec.square_size_mm
        • CMOPlaneTargetSpec.pixels_per_square
        • CMOPlaneTargetSpec.pattern
        • CMOPlaneTargetSpec.marker_size_ratio
        • CMOPlaneTargetSpec.height_mm
        • CMOPlaneTargetSpec.inner_corners_local_mm()
        • CMOPlaneTargetSpec.make_texture_u8()
        • CMOPlaneTargetSpec.width_mm
      • CMORayfieldBundleAdjustmentResult
        • CMORayfieldBundleAdjustmentResult.poses
        • CMORayfieldBundleAdjustmentResult.success
        • CMORayfieldBundleAdjustmentResult.message
        • CMORayfieldBundleAdjustmentResult.n_observations
        • CMORayfieldBundleAdjustmentResult.parameter_vector
        • CMORayfieldBundleAdjustmentResult.pose_vectors
        • CMORayfieldBundleAdjustmentResult.parameter_summary()
      • CMOStereoSpec
        • CMOStereoSpec.common_aberration
        • CMOStereoSpec.channels()
        • CMOStereoSpec.symmetric_default()
      • CMOTelecentricChannelModel
        • CMOTelecentricChannelModel.from_parameter_vector()
        • CMOTelecentricChannelModel.n_parameters
        • CMOTelecentricChannelModel.parameter_dict()
        • CMOTelecentricChannelModel.parameter_vector()
        • CMOTelecentricChannelModel.ray()
      • CMOTelecentricNModel
        • CMOTelecentricNModel.channel()
        • CMOTelecentricNModel.channel_names
        • CMOTelecentricNModel.from_stereo()
        • CMOTelecentricNModel.n_channels
        • CMOTelecentricNModel.n_parameters
        • CMOTelecentricNModel.ray()
      • CMOTelecentricStereoModel
        • CMOTelecentricStereoModel.channel()
        • CMOTelecentricStereoModel.from_parameter_vector()
        • CMOTelecentricStereoModel.n_parameters
        • CMOTelecentricStereoModel.parameter_dict()
        • CMOTelecentricStereoModel.parameter_vector()
        • CMOTelecentricStereoModel.ray()
      • CMOWarpedChannelModel
        • CMOWarpedChannelModel.from_parameter_vector()
        • CMOWarpedChannelModel.n_parameters
        • CMOWarpedChannelModel.parameter_dict()
        • CMOWarpedChannelModel.parameter_vector()
        • CMOWarpedChannelModel.ray()
      • CMOWarpedStereoModel
        • CMOWarpedStereoModel.channel()
        • CMOWarpedStereoModel.from_parameter_vector()
        • CMOWarpedStereoModel.n_parameters
        • CMOWarpedStereoModel.parameter_dict()
        • CMOWarpedStereoModel.parameter_vector()
        • CMOWarpedStereoModel.ray()
      • CentralBrownConradyModel
        • CentralBrownConradyModel.from_parameter_vector()
        • CentralBrownConradyModel.n_parameters
        • CentralBrownConradyModel.parameter_dict()
        • CentralBrownConradyModel.parameter_vector()
        • CentralBrownConradyModel.project_point()
        • CentralBrownConradyModel.ray()
      • CentralPinholeModel
        • CentralPinholeModel.from_parameter_vector()
        • CentralPinholeModel.n_parameters
        • CentralPinholeModel.parameter_dict()
        • CentralPinholeModel.parameter_vector()
        • CentralPinholeModel.project_point()
        • CentralPinholeModel.ray()
      • MultiChannelOpticalModelSelectionReport
        • MultiChannelOpticalModelSelectionReport.channel_names
        • MultiChannelOpticalModelSelectionReport.n_channels
        • MultiChannelOpticalModelSelectionReport.rows()
      • NonCentralPolynomialChannelModel
        • NonCentralPolynomialChannelModel.default_terms()
        • NonCentralPolynomialChannelModel.from_parameter_vector()
        • NonCentralPolynomialChannelModel.n_parameters
        • NonCentralPolynomialChannelModel.parameter_dict()
        • NonCentralPolynomialChannelModel.parameter_vector()
        • NonCentralPolynomialChannelModel.ray()
      • OpticalModelSelectionReport
        • OpticalModelSelectionReport.rows()
      • ParallelPlateFromRayfieldFitResult
      • PhysicalModelFitResult
      • PhysicalModelSpec
      • PinholeParallelPlateFitParams
      • PinholeParallelPlateModel
        • PinholeParallelPlateModel.from_parameter_vector()
        • PinholeParallelPlateModel.n_parameters
        • PinholeParallelPlateModel.parameter_dict()
        • PinholeParallelPlateModel.parameter_vector()
      • PinholeParallelPlateRayField
        • PinholeParallelPlateRayField.ray()
      • PolynomialRayAberration
        • PolynomialRayAberration.add()
        • PolynomialRayAberration.delta()
      • SensorWarp
        • SensorWarp.delta_px()
      • Vignetting
        • Vignetting.strength
        • Vignetting.floor
        • Vignetting.gain()
      • aggregate_model_selection_reports()
      • apply_blur_noise()
      • apply_sensor_warp()
      • brown_conrady_distort_normalized()
      • compute_cmo_zernike_residuals()
      • default_physical_model_specs()
      • fit_cmo_physical_stereo_model_to_rayfields()
      • fit_cmo_stereo_model_and_poses_from_zernike_rayfields()
      • fit_cmo_telecentric_model_to_rayfields()
      • fit_cmo_warped_model_to_rayfields()
      • fit_parallel_plate_to_zernike_rayfield()
      • fit_physical_model_to_rayfield()
      • generate_cmo_plane_dataset()
      • intersect_ray_with_z_plane()
      • intersect_rays_with_plane()
      • make_reference_cmo_scenario()
      • normalize_vectors()
      • pinhole_parallel_plate_ray_from_pixel()
      • polynomial_channel_parameters_from_spec()
      • pose_from_euler_xyz()
      • project_cmo_points()
      • project_cmo_points_approx()
      • project_cmo_target_corners()
      • rayfield_two_plane_residuals()
      • rays_from_cmo_pixels()
      • render_cmo_channel_image()
      • reprojection_guard_penalty()
      • rotx()
      • roty()
      • rotz()
      • sample_cmo_target_texture()
      • save_gray()
      • select_physical_model_from_rayfield()
      • undistort_brown_normalized()
      • usable_bic()
    • Zernike rayfields — stereocomplex.rayfields
      • MultiCameraZernikeRayField
        • MultiCameraZernikeRayField.channels
        • MultiCameraZernikeRayField.channel()
        • MultiCameraZernikeRayField.from_camera_configs()
        • MultiCameraZernikeRayField.from_fields()
        • MultiCameraZernikeRayField.n_channels
        • MultiCameraZernikeRayField.names
        • MultiCameraZernikeRayField.ray()
      • ZernikeCandidate
        • ZernikeCandidate.from_parameter_vector()
        • ZernikeCandidate.n_parameters
        • ZernikeCandidate.parameter_dict()
        • ZernikeCandidate.parameter_vector()
        • ZernikeCandidate.ray()
      • ZernikeOriginField
        • ZernikeOriginField.basis()
        • ZernikeOriginField.coeffs
        • ZernikeOriginField.direction()
        • ZernikeOriginField.origin()
        • ZernikeOriginField.raw_origin()
        • ZernikeOriginField.ray()
      • ZernikeOriginFieldCoefficients
        • ZernikeOriginFieldCoefficients.coeffs
      • ZernikeOriginFieldConfig
        • ZernikeOriginFieldConfig.image_size
        • ZernikeOriginFieldConfig.max_order
        • ZernikeOriginFieldConfig.normalization
        • ZernikeOriginFieldConfig.enforce_transverse_gauge
        • ZernikeOriginFieldConfig.modes()
      • ZernikeRayField
        • ZernikeRayField.direction()
        • ZernikeRayField.direction_coeffs
        • ZernikeRayField.direction_delta()
        • ZernikeRayField.origin_coeffs
      • ZernikeRayFieldChannel
        • ZernikeRayFieldChannel.name
        • ZernikeRayFieldChannel.field
      • ZernikeRayFieldCoefficients
    • Synthetic datasets — stereocomplex.synthetic
      • ParallelPlateImageRenderParams
      • ParallelPlateSyntheticParams
      • RenderedParallelPlateImageDataset
      • SyntheticStereoDataset
        • SyntheticStereoDataset.T_right_left
        • SyntheticStereoDataset.oracle_left_ray_function
        • SyntheticStereoDataset.oracle_right_ray_function
        • SyntheticStereoDataset.subset()
      • charuco_inner_corners_object_points()
      • detected_observations_from_rendered_parallel_plate()
      • generate_parallel_plate_stereo_dataset()
      • normal_from_tilts()
      • parallel_plate_ray_from_pixel()
      • pinhole_ray_from_pixel()
      • project_point_with_parallel_plate()
      • render_parallel_plate_charuco_images()
    • Calibration, refinement and I/O — stereocomplex.api
      • BenchmarkReport
      • CalibrationAssessment
        • CalibrationAssessment.status
        • CalibrationAssessment.messages
        • CalibrationAssessment.recommendations
      • CameraSetup
      • CharucoBoardSpec
        • CharucoBoardSpec.from_dict()
        • CharucoBoardSpec.from_meta()
      • NCameraCalibrationResult
        • NCameraCalibrationResult.n_channels
      • OracleReconstructionFloorReport
      • RayfieldComparisonReport
        • RayfieldComparisonReport.plane_intersection_rms
        • RayfieldComparisonReport.plane_intersection_median
        • RayfieldComparisonReport.plane_intersection_p95
        • RayfieldComparisonReport.direction_angle_rms_deg
        • RayfieldComparisonReport.n_samples
      • ReconstructionComparisonReport
      • ReconstructionErrorReport
      • ReconstructionResult
      • RenderedImageBenchmarkReport
      • StereoCentralRayFieldFitReport
      • StereoCentralRayFieldFitResult
      • StereoCentralRayFieldModel
        • StereoCentralRayFieldModel.R_RL
        • StereoCentralRayFieldModel.t_RL
        • StereoCentralRayFieldModel.C_L_mm
        • StereoCentralRayFieldModel.C_R_in_L_mm
        • StereoCentralRayFieldModel.from_coeffs()
        • StereoCentralRayFieldModel.ray_direction_maps()
        • StereoCentralRayFieldModel.triangulate()
      • StereoImagePair
      • StereoOpenCVCalibrationReport
      • StereoOpenCVCalibrationResult
        • StereoOpenCVCalibrationResult.to_dict()
        • StereoOpenCVCalibrationResult.to_opencv()
      • StereoZernikeOriginFieldFitResult
      • assess_calibration()
      • build_charuco_board()
      • calibrate()
      • compare_3d_reconstruction_with_without_origin_field()
      • compare_opencv_stereo_calibration()
      • compare_rayfields_on_planes()
      • detect_charuco_corners()
      • fit_opencv_stereo_from_dataset()
      • fit_opencv_stereo_from_image_dirs()
      • fit_opencv_stereo_from_image_pairs()
      • fit_stereo_central_rayfield_from_dataset()
      • fit_stereo_central_rayfield_from_image_dirs()
      • fit_stereo_central_rayfield_from_image_pairs()
      • fit_stereo_zernike_origin_field()
      • fit_stereo_zernike_origin_field_from_image_dirs()
      • intersect_rays_with_z_plane()
      • load_stereo_central_rayfield()
      • make_default_parallel_plate_charuco_board()
      • make_default_parallel_plate_charuco_dataset()
      • make_default_parallel_plate_dataset()
      • make_parallel_plate_wide_coverage_dataset()
      • oracle_reconstruction_floor_report()
      • reconstruct_points_central_stereo()
      • reconstruct_points_with_origin_fields()
      • reconstruct_points_with_parallel_plate_oracle()
      • reconstruction_error_report()
      • refine_charuco_corners()
      • run_parallel_plate_origin_field_benchmark()
      • run_parallel_plate_rendered_image_benchmark()
      • save_stereo_central_rayfield()
      • triangulate_two_rays()
  • Public API contract
    • Stability promise
    • Recommended user-facing API
    • Sub-namespaces
    • Example
    • Calibrate from your own images
      • Standard OpenCV stereo, raw vs Ray2D
      • StereoComplex 3D ray-field calibration
      • Experimental non-central calibration from image directories
      • Experimental physical plate fit from a measured rayfield
    • Optical model identification
    • Corner refinement API
    • Experimental non-central rayfield API
    • Public method2d values
  • Release readiness — v0.1.0-alpha
    • Stable APIs (semver — no breaking changes in patch/minor)
    • Advanced APIs (stable interface, expert use)
    • Experimental APIs (no stability promise)
    • Paper-only code
    • Quality gates (all passing @ 2026-05-24)
    • Known heavy artefacts (audit 2026-05-24 — 234 MB total)
    • Pending before merge to main
  • Architecture
    • Modules
    • Model layers
    • Non-central paths
    • Planned evolution
  • Conventions
    • Coordinate frames
    • Pixel centers
  • Dataset specification (v0)
    • meta.json (per scene)
      • sim_params (CPU/OptiX)
      • Optional: opencv (detection tuning)
      • board.type = "charuco"
    • frames.jsonl
    • gt_points.npz
    • gt_charuco_corners.npz (if board.type == "charuco")
  • Alternatives and positioning
    • OpenCV (camera & stereo calibration)
    • Kalibr (ETH Zurich)
    • Basalt (TUM)
    • camodocal
    • SfM toolchains (COLMAP, OpenMVG)
    • Non-goals (current scope)
  • Documentation license (CC BY-SA 4.0)
    • Code license (GPL v2 or later)
StereoComplex
  • Search


© Copyright .

Built with Sphinx using a theme provided by Read the Docs.