Migrating from PanorAi 3.0.19 to 3.1.0¶
PanorAi 3.1 keeps the public 3.0 imports for containers, projections, samplers, blenders, factories, depth, and point-cloud adapters. The new API is opt-in so existing code does not silently change coordinate conventions.
Use the canonical API in new code¶
from panorai.geometry import GnomonicProjector, GnomonicSpec
spec = GnomonicSpec(
center_lat_deg=10,
center_lon_deg=-35,
hfov_deg=100,
vfov_deg=60,
roll_deg=5,
output_shape_hw=(320, 640),
)
result = GnomonicProjector(spec).project(erp)
view, support = result.data, result.support_mask
The canonical frame is +X right, +Y up, +Z forward. ERP coordinates are
pixel-center coordinates with a top-left origin, circular longitude in
[-pi, pi), and latitude decreasing from north to south. Depth is radial
range, not implicit z-depth.
Canonical specs validate eagerly: longitude and roll are normalized to
[-180, 180), all angles must be finite real numbers, FOV values remain in
(0, 180), and dimensions must be positive integers. Values that older
internal helpers silently truncated, such as a floating image dimension, now
raise an explicit error in the new canonical API.
Projector results compose directly:
view = projector.project(erp)
restored = projector.back_project(view, output_shape_hw=erp.shape[:2])
Extracting view.data first remains supported. The wheel is PEP 561 typed and
keeps Torch optional at import time.
Container compatibility¶
Legacy calls remain valid:
face = image.to_gnomonic(lat=10, lon=-35, fov=90, x_points=640, y_points=320)
The resolution arguments now produce exactly (320, 640). The legacy inverse
gnomonic calculation also defines its zero-radius sample analytically as the
requested projection center. In 3.0.19 that sample was NaN before OpenCV
remapping and could become a different pixel or border fill on different
platforms. All other recorded legacy samples retain their 3.0 values.
To opt into the canonical convention through a container, pass only spec:
face = image.to_gnomonic(spec=spec)
spec cannot be combined with lat, lon, fov, or legacy projection
keywords.
Interpolation and optional dependencies¶
Use
bilinearfor floating RGB, features, and continuous depth.Use
nearestfor integer labels and masks. Bilinear integer input is an explicit error.Bilinear defaults to
invalid_policy="propagate", preserving strict IEEENaNpropagation. The opt-inrenormalizemode requires an explicit boolean validity mask andmin_valid_weight; it reports output validity and contributing weight separately from geometric support.Core:
pip install panoraiTorch:
pip install "panorai[torch]"Point clouds:
pip install "panorai[pcd]"Lightweight depth-adapter dependencies:
pip install "panorai[depth]"
Neither Torch nor Open3D is imported by import panorai.
For sparse floating depth, for example:
projector = GnomonicProjector(
spec,
invalid_policy="renormalize",
min_valid_weight=0.5,
)
view = projector.project(radial_range_m, validity_mask=depth_is_valid)
usable = view.support_mask & view.validity_mask
Choose the threshold from the measurement contract; PanorAi does not infer validity from zero or choose a universal threshold.
Depth distribution boundary¶
PanorAi 3.0 artifacts exposed deep copies of Depth Anything V2, DUSt3R/CroCo, Metric3D, legacy ZoeDepth, and research training/data helpers. Those trees are experimental/internal rather than stable PanorAi API and have been removed from the source tree and release artifacts. This prevents an MIT-only PanorAi distribution from silently redistributing code with additional terms, including DUSt3R/CroCo’s CC BY-NC-SA 4.0 license.
The supported 3.x compatibility surface remains:
panorai.depth.ModelRegistry;load_dav2_model,load_m3dv2_model,load_dust3r_model, andload_zoe_model;registry keys
dav2,m3dv2,dust3r, andzoe;panorai.pcdmodules and containerto_pcdmethods.
Loaders now import separately installed upstream projects only when invoked.
If an implementation is absent, they raise DepthAdapterUnavailableError
with the upstream location and license instead of becoming None at import
time. Installing panorai[depth] supplies common adapter dependencies; it does
not install or license the upstream source or model weights. Code importing a
deep path such as panorai.depth.Dust3r.*,
panorai.depth.DepthAnythingV2.*, or panorai.depth.Metric3D.* must install
and import the corresponding upstream project directly.
Root imports are lazy¶
The five public 3.0 root names remain available and unchanged:
from panorai import (
ConfigManager,
EquirectangularImage,
GnomonicFace,
GnomonicFaceSet,
PanoraiFactory,
)
PanorAi 3.1 resolves these compatibility objects only when code accesses them.
Consequently, import panorai.geometry no longer imports containers,
factories, registries, OpenCV, Pillow, Pydantic, SciPy, scikit-image, or YAML.
This changes import timing, not the identity or import path of any recorded
public 3.0 root object. Import subpackages explicitly rather than relying on an
undocumented module attribute created as a side effect of import panorai.
Blender masks and output shapes¶
Blender masks are now authoritative and independent of values. A valid black RGB pixel or zero-valued scalar participates when its mask is true; an unsupported non-zero value does not. Valid non-finite floating samples raise an error instead of silently becoming zero.
The supported fusion blenders (average, closest, feathering, gaussian,
and huber) preserve the input image shape. HuberBlender therefore returns
(H, W) for scalar inputs and (H, W, C) for channel inputs instead of always
forcing three channels. Pass return_mask=True to any built-in blender to get
(data, support_mask). GnomonicFaceSet.to_equirectangular now obtains real
back-projection masks and stores the fused mask on the returned
EquirectangularImage.support_mask.
The overlap count/standard-deviation blenders are diagnostic. The
huber_no_confidence, huber_spatial, and bundle_adjustment strategies are
experimental and are not part of the stable projection path.