15template <camera_model CameraT>
32 static auto create(
const std::vector<CameraT>& cameras,
33 const std::vector<Eigen::Isometry3d>& init_cam_se3_ref,
34 const std::vector<Eigen::Isometry3d>& init_ref_se3_tgt) ->
ExtrinsicBlocks {
35 const size_t num_cams = cameras.size();
36 const size_t num_views = init_ref_se3_tgt.size();
38 for (
size_t cam_idx = 0; cam_idx < num_cams; ++cam_idx) {
43 for (
size_t view_idx = 0; view_idx < num_views; ++view_idx) {
52 std::vector<ParamBlock> blocks;
57 [](
const auto& intr) { return ParamBlock(intr.data(), intr.size(), intr_size); });
59 [](
const auto& quat) { return ParamBlock(quat.data(), quat.size(), 3); });
61 [](
const auto& tran) { return ParamBlock(tran.data(), tran.size(), 3); });
63 [](
const auto& quat) { return ParamBlock(quat.data(), quat.size(), 3); });
65 [](
const auto& tran) { return ParamBlock(tran.data(), tran.size(), 3); });
72 result.
cameras.resize(num_cams);
73 result.
c_se3_r.resize(num_cams);
74 result.
r_se3_t.resize(num_views);
75 for (
size_t cam_idx = 0; cam_idx < num_cams; ++cam_idx) {
80 for (
size_t view_idx = 0; view_idx < num_views; ++view_idx) {
86template <camera_model CameraT>
88 const std::vector<MulticamPlanarView>& views,
89 const std::vector<CameraT>& cameras,
91 for (
size_t view_index = 0; view_index < views.size(); ++view_index) {
92 const auto& multicam_view = views[view_index];
93 for (
size_t cam_index = 0; cam_index < cameras.size(); ++cam_index) {
94 if (multicam_view[cam_index].empty()) {
97 auto* loss = options.
core.huber_delta > 0
98 ?
new ceres::HuberLoss(options.
core.huber_delta)
100 problem.AddResidualBlock(
109template <camera_model CameraT>
113 problem.SetManifold(cam_quat.data(),
new ceres::QuaternionManifold());
116 problem.SetManifold(ref_quat.data(),
new ceres::QuaternionManifold());
120 problem.SetParameterBlockConstant(intr.data());
124 problem.SetParameterBlockConstant(blocks.
ref_quat_tgt[0].data());
125 problem.SetParameterBlockConstant(blocks.
ref_tran_tgt[0].data());
130 problem.SetParameterBlockConstant(cam_quat.data());
133 problem.SetParameterBlockConstant(cam_tran.data());
137 problem.SetParameterBlockConstant(blocks.
cam_quat_ref[0].data());
138 problem.SetParameterBlockConstant(blocks.
cam_tran_ref[0].data());
146 problem.SetManifold(intr.data(),
new ceres::SubsetManifold(
152template <camera_model CameraT>
156 ceres::Problem problem;
162template <camera_model CameraT>
164 const std::vector<Eigen::Isometry3d>& init_c_se3_r,
165 const std::vector<Eigen::Isometry3d>& init_r_se3_t,
166 const std::vector<MulticamPlanarView>& views) {
167 const size_t num_cams = init_cameras.size();
168 const size_t num_views = views.size();
169 if (init_c_se3_r.size() != num_cams || init_r_se3_t.size() != num_views) {
170 throw std::invalid_argument(
"Incompatible pose vector sizes for joint optimization");
174template <camera_model CameraT>
176 const std::vector<MulticamPlanarView>& views,
const std::vector<CameraT>& init_cameras,
177 const std::vector<Eigen::Isometry3d>& init_c_se3_r,
178 const std::vector<Eigen::Isometry3d>& init_r_se3_t,
const ExtrinsicOptions& opts) {
182 ceres::Problem problem =
build_problem(views, init_cameras, opts, blocks);
187 blocks.populate_result(result);
188 if (opts.
core.compute_covariance) {
190 if (optcov.has_value()) {
200 const std::vector<Eigen::Isometry3d>&,
const std::vector<Eigen::Isometry3d>&,
206 const std::vector<Eigen::Isometry3d>&,
const std::vector<Eigen::Isometry3d>&,
Pinhole camera model with intrinsics and distortion correction.
Lens distortion models and correction algorithms.
Linear multi-camera extrinsics initialisation (DLT)
void populate_quat_tran(const Eigen::Isometry3d &pose, std::array< double, 4 > &quat, std::array< double, 3 > &translation)
static void set_residual_blocks(ceres::Problem &problem, const std::vector< MulticamPlanarView > &views, const std::vector< CameraT > &cameras, const ExtrinsicOptions &options, ExtrinsicBlocks< CameraT > &blocks)
static void set_param_constraints(ceres::Problem &problem, const ExtrinsicOptions &options, ExtrinsicBlocks< CameraT > &blocks)
auto optimize_extrinsics(const std::vector< MulticamPlanarView > &views, const std::vector< CameraT > &init_cameras, const std::vector< Eigen::Isometry3d > &init_c_se3_r, const std::vector< Eigen::Isometry3d > &init_r_se3_t, const ExtrinsicOptions &opts={}) -> ExtrinsicOptimizationResult< CameraT >
void validate_input(const std::vector< BundleObservation > &observations, const std::vector< CameraT > &initial_cameras)
Eigen::Isometry3d restore_pose(const std::array< double, 4 > &quat, const std::array< double, 3 > &translation)
auto compute_covariance(const ProblemParamBlocks &problem_param_blocks, ceres::Problem &problem, double sum_squared_residuals=0, size_t total_residuals=0) -> std::optional< Eigen::MatrixXd >
static auto build_problem(const std::vector< BundleObservation > &observations, const BundleOptions &opts, BundleBlocks< CameraT > &blocks) -> ceres::Problem
void solve_problem(ceres::Problem &problem, const OptimOptions &opts, OptimResult *result)
Type traits template for camera model implementations.
std::vector< std::array< double, 4 > > cam_quat_ref
void populate_result(ExtrinsicOptimizationResult< CameraT > &result) const
std::vector< std::array< double, 3 > > ref_tran_tgt
static auto create(const std::vector< CameraT > &cameras, const std::vector< Eigen::Isometry3d > &init_cam_se3_ref, const std::vector< Eigen::Isometry3d > &init_ref_se3_tgt) -> ExtrinsicBlocks
std::vector< std::array< double, intr_size > > intrinsics
std::vector< std::array< double, 4 > > ref_quat_tgt
std::vector< std::array< double, 3 > > cam_tran_ref
auto get_param_blocks() const -> std::vector< ParamBlock > override
ExtrinsicBlocks(size_t num_cams, size_t num_views)
static constexpr size_t intr_size
std::vector< Eigen::Isometry3d > c_se3_r
std::vector< Eigen::Isometry3d > r_se3_t
std::vector< CameraT > cameras
bool optimize_extrinsics
Solve for camera and target extrinsics.
bool optimize_skew
Solve for skew parameter.
bool optimize_intrinsics
Solve for camera intrinsics.
Eigen::MatrixXd covariance
Camera model with a tilted sensor plane (Scheimpflug configuration).