u/locusvision

I got tired of slicing 360 panoramas into cube faces, so I spent six months writing a spherical SfM engine. Solo, in Rust.

I shoot interiors with a 360 camera, and every photogrammetry tool I tried wants pinhole images. So a panorama gets cut into 6 cube faces, and one capture position becomes 6 independent cameras that the solver doesn't know share a centre. Tracks fragment at the face borders and you throw away a lot of the sphere.

I ended up writing my own engine that keeps the sphere all the way through. One panorama stays one camera with one centre. Every residual the bundle adjustment minimises is an angle on the sphere, not a pixel on a plane. The neural front-end still sees flat patches, because that is what CNNs eat, but the geometry never leaves the sphere.

The clip is a 12-panorama apartment, cold start: no known camera positions, no priors from a previous run. Cameras appear in shooting order, and each point appears when a second camera sees it, so you are roughly watching the order the solver actually had things in. 85,615 points, about 12 minutes end to end from the raw camera files, of which ~11 minutes is the neural matching stage.

Things I cannot claim yet, before anyone asks:

- No metric scale. Everything is up to a similarity transform. I have not done a tape-measure validation, that is next.

- Per panorama it is currently about 4x slower than COLMAP on cube faces. Denser, but slower.

- Two of the twelve cameras in this scene still end up a few degrees off in rotation. Working on it.

Happy to answer anything about the spherical residual, the tiling scheme, or why sub-pixel refinement that helps ordinary cameras actively hurts on 360.

u/locusvision — 10 days ago