Spherical relative-pose API¶
panorai.estimators is an isolated Experimental surface. It consumes
panorama-frame bearings and does not import or call OpenCV, PyCOLMAP or Torch. See
Spherical features and matching for the end-to-end feature workflow,
coordinate convention and limitations.
Surface |
Stability |
Canonical import |
Contract |
Public components or entries |
|---|---|---|---|---|
spherical-features-core |
Stable |
panorai.features |
panorai-spherical-features/v1 |
DeduplicationResult, FaceSetSpec, FeatureExtractor, FeatureExtractorConfig, FeatureMatcher, FeatureMatcherConfig, FeatureProvenance, FaceDetectionDiagnostics, MatchProvenance, MultifaceDetectionDiagnostics, OpenCVFeatureBackend, SphericalBearingCorrespondences, SphericalFeature, SphericalFeatureMatches, SphericalFeaturePipeline, SphericalFeaturePipelineConfig, SphericalFeatureSet, available_presets, deduplicate_spherical_keypoints, extract_opencv_features, gnomonic_feature_mask, match_opencv_features, panorai.features.backends.OpenCVFeatureBackend |
spherical-features-pycolmap |
Experimental |
panorai.features |
panorai-spherical-features-pycolmap/v1 |
GnomonicRig, GnomonicRigCamera, PyCOLMAPExportResult |
spherical-features-multiscale |
Experimental |
panorai.features |
panorai-spherical-features-multiscale/v1 |
MultiscaleEmbeddingConfig, MultiscaleFeatureMatches, MultiscaleFeatureSet, MultiscaleSphericalFeaturePipeline, OpenCVContextEmbedding, VisualContextNode, VisualEmbeddingProvider |
spherical-features-dog-sift |
Experimental |
panorai.features |
panorai-spherical-dog-sift/v2 |
SphericalDoGSIFTConfig, SphericalDoGSIFTExtractor, SphericalDoGSIFTPipeline |
spherical-features-dog-detector |
Experimental |
panorai.features |
panorai-spherical-dog-detector/v2 |
SphericalDetectionDiagnostics, SphericalDoGDetector, SphericalDoGDetectorConfig, SphericalKeypoint, SphericalKeypointSet, SphericalOctaveDetectionDiagnostics, SphericalRefinedKeypoint |
spherical-features-coarse-dog-detector |
Experimental |
panorai.features |
panorai-spherical-coarse-dog-detector/v1 |
SphericalCoarseDoGDetector, SphericalCoarseDoGDetectorConfig |
spherical-features-tangent-patches |
Experimental |
panorai.features |
panorai-tangent-patches/v1 |
OpenCVTangentDescriptor, OpenCVTangentDescriptorConfig, TangentDescriptorSet, TangentPatch, TangentPatchGeometry, TangentPatchProvider, TangentPatchRequest, TangentPatchSet |
spherical-feature-resolution-selection |
Experimental |
panorai.features |
panorai-resolution-selection/v1 |
ResolutionLevelReport, ResolutionSelectionObservation, ResolutionSelectionPolicy, ResolutionSelectionReport, ResolutionTransitionReport, select_feature_resolution |
spherical-features-tangent-descriptor-v2 |
Experimental |
panorai.features |
panorai-tangent-opencv-descriptor/v2 |
OpenCVTangentDescriptorV2, OpenCVTangentDescriptorV2Config, TangentDescriptorHypothesisSet |
spherical-relative-pose-pipeline |
Experimental |
panorai.features |
panorai-spherical-relative-pose-pipeline/v1-experimental |
ExtractSphericalFeaturePair, MatchSphericalFeatures, SphericalFeaturePair, SphericalImagePair, ToBearingCorrespondences |
spherical-deep-learning-depth |
Experimental |
panorai.experimental.deep_learning |
panorai-spherical-metric-depth/v1-experimental |
SphericalMetric3D, acquire_metric3d_convnext_large_v1, acquire_metric3d_convnext_tiny_v1, load_spherical_metric3d_convnext_large_v1, load_spherical_metric3d_convnext_tiny_v1, panorai.depth.DepthAdapterUnavailableError, panorai.depth.ModelRegistry, panorai.depth.load_dav2_model, panorai.depth.load_dust3r_model, panorai.depth.load_m3dv2_model, panorai.depth.load_zoe_model, panorai.depth.zoe.load_zoe_model, panorai.experimental.deep_learning.depth.SPHERICAL_METRIC_DEPTH_INTERFACE, panorai.experimental.deep_learning.depth.METRIC3D_CHECKPOINT_REVISION, panorai.experimental.deep_learning.depth.METRIC3D_CONVNEXT_LARGE_V1, panorai.experimental.deep_learning.depth.METRIC3D_CONVNEXT_TINY_V1, panorai.experimental.deep_learning.depth.METRIC3D_SOURCE, panorai.experimental.deep_learning.depth.METRIC3D_SOURCE_COMMIT, panorai.experimental.deep_learning.depth.ExternalArtifactRecord, panorai.experimental.deep_learning.depth.ExternalArtifactSpec, panorai.experimental.deep_learning.depth.LoadedSphericalDepthModel, panorai.experimental.deep_learning.depth.Metric3DAssets, panorai.experimental.deep_learning.depth.SphericalMetric3D, panorai.experimental.deep_learning.depth.UpstreamTermsNotAcceptedError, panorai.experimental.deep_learning.depth.acquire_metric3d_convnext_large_v1, panorai.experimental.deep_learning.depth.acquire_metric3d_convnext_tiny_v1, panorai.experimental.deep_learning.depth.load_spherical_metric3d_convnext_large_v1, panorai.experimental.deep_learning.depth.load_spherical_metric3d_convnext_tiny_v1 |
tangent-da3-metric-depth |
Experimental |
panorai.experimental.deep_learning |
panorai-depth-anything-3-metric-tangent/v1-experimental |
DA3MetricTangent, acquire_da3metric_large, load_da3metric_large, panorai.experimental.deep_learning.da3.DA3Assets, panorai.experimental.deep_learning.da3.DA3MetricTangent, panorai.experimental.deep_learning.da3.DA3TermsNotAcceptedError, panorai.experimental.deep_learning.da3.DA3_CANONICAL_FOCAL_PX, panorai.experimental.deep_learning.da3.DA3_CHECKPOINT_REVISION, panorai.experimental.deep_learning.da3.DA3_MODEL_ID, panorai.experimental.deep_learning.da3.DA3_PATCH_SIZE, panorai.experimental.deep_learning.da3.DA3_SOURCE, panorai.experimental.deep_learning.da3.DA3_SOURCE_COMMIT, panorai.experimental.deep_learning.da3.DA3METRIC_LARGE, panorai.experimental.deep_learning.da3.LoadedDA3MetricModel, panorai.experimental.deep_learning.da3.SPHERICAL_DA3_METRIC_DEPTH_INTERFACE, panorai.experimental.deep_learning.da3.acquire_da3metric_large, panorai.experimental.deep_learning.da3.load_da3metric_large |
spherical-semantic-segmentation |
Experimental |
panorai.experimental.deep_learning.segmentation |
panorai-spherical-semantic-segmentation/v1 |
SPHERICAL_MASK_PROPOSALS_INTERFACE, SPHERICAL_PROXY_SEGMENTATION_INTERFACE, SPHERICAL_SEMANTIC_SEGMENTATION_INTERFACE, SAM21_HIERA_LARGE_LICENSE, SAM21_HIERA_LARGE_REPOSITORY, SAM21_HIERA_LARGE_REVISION, IMAGENET_PROXY_VOCABULARY, DenseSemanticEvidence, Sam21Assets, Sam21FileRecord, Sam21HieraLargeSegmenter, Sam21TermsNotAcceptedError, SamMultimaskOutput, SegmentPrompt, SemanticProxyConcept, SphericalBinaryMask, SphericalProxySegmenter, SphericalMaskProposal, SphericalMaskProposalSet, SphericalSeed, SphericalSegment, SphericalSegmentationConfig, SphericalSegmentationResult, SphericalSemanticSegmenter, acquire_sam21_hiera_large, advance_chart, backproject_face_mask_sets, angular_distance_degrees, backproject_face_masks, concept_display_names, concept_evidence_from_imagenet, concept_proxy_names, connected_component_at, consensus_frontiers, extract_mask_face, extract_rgb_face, face_point_direction, fibonacci_coverage_seeds, load_sam21_hiera_large, majority_and_envelope, mask_stability_score, maximum_pairwise_iou, merge_proposals, non_maximum_suppression, partition_proposals_by_origin, pairwise_mask_iou, prompt_from_mask, prompt_grid, proposal_is_accepted, resolve_panoptic_map, select_semantic_seeds, semantic_support_for_mask, solid_angle_weights, weighted_containment, weighted_intersection_over_union |
spherical-relative-pose |
Experimental |
panorai.estimators |
panorai-spherical-relative-pose/v1 |
CalibrationEvaluation, DecoupledPoseReport, EstimateRelativePose, FivePointSample, FivePointSampler, FivePointSamplingDiagnostics, ModelCompetitionReport, ModelEvidence, PoseStabilityReport, RelativePoseAcceptancePolicy, RelativePoseConfidenceCalibrator, RelativePoseOptions, RelativePoseQualityReport, RelativePoseResult, TranslationOrientationReport, SpatiallyWeightedFivePointSampler, SphericalRelativePoseEstimator, UniformFivePointSampler, estimate_relative_pose, native_kernels_available, solve_five_point_essential, spherical_tangent_sampson_error |
semantic-object-localization |
Experimental |
panorai.object_localization |
panorai-object-localization/v1 |
JOINT_MATCH_CLUSTERS_INTERFACE, JointMatchCluster, JointMatchClusterConfig, JointMatchClusterResult, MULTIVIEW_OBJECT_HYPOTHESES_INTERFACE, BearingTrackTriangulation, DirectionalRegionTransfer, HypothesisAffinity, HypothesisAffinityConfig, HypothesisGnomonicRegion, HypothesisPairCues, HypothesisReductionCandidate, HypothesisReductionResult, HypothesisRegionEvaluation, HypothesisTransferEvaluation, HypothesisViewConsistency, HypothesisViewEmbedding, HypothesisViewPairEvaluation, MultiviewObjectHypothesis, MultiviewObjectHypothesisResult, MultiviewSpatialRegion, OBJECT_LOCALIZATION_INTERFACE, OBJECT_LOCALIZATION_STABILITY, ObjectHypothesis, ObjectLocalizationConfig, ObjectLocalizationPipeline, ObjectLocalizationResult, PairObjectLocalizationInput, RegionAssociation, ReducedHypothesisRecord, RegisteredSemanticEvidence, RegisteredBearingObservation, RegisteredBearingTrack, RegisteredPoseInconsistencyError, RegisteredRadialDepth, SEMANTIC_MATCH_PRIOR_INTERFACE, SEMANTIC_REGION_PROPOSALS_INTERFACE, SPHERICAL_ANCHOR_FUSION_INTERFACE, SemanticMatchPrior, SemanticMatchPriorConfig, SemanticQuery, SemanticConcept, SemanticRegionProposalConfig, SemanticRegionProposalResult, SemanticRegionObservation, SemanticTrackObservation, SphericalObjectHypothesisConfig, SphericalObjectHypothesisGenerator, SphericalObjectHypothesisMethod, SphericalObjectHypothesisMethodConfig, SphericalObjectHypothesisMethodResult, SphericalAnchorAffinity, SphericalAnchorCluster, SphericalAnchorClusterDecision, SphericalAnchorDecision, SphericalAnchorFusionConfig, SphericalAnchorFusionResult, SphericalAnchorPairCues, SphericalFOVAnchor, SphericalRegionMetrics, SpatialLocationHypothesis, SymmetricRegionTransfer, assign_region_associations, build_semantic_match_prior, cluster_region_association_matches, evaluate_spherical_region, fuse_registered_spherical_anchors, generate_spherical_fov_anchors, hypothesis_pair_affinity, hypothesis_view_consistency, triangulate_registered_bearing_track, localize_region_association, object_hypothesis_id, propose_region_associations, reduce_object_hypotheses, semantic_region_from_map, semantic_regions_from_map, spherical_region_mask, spherical_anchor_pair_affinity, spherical_solid_angle_weights, symmetric_spherical_region_transfer, transfer_spherical_region |
spherical-reconstruction |
Experimental |
panorai.reconstruction |
panorai-spherical-reconstruction/v1 |
BuildRegisteredReferenceSets, ColorizeSurface, DenseReconstructionWorkspace, EstimateMultiViewRanges, ExtractSurface, FuseTSDF, MultiViewRangeMap, MultiViewRangeSet, RegisteredReferenceSets, RegisteredSphericalScene, RegisteredSphericalView, SphericalBaselinePrior, SphericalCameraPose, SphericalDenseReconstructionResult, SphericalGlobalMapper, SphericalGlobalMapperOptions, SphericalPairwisePoseEdge, SphericalRangePrior, SphericalReconstructionDiagnostics, SphericalReconstructionResult, SphericalTrack, SphericalTrackObservation, SurfaceMesh, TSDFSpec, TSDFVolume, ValidateDenseReconstruction, colorize_surface, extract_surface, fuse_tsdf |
metric-spherical-landmark-ba |
Experimental |
panorai.reconstruction.metric_landmark_ba |
panorai-metric-spherical-landmark-ba/v1-experimental |
METRIC_SPHERICAL_LANDMARK_BA_INTERFACE, MetricBearingObservation, MetricLandmarkBAOptions, MetricLandmarkBAReport, MetricLandmarkBAResult, MetricRadialRangePrior, MetricScaleGauge, MetricSphericalCamera, MetricSphericalLandmark, refine_metric_spherical_landmarks |
spherical-dense-stereo |
Experimental |
panorai.stereo |
panorai-spherical-dense-stereo/v1-experimental |
SphericalDenseStereo, SphericalStereoOptions, SphericalStereoResult, classical, panoramic, colorize_spherical_range, estimate_spherical_range, render_spherical_stereo_result |
classical-rectified-stereo |
Experimental |
panorai.stereo.classical |
panorai-classical-dense-stereo/v1-experimental |
ADCensusConfig, ADCensusCost, AbsoluteDifferenceCost, BirchfieldTomasiCost, BoxCostAggregation, BuildStereoCost, CensusCost, CensusMGMConfig, ClassicalStereoResult, CrossBasedCostAggregation, ELASConfig, ELASSupportPrior, MoreGlobalMatching, OpenCVStereoMatcher, PatchMatchConfig, PatchMatchStereo, RectifiedStereoGeometry, RectifiedStereoPair, RefineStereoDisparity, SelectStereoDisparity, SemiGlobalMatching, StereoBMConfig, StereoCostVolume, StereoDisparityCandidate, StereoSGBMConfig, StereoValidationConfig, TransformStereoCost, ad_census_pipeline, census_mgm_pipeline, disparity_labels, elas_pipeline, patchmatch_pipeline, stereo_bm_pipeline, stereo_sgbm_pipeline |
registered-full-sphere-stereo-core |
Experimental |
panorai.stereo.panoramic |
panorai-registered-full-sphere-stereo/v1-experimental |
FullSphereMultiViewStereo, FullSphereStereoOptions, FullSphereStereoResult, OverlappingCubemapPlanner, PanoramicStereoPose, RegisteredPanoramaSet, StereoSourceView |
panoramic-dense-stereo-workflow |
Experimental |
panorai.stereo.panoramic |
panorai-panoramic-dense-stereo/v1-experimental |
BackProjectStereoRange, DenseStereoPerPair, FuseStereoRange, PanoramicStereoInput, PanoramicStereoResult, PlanRectifiedStereoViews, ProjectStereoViewPairs, RectifiedStereoViewPlanner, RectifiedStereoViewSpec, ResolveStereoPose, ResolveStereoScale, SelectStereoViewPairs, SphereNativeStereo, SphericalStereoViewPairer, StereoPairDiagnostic, StereoViewDescriptor, StereoViewPairScore, StereoViewSelectionDiagnostic, StereoViewPlan, ValidatePanoramicStereo, spec_from_axes |
spherical-slam |
Experimental |
panorai.slam |
panorai-spherical-slam/v1 |
EquidistantFisheyeCamera, FisheyeRayProjection, SphericalImageFrame, SphericalIncrementalSLAM, SphericalIncrementalSLAMDiagnostics, SphericalIncrementalSLAMOptions, SphericalIncrementalSLAMResult, SphericalKeyframeSummary, SphericalLocalBAReport, SphericalMapObservation, SphericalMapPoint, SphericalSLAMDiagnostics, SphericalSLAMFrameSummary, SphericalSLAMOptions, SphericalSLAMPose, SphericalSLAMResult, SphericalTrackingResult, SphericalVisualSLAM |
rotation-pair-calibration |
Experimental |
panorai.calibration |
panorai-rotation-pair-calibration/v1-experimental |
RotationCalibrationOptions, RotationCalibrationResult, calibrate_rotation_pair |
robust-model-fitting |
Experimental |
panorai.model_fitting |
panorai-robust-model-fitting/v1-experimental |
HomographyModel, ModelFamily, RobustFitOptions, RobustFitResult, RotationModel, fit_homography, fit_rotation, robust_fit |
spherical-estimators-auto-experimental |
Experimental |
panorai.estimators |
panorai-estimator/auto-experimental |
— |
EstimateRelativePose is the typed Pipeline adapter around the same
SphericalRelativePoseEstimator implementation. It accepts spherical
matches or bearing correspondences and returns RelativePoseResult or
None; it is an estimator Stage, not a differentiable Torch layer.
Use the estimators and policies catalog to compare the direct estimator, Stage adapter, samplers and the distinct capture and post-estimation policies.
Experimental geometric estimators owned by PanorAi.
The package is intentionally independent from feature extraction backends. Its relative-pose estimator consumes spherical bearings and does not import OpenCV, PyCOLMAP, or Torch.
- class panorai.estimators.CalibrationEvaluation(count: 'int', brier_score: 'float', expected_calibration_error: 'float', accuracy_at_half: 'float')¶
- count¶
- brier_score¶
- expected_calibration_error¶
- accuracy_at_half¶
- to_dict()¶
- class panorai.estimators.DecoupledPoseReport(attempted, applied, rotation_inliers, rotation_inlier_ratio, translation_pool_size, translation_consensus_size, translation_score_margin, rotation_refit_steps, translation_refit_steps, reason)¶
Evidence from the Experimental rotation/translation split.
- attempted¶
- applied¶
- rotation_inliers¶
- rotation_inlier_ratio¶
- translation_pool_size¶
- translation_consensus_size¶
- translation_score_margin¶
- rotation_refit_steps¶
- translation_refit_steps¶
- reason¶
- to_dict()¶
- class panorai.estimators.EstimateRelativePose(options=<factory>, sampler=<factory>, quality_policy=<factory>)¶
Estimate Essential, rotation, and unit translation direction.
This is a sparse robust-estimation
Stage, not a Torch layer. It delegates every numerical decision toSphericalRelativePoseEstimator.- options¶
- sampler¶
- quality_policy¶
- execute(value)¶
- input_kind = ('bearing_correspondences', 'spherical_matches')¶
- interface = 'panorai-spherical-relative-pose-pipeline/v1-experimental'¶
- output_kind = 'relative_pose'¶
- stability = 'experimental'¶
- class panorai.estimators.FivePointSample(indices, strategy, relaxation_level, min_separation_a_deg, min_separation_b_deg, unique_cells_a, unique_cells_b, design_condition_number)¶
One minimal-set proposal and its geometric diagnostics.
- indices¶
- strategy¶
- relaxation_level¶
- min_separation_a_deg¶
- min_separation_b_deg¶
- unique_cells_a¶
- unique_cells_b¶
- design_condition_number¶
- class panorai.estimators.FivePointSampler(*args, **kwargs)¶
Protocol for injectable five-point proposal components.
- describe()¶
- prepare(bearings_a, bearings_b, active_indices, sampling_weights=None)¶
- name¶
- supports_uniform_trial_bound¶
- class panorai.estimators.FivePointSamplingDiagnostics(sampler_name, sampler_configuration, samples_drawn, strict_spatial_samples, relaxed_spatial_samples, uniform_samples, failed_draws, median_min_separation_a_deg, median_min_separation_b_deg, median_design_condition_number, adaptive_uniform_trial_bound_enabled)¶
Aggregate provenance for the minimal sets proposed during RANSAC.
- sampler_name¶
- sampler_configuration¶
- samples_drawn¶
- strict_spatial_samples¶
- relaxed_spatial_samples¶
- uniform_samples¶
- failed_draws¶
- median_min_separation_a_deg¶
- median_min_separation_b_deg¶
- median_design_condition_number¶
- adaptive_uniform_trial_bound_enabled¶
- to_dict()¶
- class panorai.estimators.ModelCompetitionReport(essential, rotation_only, spherical_homography, preferred_model, essential_score_margin)¶
Evidence for Essential, rotation-only and spherical homography models.
- essential¶
- rotation_only¶
- spherical_homography¶
- preferred_model¶
- essential_score_margin¶
- class panorai.estimators.ModelEvidence(model, num_inliers, inlier_ratio, normalized_robust_score, median_residual_deg)¶
Comparable evidence for one geometric explanation.
- model¶
- num_inliers¶
- inlier_ratio¶
- normalized_robust_score¶
- median_residual_deg¶
- class panorai.estimators.PoseStabilityReport(requested_trials, successful_trials, rotation_median_deg, rotation_p90_deg, translation_median_deg, translation_p90_deg)¶
Dispersion after independent deterministic consensus re-estimation.
- requested_trials¶
- successful_trials¶
- rotation_median_deg¶
- rotation_p90_deg¶
- translation_median_deg¶
- translation_p90_deg¶
- class panorai.estimators.RelativePoseAcceptancePolicy(min_inliers=20, min_inlier_ratio=0.15, min_occupied_cells=4, min_coverage_entropy=0.25, max_median_residual_deg=0.5, min_median_parallax_deg=0.5, min_cheirality_ratio=0.6, min_translation_orientation_margin=0.05, max_stability_rotation_p90_deg=3.0, max_stability_translation_p90_deg=10.0, min_essential_score_margin=0.0, require_essential_preferred=True, require_stability=True, interface='panorai-relative-pose-acceptance/v1')¶
Conservative, explicit evidence gate for an already estimated pose.
This policy does not alter RANSAC or the returned pose. It turns measured evidence into an auditable accept/reject decision. Its output is not a calibrated probability.
- min_inliers¶
- min_inlier_ratio¶
- min_occupied_cells¶
- min_coverage_entropy¶
- max_median_residual_deg¶
- min_median_parallax_deg¶
- min_cheirality_ratio¶
- min_translation_orientation_margin¶
- max_stability_rotation_p90_deg¶
- max_stability_translation_p90_deg¶
- min_essential_score_margin¶
- require_essential_preferred¶
- require_stability¶
- interface¶
- rejection_reasons(report)¶
- to_dict()¶
- class panorai.estimators.RelativePoseConfidenceCalibrator(score_upper_bounds, probabilities, calibration_sample_ids, interface='panorai-relative-pose-confidence-calibration/v1')¶
Isotonic post-hoc calibrator with mandatory sample-ID separation.
- score_upper_bounds¶
- probabilities¶
- calibration_sample_ids¶
- interface¶
- evaluate(reports, successes, *, sample_ids, bins=5)¶
- classmethod fit(reports, successes, *, sample_ids)¶
- predict_proba(report)¶
- to_dict()¶
- class panorai.estimators.RelativePoseOptions(max_angular_error_deg=1.0, confidence=0.999, min_inlier_ratio=0.1, min_num_trials=32, max_num_trials=1000, dynamic_trials_multiplier=3.0, min_inliers=8, local_optimization_steps=3, minimal_solver_starts=16, minimal_solver_max_nfev=100, refinement_max_nfev=100, random_seed=0, min_median_parallax_deg=0.25, minimal_solver='polynomial', scale_marginal_levels=8, scale_marginal_min_fraction=0.2, robust_refinement_steps=2, quality_cell_count=20, stability_trials=6, stability_fraction=0.8, stability_ransac_trials=24, model_competition_trials=128, model_competition_tie_margin=0.01, translation_orientation_method='parallax-weighted', translation_orientation_parallax_scale_deg=1.0, compute_backend='auto', hypothesis_ranking='msac-first', nonminimal_refit_max_steps=100, pose_refinement_method='joint', decoupled_rotation_trials=512, decoupled_refit_max_steps=100, decoupled_translation_min_score_margin=0.15)¶
Configuration for
estimate_relative_pose().max_angular_error_degthresholds the first-order spherical tangent Sampson residual. Its unit is degrees, not ERP or face pixels.- max_angular_error_deg¶
- confidence¶
- min_inlier_ratio¶
- min_num_trials¶
- max_num_trials¶
- dynamic_trials_multiplier¶
- min_inliers¶
- local_optimization_steps¶
- minimal_solver_starts¶
- minimal_solver_max_nfev¶
- refinement_max_nfev¶
- random_seed¶
- min_median_parallax_deg¶
- minimal_solver¶
- scale_marginal_levels¶
- scale_marginal_min_fraction¶
- robust_refinement_steps¶
- quality_cell_count¶
- stability_trials¶
- stability_fraction¶
- stability_ransac_trials¶
- model_competition_trials¶
- model_competition_tie_margin¶
- translation_orientation_method¶
- translation_orientation_parallax_scale_deg¶
- compute_backend¶
- hypothesis_ranking¶
- nonminimal_refit_max_steps¶
- pose_refinement_method¶
- decoupled_rotation_trials¶
- decoupled_refit_max_steps¶
- decoupled_translation_min_score_margin¶
- to_dict()¶
- class panorai.estimators.RelativePoseQualityReport(num_correspondences, num_inliers, inlier_ratio, occupied_cells_a, occupied_cells_b, coverage_entropy_a, coverage_entropy_b, median_residual_deg, p90_residual_deg, median_parallax_deg, cheirality_ratio, translation_orientation, stability, model_competition, raw_quality_score, accepted, rejection_reasons, interface='panorai-relative-pose-quality/v1')¶
Inspectible pose evidence;
raw_quality_scoreis not a probability.- num_correspondences¶
- num_inliers¶
- inlier_ratio¶
- occupied_cells_a¶
- occupied_cells_b¶
- coverage_entropy_a¶
- coverage_entropy_b¶
- median_residual_deg¶
- p90_residual_deg¶
- median_parallax_deg¶
- cheirality_ratio¶
- translation_orientation¶
- stability¶
- model_competition¶
- raw_quality_score¶
- accepted¶
- rejection_reasons¶
- interface¶
- to_dict()¶
- with_decision(policy)¶
- class panorai.estimators.RelativePoseResult(rotation, translation_direction, essential_matrix, inlier_mask, residuals_rad, num_inliers, num_trials, median_parallax_deg, cheirality_ratio, degenerate, degeneracy_reasons, sampling_diagnostics, quality_report, acceptance_policy, options, compute_backend='numpy', interface='panorai-spherical-relative-pose/v1', minimal_solver='panorai-polynomial-action-matrix-v1+numerical-chart-fallback', robust_estimator='panorai-scale-marginal-lo-ransac-v1', consensus_refit_steps=0, decoupled_pose_report=None)¶
One panorama-2-from-panorama-1 relative-pose estimate.
Translation has unit norm. Its metric magnitude is unobservable from two calibrated central views and is therefore intentionally absent.
- rotation¶
- translation_direction¶
- essential_matrix¶
- inlier_mask¶
- residuals_rad¶
- num_inliers¶
- num_trials¶
- median_parallax_deg¶
- cheirality_ratio¶
- degenerate¶
- degeneracy_reasons¶
- sampling_diagnostics¶
- quality_report¶
- acceptance_policy¶
- options¶
- compute_backend¶
- interface¶
- minimal_solver¶
- robust_estimator¶
- consensus_refit_steps¶
- decoupled_pose_report¶
- property R¶
Alias for the panorama-2-from-panorama-1 rotation.
- describe()¶
- property t¶
Alias for the unit translation direction in panorama-2 coordinates.
- class panorai.estimators.TranslationOrientationReport(hypothesis_count, provisional_correspondence_count, best_positive_depth_count, alternative_positive_depth_count, positive_depth_fraction, cheirality_margin, median_triangulation_angle_deg, ambiguous, selection_method='positive-depth-count', parallax_weight_scale_deg=0.0, best_weighted_positive_depth_support=0.0, alternative_weighted_positive_depth_support=0.0, weighted_cheirality_margin=0.0, raw_cheirality_margin=0.0, effective_correspondence_weight=0.0, reliable_correspondence_count=0)¶
Cheirality evidence distinguishing the four Essential decompositions.
- hypothesis_count¶
- provisional_correspondence_count¶
- best_positive_depth_count¶
- alternative_positive_depth_count¶
- positive_depth_fraction¶
- cheirality_margin¶
- median_triangulation_angle_deg¶
- ambiguous¶
- selection_method¶
- parallax_weight_scale_deg¶
- best_weighted_positive_depth_support¶
- alternative_weighted_positive_depth_support¶
- weighted_cheirality_margin¶
- raw_cheirality_margin¶
- effective_correspondence_weight¶
- reliable_correspondence_count¶
- class panorai.estimators.SpatiallyWeightedFivePointSampler(min_angular_separation_deg=8.0, min_unique_cells=4, spherical_cell_count=20, density_radius_deg=10.0, density_power=0.0, diversity_power=0.5, uniform_trial_probability=0.2, max_design_condition_number=1000000.0, attempts_per_level=24, name='spatially-weighted-five-point-v1', supports_uniform_trial_bound=False)¶
Propose diverse, well-conditioned five-point minimal sets.
Input weights define the initial proposal mass. Optional inverse-density weighting can be enabled explicitly. Each subsequent draw is additionally weighted by angular distance from the points already selected in both panoramas. Strict separation and cell diversity are relaxed progressively; uniform sampling is used only as the final fallback when no spatial proposal satisfies the conditioning gate.
Every explicitly valid correspondence retains positive proposal mass. Robust scoring and refinement remain the responsibility of RANSAC and use the complete valid correspondence set.
- min_angular_separation_deg¶
- min_unique_cells¶
- spherical_cell_count¶
- density_radius_deg¶
- density_power¶
- diversity_power¶
- uniform_trial_probability¶
- max_design_condition_number¶
- attempts_per_level¶
- name¶
- supports_uniform_trial_bound¶
- describe()¶
- prepare(bearings_a, bearings_b, active_indices, sampling_weights=None)¶
- class panorai.estimators.SphericalRelativePoseEstimator(options=None, *, sampler=None, quality_policy=None)¶
Reusable façade for the Experimental PanorAi relative-pose estimator.
- estimate(bearings_a, bearings_b=None, *, valid=None, sampling_weights=None)¶
- class panorai.estimators.UniformFivePointSampler(name='uniform-five-point-v1', supports_uniform_trial_bound=True)¶
Classic uniform sampling without correspondence prefiltering.
- name¶
- supports_uniform_trial_bound¶
- describe()¶
- prepare(bearings_a, bearings_b, active_indices, sampling_weights=None)¶
- panorai.estimators.estimate_relative_pose(bearings_a, bearings_b=None, *, valid=None, sampling_weights=None, options=None, sampler=None, quality_policy=None)¶
Estimate one central relative pose from paired spherical bearings.
- Parameters:
bearings_a – Arrays with shape
(N, 3). Alternatively,bearings_amay be a PanorAi correspondence object exposingbearings_a,bearings_bandvalid, in which casebearings_bis omitted. Finite non-zero rows are normalized on private copies, so inputs are never modified.bearings_b – Arrays with shape
(N, 3). Alternatively,bearings_amay be a PanorAi correspondence object exposingbearings_a,bearings_bandvalid, in which casebearings_bis omitted. Finite non-zero rows are normalized on private copies, so inputs are never modified.valid – Optional explicit boolean mask. Invalid rows are excluded and remain false in the returned inlier mask; validity is never inferred from a bearing’s numeric value beyond mandatory finite/non-zero validation.
sampling_weights – Optional non-negative proposal weights with shape
(N,). They only influence selection of five-point minimal sets; all explicitly valid correspondences remain in hypothesis scoring and refinement. A correspondence object’sweightsfield is used when present unless this argument overrides it.options – Robust-estimation and numerical-solver configuration.
sampler – Injectable minimal-set proposal component. The default spatial sampler chooses only the five correspondences used to generate each hypothesis; it never prefilters the full scoring, inlier or refinement set. Use
UniformFivePointSamplerfor classic uniform proposals.
- Returns:
Nonewhen no hypothesis reachesmin_inliers. A successful result containsRand only the direction oft.- Return type:
RelativePoseResult | None
- panorai.estimators.native_kernels_available()¶
Return whether the optional first-party C++ kernels are importable.
- panorai.estimators.solve_five_point_essential(bearings_a, bearings_b, *, max_epipolar_error=5e-06, max_constraint_error=5e-05, backend='auto')¶
Return real essential matrices satisfying five bearing correspondences.
The result is sign-deduplicated and normalized to Frobenius norm one. All four projective coefficient charts are attempted so solutions with a zero coordinate in one chart are not silently lost.
- panorai.estimators.spherical_tangent_sampson_error(bearings_a, bearings_b, essential_matrix, *, squared=False, backend='auto')¶
Return intrinsic first-order epipolar errors for central-camera rays.
The constraint gradient is projected into each unit sphere’s tangent plane, giving an approximately angular residual. The returned unit is radians (or squared radians when
squared=True).
Polynomial five-correspondence kernel¶
The PanorAi-owned solver parameterizes E in the four-dimensional nullspace
of five epipolar equations, builds the ten calibrated cubic constraints, and
uses a 10-by-10 action matrix to enumerate real solutions. All four projective
coefficient charts are attempted and sign-equivalent roots are deduplicated.
A separately identified deterministic numerical search remains a fallback for
singular polynomial charts. This is PanorAi code and does not call OpenCV or
COLMAP’s minimal solver.
Native compute kernels¶
The distribution can build a first-party C++17 extension for the repeated
fixed-size polynomial construction and spherical tangent-Sampson residual
kernels. This is an acceleration of the same PanorAi mathematics, not a call
to OpenCV or COLMAP. RelativePoseOptions(compute_backend="auto") selects
the native implementation when it is installed and otherwise uses the NumPy
reference. The caller can force either route for reproducibility:
from panorai.estimators import (
RelativePoseOptions,
SphericalRelativePoseEstimator,
native_kernels_available,
)
print(native_kernels_available())
reference = SphericalRelativePoseEstimator(
RelativePoseOptions(compute_backend="numpy")
)
accelerated = SphericalRelativePoseEstimator(
RelativePoseOptions(compute_backend="native")
)
Explicit native selection fails when the compiled extension is absent;
it never silently falls back. Every successful pose records the resolved
compute_backend in describe(). Because the global mapper and
incremental SLAM both consume SphericalRelativePoseEstimator, they reuse
this kernel automatically instead of carrying separate essential-matrix
implementations.
The NumPy implementation remains the normative readable oracle. Native and NumPy paths are required to agree on essential solution sets, residuals, inlier masks, rotations, translation directions and acceptance decisions.
Minimal-set sampling inside RANSAC¶
The default SpatiallyWeightedFivePointSampler is a proposal component
inside RANSAC. On each trial it chooses only the five correspondences used
to generate a hypothesis. It never removes correspondences from full-set
scoring, inlier classification, cheirality checks, or local refinement.
The proposal combines optional caller weights with angular diversity in both panoramas, spherical-cell coverage, and a conditioning check on the five epipolar equations. It first enforces the configured angular separation, then retries with half that separation, and finally falls back to a uniform five-point draw. A uniform-trial mixture, enabled by default, ensures that a localized but valid overlap region retains a direct proposal route.
The sampler is injectable:
from panorai.estimators import (
SpatiallyWeightedFivePointSampler,
SphericalRelativePoseEstimator,
UniformFivePointSampler,
)
spatial = SpatiallyWeightedFivePointSampler(
min_angular_separation_deg=8.0,
min_unique_cells=4,
)
estimator = SphericalRelativePoseEstimator(sampler=spatial)
# Exact compatibility route for classic uniform proposals.
uniform_estimator = SphericalRelativePoseEstimator(
sampler=UniformFivePointSampler()
)
The classic adaptive w**5 RANSAC trial bound is valid only for independent
uniform minimal-set draws and is therefore used only by
UniformFivePointSampler. The spatial sampler runs the configured
conservative trial budget. The returned pose records proposal counts,
relaxations, sample separation and conditioning in sampling_diagnostics.
Quality, stability and model competition¶
Every successful result includes quality_report. It records inlier count
and ratio, spherical-cell occupancy and normalized entropy in both panoramas,
residual quantiles, parallax, cheirality, independent re-estimation from
subsets of the discovered consensus (scored against all observations), and
competition among Essential, rotation-only, and spherical
homography explanations. The default RelativePoseAcceptancePolicy turns
that evidence into accepted and explicit rejection_reasons without
hiding or replacing the estimated R and t:
pose = estimator.estimate(correspondences)
if pose is not None and pose.quality_report.accepted:
use_pose(pose.R, pose.t)
elif pose is not None:
inspect(pose.quality_report.rejection_reasons)
Competing models within model_competition_tie_margin of the best normalized
score are treated conservatively as an ambiguity, with rotation-only and then
spherical homography taking precedence over Essential in a near-tie.
Hypotheses are ranked by inlier support and then a scale-marginal continuous residual score, rather than inlier count alone. Local refinement uses iterative weights marginalized over a declared range of angular noise scales. This is an independently named PanorAi scoring policy; it is not advertised as the MAGSAC++ implementation.
Experimental scoring and consensus-refit controls¶
RelativePoseOptions.hypothesis_ranking defaults to "msac-first". It
minimizes sum(min((residual / threshold)**2, 1)) before applying the other
tie breakers. "count-first" preserves the former maximum-consensus
ordering, while "scale-marginal-first" promotes the existing multi-scale
continuous score ahead of hard inlier count. These controls change model
selection and remain Experimental.
nonminimal_refit_max_steps defaults to 100. A positive value enables an
unweighted all-inlier linear Essential refit whenever at least eight current
inliers are available. The implementation takes the last right singular
vector of the spherical epipolar design matrix, projects its singular values
to (s, s, 0), decomposes and globally rescores the pose, and repeats until
the inlier mask stabilizes, cycles, becomes rank deficient, or reaches the
explicit cap. It retains the best hypothesis observed under the selected
ranking. RelativePoseResult.consensus_refit_steps reports the executed
steps. No Hartley affine recentering is applied to calibrated unit bearings.
For real feature pairs with adequate support, the evidence-backed default is:
options = RelativePoseOptions()
The former compatibility route remains explicit:
options = RelativePoseOptions(
hypothesis_ranking="count-first",
nonminimal_refit_max_steps=0,
)
The limit is a cap; the loop normally stops on a stable or repeated inlier mask. A frozen 12-pair calibrated-fisheye phase reduced median oriented translation error from 12.93 to 5.93 degrees and increased strict successes from 4/12 to 6/12. Median rotation improved from 1.01 to 0.90 degrees, which did not meet the preregistered 25 percent reduction target. The estimator therefore remains Experimental despite this default selection. One 33-match pair produced no candidate, and near-zero translation remained unobservable; callers must retain the quality decision rather than assuming every returned or requested pose is trustworthy.
Experimental decoupled pose refinement¶
pose_refinement_method="decoupled" enables a two-stage estimator for
far-background-dominated pairs. A three-ray Wahba RANSAC uses angular MSAC to
estimate rotation. Correspondences rejected by that rotation-only model form
the translation pool; pairs of their epipolar-plane normals propose
translation axes, which are ranked by multiscale epipolar, cheirality and
parallax support. Both consensus fits repeat to a bounded stable mask.
decoupled_rotation_trials controls the rotation proposal budget and
decoupled_refit_max_steps bounds each stabilization loop. A translation
candidate is accepted only when its relative margin over every direction more
than ten degrees away reaches
decoupled_translation_min_score_margin. The default margin is 0.15.
Unobservable and ambiguous translation pools are explicit rejection reasons.
RelativePoseResult.decoupled_pose_report exposes the decision evidence.
The default pose_refinement_method="joint" preserves existing behavior.
Translation-orientation evidence¶
Every Essential hypothesis has four decompositions. The default
translation_orientation_method="parallax-weighted" chooses among them by
positive-depth support weighted by bounded triangulation strength:
options = RelativePoseOptions(
translation_orientation_method="parallax-weighted",
translation_orientation_parallax_scale_deg=1.0,
)
For triangulation angle theta and configured scale theta0, the weight
is sin(theta)**2 / (sin(theta)**2 + sin(theta0)**2). Nearly parallel rays
therefore cannot dominate the orientation merely because they are numerous.
The compatibility experiment
translation_orientation_method="positive-depth-count" reproduces the
historical binary vote.
At least five rays must have weight greater than or equal to 0.5 before the
weighted orientation is considered observable. Otherwise the result records
selection_method="positive-depth-count-fallback" and a zero decision
margin. The historical axis representative remains available for diagnostics,
but the default quality policy rejects its oriented translation.
TranslationOrientationReport retains the raw positive-depth counts and
raw margin alongside weighted supports, effective correspondence weight,
weighted margin, method, and scale. cheirality_margin always denotes the
margin used by the selected method, so the existing acceptance policy remains
explicit. This changes only four-way decomposition and confidence evidence;
it does not make translation scale observable and cannot rescue pure rotation
or uniformly weak parallax.
Calibrated confidence¶
raw_quality_score is a bounded ranking score, not a probability. A
probability is available only after fitting
RelativePoseConfidenceCalibrator on labeled calibration examples. The
calibrator uses isotonic regression and stores every calibration sample ID.
Evaluation fails if any ID overlaps, making calibration/evaluation leakage an
explicit error:
calibrator = RelativePoseConfidenceCalibrator.fit(
calibration_reports,
calibration_successes,
sample_ids=calibration_ids,
)
probability = calibrator.predict_proba(new_pose.quality_report)
metrics = calibrator.evaluate(
held_out_reports,
held_out_successes,
sample_ids=held_out_ids,
)
The default acceptance thresholds are deliberately conservative and remain Experimental; they are not a calibrated operating point. The 15-pair development fixture is not large enough to calibrate a production probability. A separately frozen and labeled set is required before confidence values can be interpreted statistically.