Point Cloud Library (PCL)  1.15.1-dev
transformation_estimation_point_to_plane_weighted.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2009-2012, Willow Garage, Inc.
6  * Copyright (c) 2012-, Open Perception, Inc.
7  * Copyright (c) Alexandru-Eugen Ichim
8  *
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  *
15  * * Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above
18  * copyright notice, this list of conditions and the following
19  * disclaimer in the documentation and/or other materials provided
20  * with the distribution.
21  * * Neither the name of the copyright holder(s) nor the names of its
22  * contributors may be used to endorse or promote products derived
23  * from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #pragma once
40 
41 #include <pcl/registration/distances.h>
42 #include <pcl/registration/transformation_estimation_point_to_plane.h>
43 #include <pcl/registration/warp_point_rigid.h>
44 #include <pcl/memory.h>
45 #include <pcl/pcl_macros.h>
46 
47 namespace pcl {
48 namespace registration {
49 /** @b TransformationEstimationPointToPlaneWeighted uses Levenberg Marquardt
50  * optimization to find the transformation that minimizes the point-to-plane distance
51  * between the given correspondences. In addition to the
52  * TransformationEstimationPointToPlane class, this version takes per-correspondence
53  * weights and optimizes accordingly.
54  *
55  * \author Alexandru-Eugen Ichim
56  * \ingroup registration
57  */
58 template <typename PointSource, typename PointTarget, typename MatScalar = float>
60 : public TransformationEstimationPointToPlane<PointSource, PointTarget, MatScalar> {
62  using PointCloudSourcePtr = typename PointCloudSource::Ptr;
63  using PointCloudSourceConstPtr = typename PointCloudSource::ConstPtr;
64 
66 
67  using PointIndicesPtr = PointIndices::Ptr;
68  using PointIndicesConstPtr = PointIndices::ConstPtr;
69 
70 public:
71  using Ptr = shared_ptr<TransformationEstimationPointToPlaneWeighted<PointSource,
72  PointTarget,
73  MatScalar>>;
74  using ConstPtr =
75  shared_ptr<const TransformationEstimationPointToPlaneWeighted<PointSource,
76  PointTarget,
77  MatScalar>>;
78 
79  using VectorX = Eigen::Matrix<MatScalar, Eigen::Dynamic, 1>;
80  using Vector4 = Eigen::Matrix<MatScalar, 4, 1>;
81  using Matrix4 =
83 
84  /** \brief Constructor. */
86 
87  /** \brief Copy constructor.
88  * \param[in] src the TransformationEstimationPointToPlaneWeighted object to copy into
89  * this
90  */
93  : tmp_src_(src.tmp_src_)
94  , tmp_tgt_(src.tmp_tgt_)
100 
101  /** \brief Copy operator.
102  * \param[in] src the TransformationEstimationPointToPlaneWeighted object to copy into
103  * this
104  */
107  {
108  if (this == &src)
109  return *this;
110  tmp_src_ = src.tmp_src_;
111  tmp_tgt_ = src.tmp_tgt_;
114  warp_point_ = src.warp_point_;
117  return *this;
118  }
119 
120  /** \brief Destructor. */
122 
123  /** \brief Estimate a rigid rotation transformation between a source and a target
124  * point cloud using LM. \param[in] cloud_src the source point cloud dataset
125  * \param[in] cloud_tgt the target point cloud dataset
126  * \param[out] transformation_matrix the resultant transformation matrix
127  * \note Uses the weights given by setWeights.
128  */
129  inline void
131  const pcl::PointCloud<PointTarget>& cloud_tgt,
132  Matrix4& transformation_matrix) const;
133 
134  /** \brief Estimate a rigid rotation transformation between a source and a target
135  * point cloud using LM. \param[in] cloud_src the source point cloud dataset
136  * \param[in] indices_src the vector of indices describing the points of interest in
137  * \a cloud_src
138  * \param[in] cloud_tgt the target point cloud dataset
139  * \param[out] transformation_matrix the resultant transformation matrix
140  * \note Uses the weights given by setWeights.
141  */
142  inline void
144  const pcl::Indices& indices_src,
145  const pcl::PointCloud<PointTarget>& cloud_tgt,
146  Matrix4& transformation_matrix) const;
147 
148  /** \brief Estimate a rigid rotation transformation between a source and a target
149  * point cloud using LM. \param[in] cloud_src the source point cloud dataset
150  * \param[in] indices_src the vector of indices describing the points of interest in
151  * \a cloud_src
152  * \param[in] cloud_tgt the target point cloud dataset
153  * \param[in] indices_tgt the vector of indices describing the correspondences of the
154  * interest points from \a indices_src
155  * \param[out] transformation_matrix the resultant transformation matrix
156  * \note Uses the weights given by setWeights.
157  */
158  void
160  const pcl::Indices& indices_src,
161  const pcl::PointCloud<PointTarget>& cloud_tgt,
162  const pcl::Indices& indices_tgt,
163  Matrix4& transformation_matrix) const;
164 
165  /** \brief Estimate a rigid rotation transformation between a source and a target
166  * point cloud using LM. \param[in] cloud_src the source point cloud dataset
167  * \param[in] cloud_tgt the target point cloud dataset
168  * \param[in] correspondences the vector of correspondences between source and target
169  * point cloud \param[out] transformation_matrix the resultant transformation matrix
170  * \note Uses the weights given by setWeights.
171  */
172  void
174  const pcl::PointCloud<PointTarget>& cloud_tgt,
175  const pcl::Correspondences& correspondences,
176  Matrix4& transformation_matrix) const;
177 
178  inline void
179  setWeights(const std::vector<double>& weights)
180  {
181  correspondence_weights_ = weights;
182  }
183 
184  /// use the weights given in the pcl::CorrespondencesPtr for one of the
185  /// estimateTransformation (...) methods
186  inline void
187  setUseCorrespondenceWeights(bool use_correspondence_weights)
188  {
189  use_correspondence_weights_ = use_correspondence_weights;
190  }
191 
192  /** \brief Set the function we use to warp points. Defaults to rigid 6D warp.
193  * \param[in] warp_fcn a shared pointer to an object that warps points
194  */
195  void
198  {
199  warp_point_ = warp_fcn;
200  }
201 
202 protected:
204  mutable std::vector<double> correspondence_weights_{};
205 
206  /** \brief Temporary pointer to the source dataset. */
207  mutable const PointCloudSource* tmp_src_{nullptr};
208 
209  /** \brief Temporary pointer to the target dataset. */
210  mutable const PointCloudTarget* tmp_tgt_{nullptr};
211 
212  /** \brief Temporary pointer to the source dataset indices. */
213  mutable const pcl::Indices* tmp_idx_src_{nullptr};
214 
215  /** \brief Temporary pointer to the target dataset indices. */
216  mutable const pcl::Indices* tmp_idx_tgt_{nullptr};
217 
218  /** \brief The parameterized function used to warp the source to the target. */
221 
222  /** Base functor all the models that need non linear optimization must
223  * define their own one and implement operator() (const Eigen::VectorXd& x,
224  * Eigen::VectorXd& fvec) or operator() (const Eigen::VectorXf& x, Eigen::VectorXf&
225  * fvec) depending on the chosen _Scalar
226  */
227  template <typename _Scalar, int NX = Eigen::Dynamic, int NY = Eigen::Dynamic>
228  struct Functor {
229  using Scalar = _Scalar;
231  using InputType = Eigen::Matrix<_Scalar, InputsAtCompileTime, 1>;
232  using ValueType = Eigen::Matrix<_Scalar, ValuesAtCompileTime, 1>;
233  using JacobianType =
234  Eigen::Matrix<_Scalar, ValuesAtCompileTime, InputsAtCompileTime>;
235 
236  /** \brief Empty Constructor. */
238 
239  /** \brief Constructor
240  * \param[in] m_data_points number of data points to evaluate.
241  */
242  Functor(int m_data_points) : m_data_points_(m_data_points) {}
243 
244  /** \brief Destructor. */
245  virtual ~Functor() = default;
246 
247  /** \brief Get the number of values. */
248  int
249  values() const
250  {
251  return (m_data_points_);
252  }
253 
254  protected:
256  };
257 
258  struct OptimizationFunctor : public Functor<MatScalar> {
260 
261  /** Functor constructor
262  * \param[in] m_data_points the number of data points to evaluate
263  * \param[in,out] estimator pointer to the estimator object
264  */
265  OptimizationFunctor(int m_data_points,
267  : Functor<MatScalar>(m_data_points), estimator_(estimator)
268  {}
269 
270  /** Copy constructor
271  * \param[in] src the optimization functor to copy into this
272  */
274  : Functor<MatScalar>(src.m_data_points_), estimator_()
275  {
276  *this = src;
277  }
278 
279  /** Copy operator
280  * \param[in] src the optimization functor to copy into this
281  */
282  inline OptimizationFunctor&
284  {
285  if (this == &src)
286  return *this;
288  estimator_ = src.estimator_;
289  return *this;
290  }
291 
292  /** \brief Destructor. */
293  virtual ~OptimizationFunctor() = default;
294 
295  /** Fill fvec from x. For the current state vector x fill the f values
296  * \param[in] x state vector
297  * \param[out] fvec f values vector
298  */
299  int
300  operator()(const VectorX& x, VectorX& fvec) const;
301 
303  PointTarget,
304  MatScalar>* estimator_;
305  };
306 
307  struct OptimizationFunctorWithIndices : public Functor<MatScalar> {
309 
310  /** Functor constructor
311  * \param[in] m_data_points the number of data points to evaluate
312  * \param[in,out] estimator pointer to the estimator object
313  */
315  int m_data_points,
317  : Functor<MatScalar>(m_data_points), estimator_(estimator)
318  {}
319 
320  /** Copy constructor
321  * \param[in] src the optimization functor to copy into this
322  */
324  : Functor<MatScalar>(src.m_data_points_), estimator_()
325  {
326  *this = src;
327  }
328 
329  /** Copy operator
330  * \param[in] src the optimization functor to copy into this
331  */
334  {
335  if (this == &src)
336  return *this;
338  estimator_ = src.estimator_;
339  return *this;
340  }
341 
342  /** \brief Destructor. */
343  virtual ~OptimizationFunctorWithIndices() = default;
344 
345  /** Fill fvec from x. For the current state vector x fill the f values
346  * \param[in] x state vector
347  * \param[out] fvec f values vector
348  */
349  int
350  operator()(const VectorX& x, VectorX& fvec) const;
351 
353  PointTarget,
354  MatScalar>* estimator_;
355  };
356 
357 public:
359 };
360 } // namespace registration
361 } // namespace pcl
362 
363 #include <pcl/registration/impl/transformation_estimation_point_to_plane_weighted.hpp>
shared_ptr< PointCloud< PointSource > > Ptr
Definition: point_cloud.h:414
shared_ptr< const PointCloud< PointSource > > ConstPtr
Definition: point_cloud.h:415
TransformationEstimation represents the base class for methods for transformation estimation based on...
TransformationEstimationPointToPlane uses Levenberg Marquardt optimization to find the transformation...
TransformationEstimationPointToPlaneWeighted uses Levenberg Marquardt optimization to find the transf...
void setWarpFunction(const typename WarpPointRigid< PointSource, PointTarget, MatScalar >::Ptr &warp_fcn)
Set the function we use to warp points.
TransformationEstimationPointToPlaneWeighted(const TransformationEstimationPointToPlaneWeighted &src)
Copy constructor.
void setUseCorrespondenceWeights(bool use_correspondence_weights)
use the weights given in the pcl::CorrespondencesPtr for one of the estimateTransformation (....
void estimateRigidTransformation(const pcl::PointCloud< PointSource > &cloud_src, const pcl::PointCloud< PointTarget > &cloud_tgt, Matrix4 &transformation_matrix) const
Estimate a rigid rotation transformation between a source and a target point cloud using LM.
typename TransformationEstimation< PointSource, PointTarget, MatScalar >::Matrix4 Matrix4
TransformationEstimationPointToPlaneWeighted & operator=(const TransformationEstimationPointToPlaneWeighted &src)
Copy operator.
const pcl::Indices * tmp_idx_tgt_
Temporary pointer to the target dataset indices.
const pcl::Indices * tmp_idx_src_
Temporary pointer to the source dataset indices.
shared_ptr< const TransformationEstimationPointToPlaneWeighted< PointSource, PointTarget, MatScalar > > ConstPtr
virtual ~TransformationEstimationPointToPlaneWeighted()=default
Destructor.
shared_ptr< TransformationEstimationPointToPlaneWeighted< PointSource, PointTarget, MatScalar > > Ptr
pcl::registration::WarpPointRigid< PointSource, PointTarget, MatScalar >::Ptr warp_point_
The parameterized function used to warp the source to the target.
shared_ptr< WarpPointRigid< PointSourceT, PointTargetT, Scalar > > Ptr
#define PCL_MAKE_ALIGNED_OPERATOR_NEW
Macro to signal a class requires a custom allocator.
Definition: memory.h:86
Defines functions, macros and traits for allocating and using memory.
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
IndicesAllocator<> Indices
Type used for indices in PCL.
Definition: types.h:133
Defines all the PCL and non-PCL macros used.
shared_ptr< ::pcl::PointIndices > Ptr
Definition: PointIndices.h:13
shared_ptr< const ::pcl::PointIndices > ConstPtr
Definition: PointIndices.h:14
Base functor all the models that need non linear optimization must define their own one and implement...
OptimizationFunctor(int m_data_points, const TransformationEstimationPointToPlaneWeighted *estimator)
Functor constructor.
const TransformationEstimationPointToPlaneWeighted< PointSource, PointTarget, MatScalar > * estimator_
OptimizationFunctorWithIndices & operator=(const OptimizationFunctorWithIndices &src)
Copy operator.
const TransformationEstimationPointToPlaneWeighted< PointSource, PointTarget, MatScalar > * estimator_
OptimizationFunctorWithIndices(int m_data_points, const TransformationEstimationPointToPlaneWeighted *estimator)
Functor constructor.