View graph¶
The view graph is an undirected graph used in Structure from Motion: vertices are ViewIds (images / cameras in your problem), and edges carry pairwise relative geometry between two views in a TwoViewInfo (focal lengths, relative rotation, relative position, inlier counts, optional scale cues, etc.).
It is the usual bridge between feature matching / two-view verification and global or incremental pose estimation: you add an edge for each image pair with a trusted relative pose, then run rotation averaging, translation estimation, filtering, etc., on that graph.
C++ core: src/theia/sfm/view_graph/view_graph.h. Pairwise metadata: twoview_info.h.
ViewGraph API¶
Vertices are implied by any ViewId that appears in an edge or that you treat as present (there is no separate “add vertex” call—AddEdge adds endpoints as needed).
| Method | Meaning |
|---|---|
AddEdge(view_id_1, view_id_2, two_view_info) |
Add or update the undirected edge \((v_1, v_2)\). |
RemoveEdge(view_id_1, view_id_2) |
Remove edge; returns whether it existed. |
RemoveView(view_id) |
Remove vertex and all incident edges. |
HasView / HasEdge |
Query existence. |
NumViews / NumEdges |
Counts. |
GetNeighborIdsForView(view_id) |
Neighbors (read-only set); None if view missing. |
GetEdge / GetMutableEdge |
Access TwoViewInfo for an edge. |
GetAllEdges |
Map \((\min id,\max id)\rightarrow\) TwoViewInfo (each edge once). |
ReadFromDisk / WriteToDisk |
cereal serialization of the graph. |
!!! note "Python bindings"
`ExtractSubgraph` and `GetLargestConnectedComponentIds` are **not** currently exposed in pybind (see `sfm.cc`). You can still prune the graph by removing views/edges from Python or by operating on edge lists you build yourself.
TwoViewInfo¶
Stores relative pose of view 2 with respect to view 1, with view 1 at the origin and identity rotation by convention:
focal_length_1,focal_length_2rotation_2— angle-axis (Ceres convention) for \(R_2\)position_2— center of camera 2 in the coordinate system of camera 1num_verified_matches,num_homography_inliers,visibility_score,scale_estimate— bookkeeping for reconstruction heuristics
Use EstimateTwoViewInfo (and related filters) to populate edges from raw matches; see Pose and SfM.
Graph-level utilities¶
These free functions in pytheia.sfm operate on a ViewGraph or on parallel structures:
RelativeRotationsFromViewGraph— builds the sparse relative-rotation problem input for global rotation solvers (see Global pose estimation).FilterViewGraphCyclesByRotation— consistency filtering on the rotation graph.RemoveDisconnectedViewPairs— drops pairs that are not in the main connected structure (parameters in the C++ headers underview_graph/).FilterViewPairsFromOrientation,FilterViewPairsFromRelativeTranslation— thin inconsistent translations / orientations.
Matching and geometric verification that create the initial edges are outside this module (Python OpenCV / learning-based matchers, or your own pipeline).
Typical workflow¶
- Build a
ViewGraph. - For each verified image pair,
AddEdgewith a filledTwoViewInfo. - Filter edges (cycles, translation, disconnects) as needed.
- Feed
RelativeRotationsFromViewGraph(or incremental seeding) into global pose estimation or an incremental reconstructor. - Produce a
Reconstruction; triangulate and run bundle adjustment.
See also¶
- SfM —
ReconstructionEstimator, view/track types - Global pose estimation — rotation / position from a view graph
- Triangulation — 3D points from known poses