MRPT  1.9.9
ba_internals.h
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2010 Hauke Strasdat
3  * Imperial College London
4  * Copyright (c) 2005-2018, Individual contributors, see AUTHORS file
5  * See: http://www.mrpt.org/Authors - All rights reserved.
6  *
7  * bundle_adjuster.h is part of RobotVision.
8  *
9  * RobotVision is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as
11  * published by the Free Software Foundation, either version 3 of the
12  * License, or any later version.
13  *
14  * RobotVision is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * and the GNU Lesser General Public License along with this program.
21  * If not, see <http://www.gnu.org/licenses/>.
22  */
23 #ifndef ba_internals_H
24 #define ba_internals_H
25 
28 #include <mrpt/poses/CPose3D.h>
30 #include <mrpt/vision/types.h>
31 
32 #include <array>
33 
34 // Declarations shared between ba_*.cpp files, but which are private to MRPT
35 // not to be seen by an MRPT API user.
36 
37 namespace mrpt::vision
38 {
39 using mrpt::math::CArrayDouble; // Allow these "using"s since these headers are
40 // internal to mrpt
42 using std::vector;
43 
44 #define VERBOSE_COUT \
45  if (verbose) cout
46 
47 // Auxiliary struct for keeping the list of all Jacobians in a sparse, efficient
48 // way.
49 template <int FrameDof, int PointDof, int ObsDim>
50 struct JacData
51 {
52  inline JacData()
55  J_frame_valid(false),
56  J_point_valid(false)
57  {
58  }
59 
62 
63  // Jacobians of the observation wrt the camera pose & the point:
67 
68  MRPT_MAKE_ALIGNED_OPERATOR_NEW // Needed by any struct having
69  // Eigen::Matrix<> fields
70 };
71 
72 /** The projective camera 2x6 Jacobian \f$ \frac{\partial h(f,p)}{\partial p}
73  * \f$ (wrt the 6D camera pose)
74  * \note Jacobians as described in
75  * http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty
76  * (Appendix A)
77  */
78 template <bool POSES_ARE_INVERSE>
79 void frameJac(
80  const mrpt::img::TCamera& camera_params,
81  const mrpt::poses::CPose3D& cam_pose,
82  const mrpt::math::TPoint3D& landmark_global,
84 {
85  using mrpt::square;
86 
87  double x, y, z; // wrt cam (local coords)
88  if (POSES_ARE_INVERSE)
89  cam_pose.composePoint(
90  landmark_global.x, landmark_global.y, landmark_global.z, x, y, z);
91  else
92  cam_pose.inverseComposePoint(
93  landmark_global.x, landmark_global.y, landmark_global.z, x, y, z);
94 
95  ASSERT_(z != 0);
96  const double _z = 1.0 / z;
97  const double fx_z = camera_params.fx() * _z;
98  const double fy_z = camera_params.fy() * _z;
99  const double _z2 = square(_z);
100  const double fx_z2 = camera_params.fx() * _z2;
101  const double fy_z2 = camera_params.fy() * _z2;
102 
103  if (POSES_ARE_INVERSE)
104  {
105  const double xy = x * y;
106 
107  const double J_vals[] = {fx_z,
108  0,
109  -fx_z2 * x,
110  -fx_z2 * xy,
111  camera_params.fx() * (1 + square(x * _z)),
112  -fx_z * y,
113  0,
114  fy_z,
115  -fy_z2 * y,
116  -camera_params.fy() * (1 + square(y * _z)),
117  fy_z2 * xy,
118  fy_z * x};
119  out_J.loadFromArray(J_vals);
120  }
121  else
122  {
123  const mrpt::math::CMatrixDouble33& R = cam_pose.getRotationMatrix();
124 
125  const double jac_proj_vals[] = {fx_z, 0, -fx_z2 * x,
126  0, fy_z, -fy_z2 * y};
128  jac_proj_vals);
129 
130  const double p_x = cam_pose.x();
131  const double p_y = cam_pose.y();
132  const double p_z = cam_pose.z();
133  const double tx = landmark_global.x - p_x;
134  const double ty = landmark_global.y - p_y;
135  const double tz = landmark_global.z - p_z;
136 
137  const double aux_vals[] = {
138  -R(0, 0),
139  -R(1, 0),
140  -R(2, 0),
141  tz * R(1, 0) - ty * R(2, 0) + R(1, 0) * p_z - R(2, 0) * p_y,
142  tx * R(2, 0) - tz * R(0, 0) - R(0, 0) * p_z + R(2, 0) * p_x,
143  ty * R(0, 0) - tx * R(1, 0) + R(0, 0) * p_y - R(1, 0) * p_x,
144  -R(0, 1),
145  -R(1, 1),
146  -R(2, 1),
147  tz * R(1, 1) - ty * R(2, 1) + R(1, 1) * p_z - R(2, 1) * p_y,
148  tx * R(2, 1) - tz * R(0, 1) - R(0, 1) * p_z + R(2, 1) * p_x,
149  ty * R(0, 1) - tx * R(1, 1) + R(0, 1) * p_y - R(1, 1) * p_x,
150  -R(0, 2),
151  -R(1, 2),
152  -R(2, 2),
153  tz * R(1, 2) - ty * R(2, 2) + R(1, 2) * p_z - R(2, 2) * p_y,
154  tx * R(2, 2) - tz * R(0, 2) - R(0, 2) * p_z + R(2, 2) * p_x,
155  ty * R(0, 2) - tx * R(1, 2) + R(0, 2) * p_y - R(1, 2) * p_x};
157  out_J.multiply_AB(jac_proj, vals);
158  }
159 }
160 
161 /** Jacobians wrt the point
162  * \note Jacobians as described in
163  * http://www.mrpt.org/6D_poses:equivalences_compositions_and_uncertainty
164  * (Appendix A)
165  */
166 template <bool POSES_ARE_INVERSE>
167 void pointJac(
168  const mrpt::img::TCamera& camera_params,
169  const mrpt::poses::CPose3D& cam_pose,
170  const mrpt::math::TPoint3D& landmark_global,
172 {
173  using namespace mrpt::math;
174 
175  mrpt::math::TPoint3D l; // Local point, wrt camera
176 
178 
179  if (POSES_ARE_INVERSE)
180  cam_pose.composePoint(
181  landmark_global.x, landmark_global.y, landmark_global.z, l.x, l.y,
182  l.z, &dp_point);
183  else
184  cam_pose.inverseComposePoint(
185  landmark_global.x, landmark_global.y, landmark_global.z, l.x, l.y,
186  l.z, &dp_point);
187 
188  ASSERT_(l.z != 0);
189  const double _z = 1.0 / l.z;
190  const double _z2 = square(_z);
191 
192  const double tmp_vals[] = {
193  camera_params.fx() * _z, 0,
194  -camera_params.fx() * l.x * _z2, 0,
195  camera_params.fy() * _z, -camera_params.fy() * l.y * _z2};
197 
198  out_J.multiply_AB(tmp, dp_point);
199 }
200 
201 // === Compute sparse Jacobians ====
202 // Case: 6D poses + 3D points + 2D (x,y) observations
203 // For the case of *inverse* or *normal* frame poses being estimated.
204 // Made inline so immediate values in "poses_are_inverses" are propragated by
205 // the compiler
206 template <bool POSES_ARE_INVERSE>
208  const TFramePosesVec& frame_poses,
209  const TLandmarkLocationsVec& landmark_points,
210  const mrpt::img::TCamera& camera_params,
212  const size_t num_fix_frames, const size_t num_fix_points)
213 {
214  MRPT_START
215 
216  // num_fix_frames & num_fix_points: Are relative to the order in frame_poses
217  // & landmark_points
218  ASSERT_(!frame_poses.empty() && !landmark_points.empty());
219  const size_t N = jac_data_vec.size();
220 
221  for (size_t i = 0; i < N; i++)
222  {
223  JacData<6, 3, 2>& D = jac_data_vec[i];
224 
225  const TCameraPoseID i_f = D.frame_id;
226  const TLandmarkID i_p = D.point_id;
227 
228  ASSERTDEB_(i_f < frame_poses.size());
229  ASSERTDEB_(i_p < landmark_points.size());
230 
231  if (i_f >= num_fix_frames)
232  {
233  frameJac<POSES_ARE_INVERSE>(
234  camera_params, frame_poses[i_f], landmark_points[i_p],
235  D.J_frame);
236  D.J_frame_valid = true;
237  }
238 
239  if (i_p >= num_fix_points)
240  {
241  pointJac<POSES_ARE_INVERSE>(
242  camera_params, frame_poses[i_f], landmark_points[i_p],
243  D.J_point);
244  D.J_point_valid = true;
245  }
246  }
247  MRPT_END
248 }
249 
250 /** Construct the BA linear system.
251  * Set kernel_1st_deriv!=nullptr if using robust kernel.
252  */
254  const TSequenceFeatureObservations& observations,
255  const std::vector<std::array<double, 2>>& residual_vec,
256  const mrpt::aligned_std_vector<JacData<6, 3, 2>>& jac_data_vec,
261  const size_t num_fix_frames, const size_t num_fix_points,
262  const vector<double>* kernel_1st_deriv);
263 }
264 #endif
265 
266 
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:140
mrpt::math::CMatrixFixedNumeric< double, ObsDim, PointDof > J_point
Definition: ba_internals.h:65
uint64_t TCameraPoseID
Unique IDs for camera frames (poses)
#define MRPT_START
Definition: exceptions.h:262
GLdouble GLdouble z
Definition: glext.h:3872
uint64_t TLandmarkID
Unique IDs for landmarks.
double fx() const
Get the value of the focal length x-value (in pixels).
Definition: TCamera.h:163
double fy() const
Get the value of the focal length y-value (in pixels).
Definition: TCamera.h:165
CArrayNumeric is an array for numeric types supporting several mathematical operations (actually...
Definition: CArrayNumeric.h:25
void pointJac(const mrpt::img::TCamera &camera_params, const mrpt::poses::CPose3D &cam_pose, const mrpt::math::TPoint3D &landmark_global, mrpt::math::CMatrixFixedNumeric< double, 2, 3 > &out_J)
Jacobians wrt the point.
Definition: ba_internals.h:167
#define MRPT_MAKE_ALIGNED_OPERATOR_NEW
Put this macro inside any class with members that require {16,32,64}-byte memory alignment (e...
std::vector< T, mrpt::aligned_allocator_cpp11< T > > aligned_std_vector
TCameraPoseID frame_id
Definition: ba_internals.h:60
A complete sequence of observations of features from different camera frames (poses).
T square(const T x)
Inline function for the square of a number.
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
CArrayNumeric< double, N > CArrayDouble
A partial specialization of CArrayNumeric for double numbers.
Definition: CArrayNumeric.h:64
GLbyte ty
Definition: glext.h:6092
Classes for computer vision, detectors, features, etc.
Definition: CCamModel.h:18
Structure to hold the parameters of a pinhole camera model.
Definition: TCamera.h:27
double x
X,Y,Z coordinates.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
const float R
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
void ba_compute_Jacobians(const TFramePosesVec &frame_poses, const TLandmarkLocationsVec &landmark_points, const mrpt::img::TCamera &camera_params, mrpt::aligned_std_vector< JacData< 6, 3, 2 >> &jac_data_vec, const size_t num_fix_frames, const size_t num_fix_points)
Definition: ba_internals.h:207
void ba_build_gradient_Hessians(const TSequenceFeatureObservations &observations, const std::vector< std::array< double, 2 >> &residual_vec, const mrpt::aligned_std_vector< JacData< 6, 3, 2 >> &jac_data_vec, mrpt::aligned_std_vector< mrpt::math::CMatrixFixedNumeric< double, 6, 6 >> &U, mrpt::aligned_std_vector< CArrayDouble< 6 >> &eps_frame, mrpt::aligned_std_vector< mrpt::math::CMatrixFixedNumeric< double, 3, 3 >> &V, mrpt::aligned_std_vector< CArrayDouble< 3 >> &eps_point, const size_t num_fix_frames, const size_t num_fix_points, const vector< double > *kernel_1st_deriv)
Construct the BA linear system.
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
Definition: exceptions.h:205
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
Definition: CPose3D.cpp:379
#define MRPT_END
Definition: exceptions.h:266
mrpt::aligned_std_vector< mrpt::poses::CPose3D > TFramePosesVec
A list of camera frames (6D poses), which assumes indexes are unique, consecutive IDs...
mrpt::math::CMatrixFixedNumeric< double, ObsDim, FrameDof > J_frame
Definition: ba_internals.h:64
GLbyte GLbyte tz
Definition: glext.h:6092
GLenum GLint GLint y
Definition: glext.h:3538
void frameJac(const mrpt::img::TCamera &camera_params, const mrpt::poses::CPose3D &cam_pose, const mrpt::math::TPoint3D &landmark_global, mrpt::math::CMatrixFixedNumeric< double, 2, 6 > &out_J)
The projective camera 2x6 Jacobian (wrt the 6D camera pose)
Definition: ba_internals.h:79
GLenum GLint x
Definition: glext.h:3538
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:230
Lightweight 3D point.
std::vector< mrpt::math::TPoint3D > TLandmarkLocationsVec
A list of landmarks (3D points), which assumes indexes are unique, consecutive IDs.
TLandmarkID point_id
Definition: ba_internals.h:61
void inverseComposePoint(const double gx, const double gy, const double gz, double &lx, double &ly, double &lz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr) const
Computes the 3D point L such as .
Definition: CPose3D.cpp:649



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020