ADR 0007: Equidistant fisheye lens optics
Status: accepted (2026-10-19), the ONE R values measured on ONE R footage, the Euler order provisional; the ONE R's coverage set by ADR 0019
Context
Stitching needs to turn a direction in space into the pixel a lens saw, and back. The Insta360 v1 calibration gives, per lens, a fisheye radius, a center, and a yaw/pitch/roll pose (ADR 0003). It does not give a field of view or a focal length, it does not say how the fisheye maps angles to pixels, and it does not say how far out the image is usable. Those have to be chosen, and the choice governs where every output pixel samples the lenses.
Decision
- The lens is an equidistant fisheye: the pixel distance from the lens centre is proportional to the angle from the optical axis,
r = f · θ. This is the simplest fisheye model and the one the v1 calibration is written for. - Two angles describe a lens, and they are kept apart.
fieldOfViewis the mapping: the full angle that reaches the calibrationradius, sof = radius / (fieldOfView / 2).coverageis how much of the sphere the lens is trusted to image, which sets where the overlap with the other lens is and so how wide the seam blend can be. They differ because the illuminated image extends pastradius. Tying them together forces a choice between a correct mapping with almost no overlap and a usable overlap with a wrong mapping. - Both are per-camera-model constants the reader supplies, not read from the file, the same kind of external fact as a camera's IMU frame. For the ONE R they are measured on ONE R footage: the mapping at 183 degrees is where the two lenses' log brightness correlates best across a fixed band on the seam (
stitch/seamCorrelation, consistent across three freefall frames where the scene is far away and parallax is negligible; 193 degrees visibly doubles the seam), and the coverage is 185 degrees, about 1.011 times the radius, inside the illuminated circle's dark border (ADR 0019;format/insta360/recording.ts). - The pose maps the lens frame to the camera frame by yaw about Z, pitch about X and roll about Y, composed as a quaternion. Projecting a camera-frame direction rotates it into the lens frame first; unprojecting a pixel rotates the recovered lens-frame direction back out. Roll is about Y so the back lens's near-180-degree roll flips the optical axis to the far hemisphere and keeps the two lenses' azimuth in register; the same roll about X would leave the hemispheres 180 degrees apart. This was confirmed by stitching the real ONE R: the wrong axis put the same object at opposite longitudes in the two lenses.
- Projection reports where a direction lands and how much to trust it: the pixel, the
reach(distance from the centre overradius, which exceeds 1 inside the coverage past the radius), and themargininside the coverage, so the stitch can pick a lens and weight the overlap (ADR 0008).
Consequences
- The optics are pure core, tested by round-tripping a direction through project then unproject and by known-angle cases, independent of any camera. Their agreement with the real lens is measured on footage, not asserted by a unit test; the developer harness (
stitch/preview.test.ts) sweeps the mapping and reports the seam correlation for exactly that. - The mapping, coverage and pose convention are where a wrong assumption shows up as a visibly wrong stitch; each is an isolated constant, and
LensProjectionstays a union that a unified or Mei model can join if equidistant proves too coarse away from the seam. The Euler order and the small pitch and yaw axes are not yet distinguished by the one ONE R calibration available (its pitch and yaw are under a degree) and stay provisional until another camera or the authoritative reference pins them. - Acceleration, timing and stabilization are untouched here; optics is only the direction-to-pixel map.