Applications: solve the task first

Choose an Application when the method is already known and only its parameters or inputs change. A wrapper validates configuration, invokes existing PanorAi algorithms and returns a public typed result; it does not duplicate the algorithm.

Surface

Stability

Canonical import

Contract

Public components or entries

panorama-stitching-application

Experimental

panorai.applications

panorai-panorama-stitching/v1-experimental

PanoramaStitcher

registered-full-sphere-stereo-application

Experimental

panorai.applications

panorai-registered-full-sphere-stereo/v1-experimental

FullSphereDenseStereo

spherical-applications-dog-reviewed-profile

Experimental

panorai.applications

panorai-spherical-dog-features/v1

SphericalDoGFeatures.reviewed_profile

spherical-applications

Experimental

panorai.applications

panorai-application/v1-experimental

Application, ApplicationConfigurationError, ADCensusStereoDepth, AssessRelativePoseCapture, CensusMGMStereoDepth, ELASStereoDepth, PipelineApplication, PatchMatchStereoDepth, PanoramicDenseStereo, InstanceHeuristicDecision, RelativePoseCaptureAssessment, RelativePoseCaptureError, RelativePoseCaptureInput, RelativePoseCaptureMetadata, RelativePoseCapturePolicy, RelativePoseProfile, SphericalDenseReconstruction, SphericalDoGFeatures, SphericalMaskRCNNPaper, SphericalMaskRCNNWorkflow, SphericalRelativePose, SphericalStereoDepth, SphericalStereoInput, StereoBMDepth, StereoSGBMDepth

spherical-applications-slic

Stable

panorai.applications

panorai-spherical-slic/v1

SphericalSLIC

spherical-applications-auto-experimental

Experimental

panorai.applications

panorai-application/auto-experimental

—

1. Run the smallest Stable application

The following example is self-contained and executed in CI. It uses intrinsic spherical SLIC, so no projected faces are created.

from panorai import EquirectangularImage
from panorai.applications import SphericalSLIC

panorama = EquirectangularImage.sample("spherical-grid", size=(36, 18))

application = SphericalSLIC(n_segments=8, max_num_iter=2)
labels = application(panorama)

assert labels.kind == "labels"
assert labels.values.shape == panorama.shape_hw
assert labels.grid.is_canonical_erp
assert labels.support.shape == labels.validity.shape == panorama.shape_hw

2. Reconfigure immutably

Application instances are configurations. with_params returns a new instance and leaves the original untouched:

finer = application.with_params(n_segments=32)
pipeline = application.as_pipeline()
description = pipeline.describe()

assert application.n_segments == 8  # the original remains unchanged
assert finer.n_segments == 32
assert pipeline.interface == "panorai-spherical-pipeline/v1"
assert description["steps"][0]["stage"] == "OnSphere"

Use get_params() for tuning tools and describe() for an auditable view of input, output, execution domain and lower-level composition.

3. Persist only registered configurations

SphericalSLIC.save("slic.json") writes canonical JSON through an explicit registry. Loading never imports a class named by the file, and arbitrary callables are not serialized. This makes the saved configuration portable without using pickle.

4. Use the fixed DoG candidate without hiding its status

The reviewed DoG factory fixes the complete detector, tangent-patch and RootSIFT configuration. It is useful for reproducible research now, but it is still Experimental while its prospective external gates remain open:

from panorai import EquirectangularImage
from panorai.applications import SphericalDoGFeatures

panorama = EquirectangularImage.open("room_360.jpg")
method = SphericalDoGFeatures.reviewed_profile()
features = method(panorama, panorama_id="room-360")

assert method.profile_id == "panorai-spherical-dog-features/reviewed-v1"
print(features.bearings, features.descriptors)

Backend selection is not a scientific change:

numpy_method = method.with_params(config__convolution_backend="numpy")
assert numpy_method.profile_id == method.profile_id

Changing the contrast threshold is a different method. The immutable update therefore drops the reviewed identity and returns the generic Experimental wrapper:

custom = method.with_params(config__contrast_threshold=0.001)
assert custom.profile_id is None

The exact protocol and cohort-freezing commands are documented in Spherical application promotion protocol.

5. Estimate Essential, R and translation direction

SphericalRelativePose accepts an ordered pair of ERP images. Its named reference profile includes both the frozen frontend and the selected MSAC-first/all-inlier-refit estimator; selecting another extractor, matcher or pose strategy is therefore explicit:

from panorai.applications import SphericalRelativePose

application = SphericalRelativePose.reference()
pose = application(reference, source)
if pose is None or not pose.quality_report.accepted:
    raise RuntimeError("relative pose was not trustworthy")

E = pose.essential_matrix
R_source_from_reference = pose.R
t_direction_source_from_reference = pose.t

The translation is a unit direction, never metric scale. The equivalent composition is visible and configurable instead of being hidden inside the wrapper:

pipeline = application.as_pipeline()
print(tuple(pipeline.named_steps))
# extract_features, match_features, bearing_correspondences, estimate_pose

Capture-time evidence remains separate. When independently registered depth is available, prepend the scanner-assisted eligibility Stage:

from panorai.applications import (
    RelativePoseCaptureMetadata,
    RelativePoseCapturePolicy,
)

application = SphericalRelativePose.reference(
    capture_policy=RelativePoseCapturePolicy.scanner_assisted_reference()
)
pose = application(
    reference,
    source,
    capture_metadata=RelativePoseCaptureMetadata(
        registered_cloud_overlap_min=0.72,
    ),
)

The measured 50% overlap minimum is an eligibility condition, not a pose quality guarantee. The post-estimation quality_report.accepted decision remains mandatory.

These are sparse feature/geometry stages. No raster OnSphere operation or Torch layer is required: feature extraction runs on canonical projected views, matching and bearing conversion are non-differentiable algorithms, and the Essential estimator runs directly on spherical bearings.

6. Descend when the method changes

application.as_pipeline() exposes the equivalent composition. Descend to Pipeline when you need a different stage, branch, batch or fusion policy. Descend to Spherical Ops when the operation itself changes.

7. Construct a panorama from overlapping planar images

PanoramaStitcher is an Experimental, non-flagship Application for a central camera rotating about one optical centre. It accepts two or more overlapping planar pinhole images and returns a partial typed ERP plus registration diagnostics. Its as_pipeline() exposes feature detection, overlap discovery, calibration/registration, warping, exposure compensation and blending as public Stages.

Use the dedicated guide before running it: missing metadata invokes explicit shared-FOV assumptions, and translation, strong parallax, rolling shutter and unknown lens distortion are outside the current model.

Current application boundary

SphericalSLIC is Stable. SphericalDoGFeatures.reviewed_profile() is a fixed but still Experimental promotion candidate. The generic SphericalDoGFeatures, SphericalStereoDepth, SphericalRelativePose and SphericalMaskRCNNWorkflow and PanoramaStitcher are executable Experimental wrappers with separate scientific and dependency gates. A common wrapper shape does not imply common stability.

Understand the design in Application wrappers and look up signatures in Applications API.