Sampling and fusion methods =========================== ``EquirectangularImage.views()`` samples an ERP into canonical gnomonic views. ``GnomonicFaceSet.reconstruct()`` back-projects raster results and fuses only explicitly valid contributions. Sampling determines where pinhole methods run; fusion determines how overlapping results become one output. Output topology determines fusion --------------------------------- Raster fusion is only one case. ``map_points()`` lifts detections and uses angular NMS; ``map_regions()`` lifts boxes, polygons, or masks and uses solid-angle IoU/containment; ``map_views()`` aggregates scores or embeddings over explicit spherical footprints. These policies do not materialize fake rasters merely to reuse a blender. See :doc:`spherical_observations`. Samplers -------- The Stable object workflow accepts four layouts by name. It also accepts a sampler object that supplies its own tangent points. ``size`` selects output view shape and ``fov`` selects horizontal/vertical angular coverage; neither is chosen implicitly by the sampler. Cube ~~~~ ``views("cube", ...)`` returns six fixed faces in ``front``, ``right``, ``back``, ``left``, ``up``, ``down`` order. It is the smallest predictable all-sphere layout and is a useful default when six broad views provide enough overlap for the face-local method. Icosahedron ~~~~~~~~~~~ ``views("icosahedron", subdivisions=n, ...)`` starts from 12 symmetric icosahedron vertices. Each subdivision adds normalized edge midpoints and increases directional density. Use it when more uniform overlap than a cube is needed; the view count is controlled by ``subdivisions``, not ``count``. Fibonacci ~~~~~~~~~ ``views("fibonacci", count=n, ...)`` uses a golden-angle construction for a requested number of nearly uniform directions. It is useful for controlled coverage/compute studies and for dense local-model evaluation without the hierarchical levels of the icosahedron sampler. Spiral ~~~~~~ ``views("spiral", count=n, ...)`` returns directions ordered along a simple spherical spiral. Use it when deterministic traversal order is useful. It is not an equal-area partition and should not be assumed to give the same local overlap as Fibonacci sampling at the same count. Custom sampler objects ~~~~~~~~~~~~~~~~~~~~~~ Pass an object exposing ``get_tangent_points() -> [(latitude_deg, longitude_deg), ...]`` as the first argument to ``views()``. The object owns its direction generation and reproducibility. ``count`` and ``subdivisions`` must then be configured by the object rather than passed to ``views()``. The registry also contains ``BlueNoiseSampler`` for stochastic, well-spaced research sampling. Supply it as an object and control the random seed outside PanorAi when exact reproduction matters; it is not a named Stable shortcut of the object workflow. The optional ``rotations=((dlat, dlon), ...)`` argument appends rotated copies of the selected base layout. This increases overlap; it does not rotate the source ERP or replace a calibrated camera pose. Blenders -------- Blender validity contract ~~~~~~~~~~~~~~~~~~~~~~~~~ Every contribution carries a support/validity mask. Black RGB, label zero, and zero depth participate when their mask is true; a non-zero value is ignored when its mask is false. Valid floating values must be finite. ``reconstruct()`` accepts ``average``, ``gaussian``, and ``closest`` directly by name on NumPy and Torch data. A modality bundle selects independently, for example ``blend={"image": "gaussian", "labels": "closest"}``. Additional blender objects below are supported for NumPy workflow data. Average ~~~~~~~ ``blend="average"`` computes a uniform mean over explicitly valid overlapping continuous samples. It is the default for image and depth modalities. Do not use it for categorical label IDs. Gaussian ~~~~~~~~ ``blend="gaussian"`` weights valid contributions by angular proximity to each face centre. It reduces the influence of the more distorted face boundaries and is usually the first fusion policy to test for RGB, logits, and continuous range. Closest ~~~~~~~ ``blend="closest"`` selects the valid contribution farthest inside a face's support boundary. It is the default for labels because it preserves one discrete value instead of averaging class IDs. Feathering ~~~~~~~~~~ ``FeatheringBlender`` uses a normalized distance transform inside every explicit mask and smoothly reduces contribution near support boundaries. Pass the object to ``reconstruct()`` for NumPy continuous rasters. Huber ~~~~~ ``HuberBlender`` estimates a robust per-value location across valid overlaps. It can reduce isolated numeric outliers but costs more than the first-class average/Gaussian paths. It preserves the input raster shape and is available for NumPy workflow data. Diagnostic blenders ~~~~~~~~~~~~~~~~~~~ ``OverlapCounterBlender``, ``OverlapStdBlender``, and ``OverlapStdFeatheredBlender`` produce overlap count or dispersion rasters. They are audit products with shape ``(H, W, 1)``, not fused predictions. Experimental blenders ~~~~~~~~~~~~~~~~~~~~~ ``HuberNoConfidenceBlender`` and ``HuberSpatialBlender`` are research robust estimators with tested mask/shape contracts but no reference numerical oracle. ``BundleAdjustmentBlender`` accepts scalar radius maps only and is not part of the Stable projection path.