EquirectangularImage API

The Stable panorai-object-workflow/v1 container is available from both panorai.EquirectangularImage and panorai.data.EquirectangularImage. Pillow-style sizes are (width, height); canonical geometry shapes and GnomonicSpec.output_shape_hw are (height, width).

Construction and I/O

class panorai.EquirectangularImage(data, shadow_angle=0.0, lat=0.0, lon=0.0, support_mask=None, *, valid=None, shadow_padded=False)

Represents an equirectangular image with optional multi-channel support.

  • Inherits from SphericalData, which extends multi-channel capabilities.

  • Allows attaching samplers and projection transforms dynamically.

  • Can be converted into one or multiple GnomonicFaces.

classmethod EquirectangularImage.open(source, *, mode='RGB', shadow_angle=0.0, lat=0.0, lon=0.0, support_mask=None, valid=None, shadow_padded=False)

Open an ERP image eagerly and release the source file immediately.

mode=None preserves the decoded Pillow mode. The default RGB gives a predictable three-channel image. File-backed lazy decoding is intentionally not exposed: the returned panorama owns its array.

classmethod EquirectangularImage.sample(pattern='spherical-grid', size=(512, 256), *, shadow_angle=0.0, lat=0.0, lon=0.0, support_mask=None, valid=None, shadow_padded=False)

Create a deterministic synthetic RGB ERP for examples and tests.

Parameters:
  • pattern – One of "spherical-grid", "directions" or "checkerboard". "directions" maps canonical (X, Y, Z) rays to RGB; the other patterns mark angular cells on the same pixel-centre lattice.

  • size – Pillow-style (width, height) output size.

  • shadow_angle – Optional south-polar shadow angle in degrees.

  • lat – Latitude metadata in degrees.

  • lon – Longitude metadata in degrees.

  • support_mask – Optional geometric source support.

  • valid – Optional data-validity mask.

  • shadow_padded – Whether shadow rows are already materialized.

This is a documentation fixture, not a dataset or a scientific oracle. Pixel values are deterministic, but callers should rely on the stated geometry and modalities rather than treating the artwork as evidence.

classmethod EquirectangularImage.constant(value, *, height, width, dtype=<class 'numpy.float32'>, shadow_angle=0.0, lat=0.0, lon=0.0, support_mask=None, valid=None, shadow_padded=False)

Create a constant NumPy ERP with explicit height and width.

A scalar value produces an (H, W) field. A one-dimensional value such as (0.1, 0.2, 0.3) produces an (H, W, C) image. The default float32 dtype is intended for numerical tutorials; pass dtype=np.uint8 when an encoded 8-bit image is required.

Unlike new(), dimensions use canonical geometry order and are keyword-only, so tutorial code cannot silently exchange width and height.

classmethod EquirectangularImage.new(mode, size, color=0, **kwargs)

Create a constant ERP using Pillow-style (width, height) size.

classmethod EquirectangularImage.fromarray(array, *, layout='HWC', shadow_angle=0.0, lat=0.0, lon=0.0, support_mask=None, valid=None, shadow_padded=False)

Create an owned ERP from a NumPy HW, HWC or CHW array.

classmethod EquirectangularImage.from_pil(image, *, shadow_angle=0.0, lat=0.0, lon=0.0, support_mask=None, valid=None, shadow_padded=False)

Create an owned ERP from a Pillow image without retaining its file.

EquirectangularImage.to_pil(*, field='image', mode=None, value_range=None, invalid_fill=0)

Convert one field to an owned Pillow image for display or encoding.

Floating multi-channel rasters use value_range=(0, 1) by default and are quantized to 8-bit for Pillow. Floating single-channel data stays in Pillow F mode unless a different mode is requested. Invalid samples are filled explicitly for the exported preview; the PanorAi container remains unchanged.

EquirectangularImage.save(destination, format=None, *, field='image', mode=None, value_range=None, invalid_fill=0, **params)

Encode one raster field through Pillow without serializing metadata.

save() writes one raster field, not the typed multimodal contract. Floating RGB/RGBA output is quantized from an explicit value range; invalid samples use invalid_fill only in the encoded copy.

Image-style spherical transforms

EquirectangularImage.copy()

Return an owned deep copy; all image-style transforms are immutable.

EquirectangularImage.convert(mode)

Return a copy whose image field uses a different Pillow color mode.

EquirectangularImage.resize(size, *, interpolation=None, invalid_policy='propagate', min_valid_weight=None, preserve_dtype=True)

Resample every aligned field onto a new canonical ERP lattice.

size follows Pillow’s (width, height) order. Continuous fields use bilinear sampling unless overridden; categorical fields always use nearest sampling. Longitude remains periodic and masks are transformed independently from numeric values.

EquirectangularImage.thumbnail(size, *, interpolation=None, preserve_dtype=True)

Return an immutable aspect-preserving ERP bounded by size.

Unlike Pillow’s in-place thumbnail(), this method never mutates and never enlarges the source.

EquirectangularImage.rotate(rotation=None, *, yaw_deg=0.0, pitch_deg=0.0, roll_deg=0.0, size=None, interpolation=None, invalid_policy='propagate', min_valid_weight=None, preserve_dtype=True)

Actively rotate rays in 3D, never the rectangular ERP canvas.

Supply either a canonical 3x3 rotation matrix or named Euler angles. A positional scalar such as Pillow’s rotate(45) is deliberately rejected because a planar angle does not identify a spherical axis.

EquirectangularImage.transpose(method)

Apply a named spherical reflection without swapping raster axes.

class panorai.SphericalTranspose(*values)

Named orientation changes that retain a well-defined spherical meaning.

Unlike a raw array transpose, these operations act on longitude/latitude coordinates. They never exchange the ERP height and width axes.

Projection, filtering and composition

EquirectangularImage.crop(spec, *, depth_policy='propagate', min_valid_weight=None)

Project a tangent crop and return a GnomonicFace.

A rectangular pixel box is intentionally not accepted: the crop is defined by a panorai.geometry.GnomonicSpec with centre, angular field of view, roll and output lattice.

EquirectangularImage.filter(operation, *, field='image')

Apply one registered sphere-aware operation to a named ERP field.

EquirectangularImage.composite(face, *, blend='replace', alpha=None)

Reproject and combine one tangent face with this complete ERP.

replace makes face support authoritative, including its validity. alpha blends continuous values only where both sources are valid; the blended region is invalid otherwise. A raw planar array is not accepted because it has no projection back to the sphere.

EquirectangularImage.paste(face, *, blend='replace', alpha=None)

Alias for composite(); returns a new spherical image.

The lower-level views(), process_views(), with_depth(), with_labels(), with_field() and apply_spherical() methods remain part of the same Stable object workflow. See Pipeline API and Spherical operations API for composition and operation contracts.

Properties

size, width and height use image-style dimensions. shape_hw is the geometry-style shape. mode is the logical image mode, dtype and backend describe storage, and format records the decoded file format until a transform creates a new raster.