Calibration Library 1.0.0
A C++ library for camera calibration and vision-related geometric transformations
Loading...
Searching...
No Matches
extrinsics.h
Go to the documentation of this file.
1
3#pragma once
4
5// std
6#include <string>
7#include <vector>
8
9// eigen
10#include <Eigen/Geometry>
11
16
17namespace calib {
18
19// [camera]
20using MulticamPlanarView = std::vector<PlanarView>;
21
22struct ExtrinsicPoses final {
23 std::vector<Eigen::Isometry3d> c_se3_r; // reference->camera
24 std::vector<Eigen::Isometry3d> r_se3_t; // target->reference
25};
26
27template <camera_model CameraT>
28auto estimate_extrinsic_dlt(const std::vector<MulticamPlanarView>& views,
29 const std::vector<CameraT>& cameras) -> ExtrinsicPoses {
30 if (views.empty() || cameras.empty()) {
31 throw std::runtime_error("Empty views or cameras provided");
32 }
33
34 const size_t num_cameras = cameras.size();
35 const size_t num_views = views.size();
36
37 // Step 1: Per-view camera poses relative to a transient reference (the target)
38 std::vector<std::vector<Eigen::Isometry3d>> cam_se3_ref(
39 num_views, std::vector<Eigen::Isometry3d>(num_cameras, Eigen::Isometry3d::Identity()));
40
41 for (size_t view_idx = 0; view_idx < num_views; ++view_idx) {
42 const auto& view = views[view_idx];
43 if (view.size() != num_cameras) {
44 throw std::runtime_error(
45 "View " + std::to_string(view_idx) + " has wrong number of cameras: expected " +
46 std::to_string(num_cameras) + ", got " + std::to_string(view.size()));
47 }
48 for (size_t cam_idx = 0; cam_idx < num_cameras; ++cam_idx) {
49 cam_se3_ref[view_idx][cam_idx] = estimate_planar_pose(view[cam_idx], cameras[cam_idx]);
50 }
51 }
52
53 // Step 2: Compute relative camera poses c_se3_r: relative to camera 0
54 std::vector<Eigen::Isometry3d> c_se3_r(num_cameras, Eigen::Isometry3d::Identity());
55 for (size_t cam_idx = 1; cam_idx < num_cameras; ++cam_idx) {
56 std::vector<Eigen::Isometry3d> rels;
57 for (size_t view_idx = 0; view_idx < num_views; ++view_idx) {
58 const auto& obs_ref = views[view_idx][0];
59 const auto& obs_cam = views[view_idx][cam_idx];
60 if (obs_ref.size() < 4 || obs_cam.size() < 4) continue;
61 rels.push_back(cam_se3_ref[view_idx][cam_idx] * cam_se3_ref[view_idx][0].inverse());
62 }
63 if (!rels.empty()) c_se3_r[cam_idx] = average_isometries(rels);
64 }
65
66 // Step 3: Compute target poses r_se3_t per view
67 std::vector<Eigen::Isometry3d> r_se3_t(num_views, Eigen::Isometry3d::Identity());
68 for (size_t view_idx = 0; view_idx < num_views; ++view_idx) {
69 std::vector<Eigen::Isometry3d> tposes;
70 for (size_t cam_idx = 0; cam_idx < num_cameras; ++cam_idx) {
71 if (views[view_idx][cam_idx].size() < 4) continue;
72 tposes.push_back(c_se3_r[cam_idx].inverse() * cam_se3_ref[view_idx][cam_idx]);
73 }
74 if (!tposes.empty()) r_se3_t[view_idx] = average_isometries(tposes);
75 }
76
77 return ExtrinsicPoses{c_se3_r, r_se3_t};
78}
79
80static_assert(serializable_aggregate<ExtrinsicPoses>);
81
82} // namespace calib
Linear multi-camera extrinsics initialisation (DLT)
Eigen::Isometry3d average_isometries(const std::vector< Eigen::Isometry3d > &poses)
Definition se3_utils.h:75
auto estimate_planar_pose(PlanarView view, const CameraMatrix &intrinsics) -> Eigen::Isometry3d
std::vector< PlanarView > MulticamPlanarView
Definition extrinsics.h:20
auto estimate_extrinsic_dlt(const std::vector< MulticamPlanarView > &views, const std::vector< CameraT > &cameras) -> ExtrinsicPoses
Definition extrinsics.h:28
Pinhole camera model with intrinsics and distortion.
std::vector< Eigen::Isometry3d > c_se3_r
Definition extrinsics.h:23
std::vector< Eigen::Isometry3d > r_se3_t
Definition extrinsics.h:24