Extract and match spherical features

Level: Start · Strategy: Projection-domain · Stability: Stable face-based feature route

SphericalFeaturePipeline samples views, runs the planar detector, lifts every accepted point to a unit bearing and suppresses overlap duplicates.

from panorai.features import SphericalFeaturePipeline

pipeline = SphericalFeaturePipeline.from_preset(
    "sift-flann",
    face_sampler="icosahedron",
    face_shape_hw=(256, 256),
)
features_a = pipeline.extract(erp_a, panorama_id="a")
features_b = pipeline.extract(erp_b, panorama_id="b")
matches = pipeline.match(features_a, features_b)
bearings = matches.to_bearing_correspondences()

The result retains face pixels, ERP pixels, bearings, descriptors and provenance. Descriptor matches are candidates; pose estimation performs the geometric verification.

Inputs and outputs

erp_a and erp_b are NumPy ERPs. If either image has unobserved or invalid directions, pass its explicit support/validity mask through the documented pipeline configuration; do not encode invalidity as black RGB. Each extracted feature contains its unit bearing and origin face, which is the representation consumed by spherical geometry.

matches records descriptor indices and scores. Calling to_bearing_correspondences() produces paired unit vectors, not verified 3-D points and not metric motion.

First diagnostics

Before pose estimation, plot accepted bearings over both ERPs and inspect:

  • angular coverage instead of raw match count;

  • concentration at face edges or the ERP seam;

  • repeated structures that survive the ratio test;

  • the number removed by reciprocal matching and angular NMS.

If the scene is mostly rotational, distant or textureless, descriptor matches may look plausible while translation remains unobservable.

Next: understand projected features.