Cubemap, batch, and autograd

Field

Contract

Application

Project and reconstruct panoramic views

Input

ERP arrays or NCHW tensors

Output

Cubemap/gnomonic batches and reconstructed ERP

Strategy

Projection-domain

API

Cubemap APIs and EquirectangularImage.process_views

Stability

Stable geometry; Compatibility containers

Dependencies

Core; Torch optional for tensor examples

Evidence

Executed analytic fixtures

How this application is composed

Cubemap and gnomonic projectors come from panorai.geometry; batch and dtype preservation belong to the selected NumPy/Torch backend; reconstruction uses explicit support masks. process_views() wraps those stages when one callback and one fused ERP are sufficient. The lower-level objects remain available for custom batching, autograd or per-face outputs.

See the Cubemap, batch, and learned-model workflow section of the spherical computer-vision guide for what PanorAi projects, when an ERP is reconstructed, and why neither cubemap conversion nor batched projection is a spherical convolution.

PanorAi-specific: fixed cubemap face order/orientation, canonical ray sampling, batch-preserving projection, explicit support and inverse ERP reconstruction. The operation or model applied to each face remains caller- owned.

Cubemap round trip

Cubemap faces use the immutable order front, right, back, left, up, down. This continuous RGB example uses bilinear interpolation and reconstructs an HWC panorama.

from panorai.geometry import (
    CUBE_FACE_ORDER,
    cubemap_to_equirectangular,
    equirectangular_to_cubemap,
)

cubemap = equirectangular_to_cubemap(
    rgb, face_shape_hw=(8, 8), interpolation="bilinear"
)
assert tuple(cubemap) == CUBE_FACE_ORDER
rebuilt = cubemap_to_equirectangular(
    {name: result.data for name, result in cubemap.items()},
    output_shape_hw=(height, width),
    interpolation="bilinear",
)
assert rebuilt.data.shape == rgb.shape
assert rebuilt.support_mask.all()

Torch batch and input gradients

Torch is optional. Batched image tensors use NCHW; the result preserves batch, channels, dtype, and device. Autograd is supported for input values, not for geometric parameters.

import torch

batch = torch.linspace(
    0.0, 1.0, 2 * 3 * height * width, dtype=torch.float32
).reshape(2, 3, height, width)
batch.requires_grad_(True)  # NCHW batch on the current device
torch_view = equirectangular_to_gnomonic(
    batch, view_spec, interpolation="bilinear"
)
assert torch_view.data.shape == (2, 3, 8, 12)
torch_view.data.sum().backward()
assert batch.grad is not None and torch.isfinite(batch.grad).all()

Execute every example, including Torch, with:

python scripts/run_documentation_examples.py --source-checkout --torch