Calibration Library 1.0.0
A C++ library for camera calibration and vision-related geometric transformations
Loading...
Searching...
No Matches
observationutils.h
Go to the documentation of this file.
1
3#pragma once
4
5// ceres
7
10#include "ceres/rotation.h"
11
12namespace calib {
13
14// templated for autodiff
15template <typename T>
16static Eigen::Matrix<T, 3, 1> array_to_translation(const T* const arr) {
17 return Eigen::Matrix<T, 3, 1>(arr[0], arr[1], arr[2]);
18}
19
20template <typename T>
21static Eigen::Matrix<T, 3, 3> quat_array_to_rotmat(const T* const arr) {
22 Eigen::Quaternion<T> quat(arr[0], arr[1], arr[2], arr[3]);
23 return quat.toRotationMatrix();
24}
25
26template <typename T>
27std::pair<Eigen::Matrix<T, 3, 3>, Eigen::Matrix<T, 3, 1>> invert_transform(
28 const Eigen::Matrix<T, 3, 3>& rotation, const Eigen::Matrix<T, 3, 1>& translation) {
29 Eigen::Matrix<T, 3, 3> rotation_t = rotation.transpose();
30 Eigen::Matrix<T, 3, 1> translation_i = -rotation_t * translation;
31 return {rotation_t, translation_i};
32}
33
34template <typename T>
35std::pair<Eigen::Matrix<T, 3, 3>, Eigen::Matrix<T, 3, 1>> product(
36 const Eigen::Matrix<T, 3, 3>& rotation1, const Eigen::Matrix<T, 3, 1>& translation1,
37 const Eigen::Matrix<T, 3, 3>& rotation2, const Eigen::Matrix<T, 3, 1>& translation2) {
38 Eigen::Matrix<T, 3, 3> rotation = rotation1 * rotation2;
39 Eigen::Matrix<T, 3, 1> translation = rotation1 * translation2 + translation1;
40 return {rotation, translation};
41}
42
43inline void populate_quat_tran(const Eigen::Isometry3d& pose, std::array<double, 4>& quat,
44 std::array<double, 3>& translation) {
45 Eigen::Quaterniond q0(pose.linear());
46 quat = {q0.w(), q0.x(), q0.y(), q0.z()};
47 translation = {pose.translation().x(), pose.translation().y(), pose.translation().z()};
48}
49
50inline Eigen::Quaterniond array_to_norm_quat(const std::array<double, 4>& arr) {
51 Eigen::Quaterniond quat(arr[0], arr[1], arr[2], arr[3]);
52 quat.normalize();
53 return quat;
54}
55
56inline Eigen::Isometry3d restore_pose(const std::array<double, 4>& quat,
57 const std::array<double, 3>& translation) {
58 auto pose = Eigen::Isometry3d::Identity();
59 pose.linear() = array_to_norm_quat(quat).toRotationMatrix();
60 pose.translation() << translation[0], translation[1], translation[2];
61 return pose;
62}
63
64// ---------- small SO(3) helpers (double) ----------
65// Utility: skew-symmetric matrix from vector
66// log(R) as a 3-vector (axis*angle)
67// ---------- stable ridge LS solve ----------
68inline Eigen::Isometry3d array_to_pose(const double* pose) {
69 Eigen::Matrix3d rotation;
70 ceres::AngleAxisToRotationMatrix(pose, rotation.data());
71 Eigen::Isometry3d se3 = Eigen::Isometry3d::Identity();
72 se3.linear() = rotation;
73 se3.translation() = Eigen::Vector3d(pose[3], pose[4], pose[5]);
74 return se3;
75}
76
77// Utility: average a set of affine transforms (rotation via quaternion averaging)
78template <typename T>
80 const PlanarView& planar_obs, std::vector<Observation<T>>& obs,
81 const Eigen::Transform<T, 3, Eigen::Isometry>& camera_se3_target) {
82 if (obs.size() != planar_obs.size()) {
83 obs.resize(planar_obs.size());
84 }
85 for (size_t i = 0; i < planar_obs.size(); ++i) {
86 const auto& planar_item = planar_obs[i];
87 // Convert pixel coordinates to normalized image coordinates
88 Eigen::Matrix<T, 3, 1> point{T(planar_item.object_xy.x()), T(planar_item.object_xy.y()),
89 T(0)};
90 point = camera_se3_target * point;
91 const T xn = point.x() / point.z();
92 const T yn = point.y() / point.z();
93 obs[i] = Observation<T>{xn, yn, T(planar_item.image_uv.x()), T(planar_item.image_uv.y())};
94 }
95}
96
97template <typename T>
98Observation<T> to_observation(const PlanarObservation& obs, const T* pose6) {
99 const T* axisangle = pose6; // angle-axis
100 const T* translation = pose6 + 3; // translation
101
102 Eigen::Matrix<T, 3, 1> point{T(obs.object_xy.x()), T(obs.object_xy.y()), T(0.0)};
103 Eigen::Matrix<T, 3, 1> point_c;
104 ceres::AngleAxisRotatePoint(axisangle, point.data(), point_c.data());
105 point_c += Eigen::Matrix<T, 3, 1>(translation[0], translation[1], translation[2]);
106 T inv_z = T(1.0) / point_c.z();
107 Observation<T> observation;
108 observation.x = point_c.x() * inv_z;
109 observation.y = point_c.y() * inv_z;
110 observation.u = T(obs.image_uv.x());
111 observation.v = T(obs.image_uv.y());
112 return observation;
113}
114
115} // namespace calib
Lens distortion models and correction algorithms.
Linear multi-camera extrinsics initialisation (DLT)
static Eigen::Matrix< T, 3, 1 > array_to_translation(const T *const arr)
void populate_quat_tran(const Eigen::Isometry3d &pose, std::array< double, 4 > &quat, std::array< double, 3 > &translation)
Eigen::Quaterniond array_to_norm_quat(const std::array< double, 4 > &arr)
static void planar_observables_to_observables(const PlanarView &planar_obs, std::vector< Observation< T > > &obs, const Eigen::Transform< T, 3, Eigen::Isometry > &camera_se3_target)
std::pair< Eigen::Matrix< T, 3, 3 >, Eigen::Matrix< T, 3, 1 > > product(const Eigen::Matrix< T, 3, 3 > &rotation1, const Eigen::Matrix< T, 3, 1 > &translation1, const Eigen::Matrix< T, 3, 3 > &rotation2, const Eigen::Matrix< T, 3, 1 > &translation2)
std::pair< Eigen::Matrix< T, 3, 3 >, Eigen::Matrix< T, 3, 1 > > invert_transform(const Eigen::Matrix< T, 3, 3 > &rotation, const Eigen::Matrix< T, 3, 1 > &translation)
static Eigen::Matrix< T, 3, 3 > quat_array_to_rotmat(const T *const arr)
Observation< T > to_observation(const PlanarObservation &obs, const T *pose6)
std::vector< PlanarObservation > PlanarView
Definition planarpose.h:26
Eigen::Isometry3d restore_pose(const std::array< double, 4 > &quat, const std::array< double, 3 > &translation)
Eigen::Isometry3d array_to_pose(const double *pose)
Observation structure for distortion parameter estimation.
Definition distortion.h:69
T y
Normalized undistorted coordinates.
Definition distortion.h:70
T v
Observed distorted pixel coordinates.
Definition distortion.h:71
Eigen::Vector2d object_xy
Definition planarpose.h:23
Eigen::Vector2d image_uv
Definition planarpose.h:24