orientation op• Data kinds: signal × table → table
• Call: import fullseye as fs; fs.ledger.camera_orientation_from_skyline(skyline_rows, K, sky_table, yaw_step_deg=1.0, pitch_range=(-15.0, 15.0), roll_range=(-10.0, 10.0), coarse_step_deg=2.5) (to call the implementation directly, import geocam; geocam.camera_orientation_from_skyline(skyline_rows, K, sky_table, yaw_step_deg=1.0, pitch_range=(-15.0, 15.0), roll_range=(-10.0, 10.0), coarse_step_deg=2.5); from the registry, opsgeocam.get("camera_orientation_from_skyline"))
Determines (yaw, pitch, roll) from the skyline of a photo (row per column) and the skyline of the DEM → table.
Turning the photo's boundary pixels (u, v) into camera rays and rotating them into the world with a trial pose, each column becomes an (azimuth, elevation) point. The RMS of the difference between that elevation and the elevation looked up from the DEM skyline at that azimuth is the cost of the pose. yaw is swept through a full circle in steps of yaw_step_deg and pitch and roll are grid-searched in steps of coarse_step_deg; from the minimum point it is refined to continuous values with Nelder–Mead (scipy). The skyline matching of Baatz et al. 2012, narrowed to a known position and 1 camera.
Returns the ambiguity: the curve of the best cost per yaw (yaw_profile_deg / yaw_profile_residual_deg) and the difference between the best and the 2nd valley, margin_deg (2nd valley = the minimum at least 20° away from the best). Photos showing only flat land, symmetric ridges or a half circle have several valleys and a small margin. If the margin is about the residual of coarse, the orientation is not determined (it does not silently return 1: ambiguous).
Args:
skyline_rows: (W,) output of skyline_extract (row per column).
K: (fx, fy, cx, cy).
sky_table: output of dem_skyline.
yaw_step_deg / coarse_step_deg: step of the coarse grid. pitch_range / roll_range: search range [deg].
Returns:
table: yaw_deg / pitch_deg / roll_deg / residual_deg (elevation residual RMS) /
margin_deg / runner_up_yaw_deg / ambiguous (bool) / yaw_profile_deg (M,) /
yaw_profile_residual_deg (M,) / n_columns.
• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).
• Operator provenance and references — the sources of the research/methods this op family came from.
• The canonical algorithm (author, year) and its uses are named in the family usage guide above.
• poc_public_camera_heading — py -3.11 examples/poc_public_camera_heading.py
table as input)orientation)—
*Provenance: geocam.py — GEOCAM operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.