Clean spherical masks with morphology

This tutorial closes a small hole in a binary region that crosses the ERP longitude seam. The structuring radius is four degrees on the sphere, not four image pixels.

import numpy as np  # noqa: F811 - included example is standalone
from panorai import EquirectangularImage, OnSphere, Pipeline
from panorai.data import RasterFieldSpec
from panorai.ops.spherical import Closing, GeodesicDisk

mask = np.zeros((48, 96), dtype=bool)
mask[18:30, 94:] = True
mask[18:30, :2] = True  # one object crossing the longitude seam
mask[23, 0] = False  # a small hole to close intrinsically
panorama_mask = EquirectangularImage.from_field(
    "mask",
    mask,
    spec=RasterFieldSpec.categorical(),
)
operation = Closing(GeodesicDisk(radius_deg=4.0))

cleaned = panorama_mask.filter(operation, field="mask")
equivalent = Pipeline(OnSphere(operation, input="mask", output="mask"))(
    panorama_mask
)

assert cleaned.field("mask").dtype == np.bool_
assert cleaned.field("mask")[23, 0]
np.testing.assert_array_equal(cleaned.field("mask"), equivalent.values)
assert equivalent.grid.transforms[-1].operation == "closing"

Choose the operation

Dilate expands bright/true regions and Erode shrinks them. Opening removes isolated bright regions; Closing fills small dark holes and joins nearby regions. All four use the same GeodesicDisk contract and preserve the canonical ERP grid.

The configured object is reusable and safely serializable inside a Pipeline. The equivalent direct functions are dilate, erode, opening and closing.

Compose a Torch model

With the optional Torch extra, the same roles are available as panorai.ops.spherical.nn.Dilate, Erode, Opening and Closing. They accept floating NCHW tensors, preserve the spatial grid, propagate autograd to selected extrema, and compose in torch.nn.Sequential. The Stable device contract is CPU float32/float64; this does not imply a CUDA or MPS guarantee.

Read the concept before choosing a radius or sampling step, especially when comparing multiple ERP resolutions.