39 #ifndef PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_LM_HPP_
40 #define PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_LM_HPP_
45 #include <unsupported/Eigen/NonLinearOptimization>
47 template <
typename Po
intSource,
typename Po
intTarget>
void
51 Eigen::Matrix4f &transformation_matrix)
55 if (cloud_src.
points.size () != cloud_tgt.
points.size ())
57 PCL_ERROR (
"[pcl::registration::TransformationEstimationLM::estimateRigidTransformation] ");
58 PCL_ERROR (
"Number or points in source (%zu) differs than target (%zu)!\n",
62 if (cloud_src.
points.size () < 4)
64 PCL_ERROR (
"[pcl::registration::TransformationEstimationLM::estimateRigidTransformation] ");
65 PCL_ERROR (
"Need at least 4 points to estimate a transform! Source and target have %zu points!\n",
74 int n_unknowns = warp_point_->getDimension ();
75 Eigen::VectorXd x (n_unknowns);
79 tmp_src_ = &cloud_src;
80 tmp_tgt_ = &cloud_tgt;
82 OptimizationFunctor functor (static_cast<int> (cloud_src.
points.size ()),
this);
83 Eigen::NumericalDiff<OptimizationFunctor> num_diff (functor);
84 Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctor>,
double> lm (num_diff);
85 int info = lm.minimize (x);
88 PCL_DEBUG (
"[pcl::registration::TransformationEstimationLM::estimateRigidTransformation]");
89 PCL_DEBUG (
"LM solver finished with exit code %i, having a residual norm of %g. \n", info, lm.fvec.norm ());
91 for (
int i = 1; i < n_unknowns; ++i)
92 PCL_DEBUG (
" %f", x[i]);
96 Eigen::VectorXf params = x.cast<
float> ();
97 warp_point_->setParam (params);
98 transformation_matrix = warp_point_->getTransform ();
105 template <
typename Po
intSource,
typename Po
intTarget>
void
108 const std::vector<int> &indices_src,
110 Eigen::Matrix4f &transformation_matrix)
112 if (indices_src.size () != cloud_tgt.
points.size ())
114 PCL_ERROR (
"[pcl::registration::TransformationEstimationLM::estimateRigidTransformation] Number or points in source (%zu) differs than target (%zu)!\n", indices_src.size (), cloud_tgt.
points.size ());
119 transformation_matrix.setIdentity ();
121 const int nr_correspondences =
static_cast<const int> (cloud_tgt.
points.size ());
122 std::vector<int> indices_tgt;
123 indices_tgt.resize(nr_correspondences);
124 for (
int i = 0; i < nr_correspondences; ++i)
127 estimateRigidTransformation(cloud_src, indices_src, cloud_tgt, indices_tgt, transformation_matrix);
131 template <
typename Po
intSource,
typename Po
intTarget>
inline void
134 const std::vector<int> &indices_src,
136 const std::vector<int> &indices_tgt,
137 Eigen::Matrix4f &transformation_matrix)
139 if (indices_src.size () != indices_tgt.size ())
141 PCL_ERROR (
"[pcl::registration::TransformationEstimationLM::estimateRigidTransformation] Number or points in source (%zu) differs than target (%zu)!\n", indices_src.size (), indices_tgt.size ());
145 if (indices_src.size () < 4)
147 PCL_ERROR (
"[pcl::IterativeClosestPointNonLinear::estimateRigidTransformationLM] ");
148 PCL_ERROR (
"Need at least 4 points to estimate a transform! Source and target have %zu points!",
149 indices_src.size ());
157 int n_unknowns = warp_point_->getDimension ();
158 Eigen::VectorXd x (n_unknowns);
159 x.setConstant (n_unknowns, 0);
162 tmp_src_ = &cloud_src;
163 tmp_tgt_ = &cloud_tgt;
164 tmp_idx_src_ = &indices_src;
165 tmp_idx_tgt_ = &indices_tgt;
167 OptimizationFunctorWithIndices functor (static_cast<int> (indices_src.size ()),
this);
168 Eigen::NumericalDiff<OptimizationFunctorWithIndices> num_diff (functor);
169 Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctorWithIndices> > lm (num_diff);
170 int info = lm.minimize (x);
173 PCL_DEBUG (
"[pcl::registration::TransformationEstimationLM::estimateRigidTransformation]");
174 PCL_DEBUG (
"LM solver finished with exit code %i, having a residual norm of %g. \n", info, lm.fvec.norm ());
176 for (
int i = 1; i < n_unknowns; ++i)
177 PCL_DEBUG (
" %f", x[i]);
181 Eigen::VectorXf params = x.cast<
float> ();
182 warp_point_->setParam (params);
183 transformation_matrix = warp_point_->getTransform ();
187 tmp_idx_src_ = tmp_idx_tgt_ = NULL;
191 template <
typename Po
intSource,
typename Po
intTarget>
inline void
196 Eigen::Matrix4f &transformation_matrix)
198 const int nr_correspondences =
static_cast<const int> (correspondences.size ());
199 std::vector<int> indices_src (nr_correspondences);
200 std::vector<int> indices_tgt (nr_correspondences);
201 for (
int i = 0; i < nr_correspondences; ++i)
203 indices_src[i] = correspondences[i].index_query;
204 indices_tgt[i] = correspondences[i].index_match;
207 estimateRigidTransformation(cloud_src, indices_src, cloud_tgt, indices_tgt, transformation_matrix);
211 template <
typename Po
intSource,
typename Po
intTarget>
int
213 const Eigen::VectorXd &x, Eigen::VectorXd &fvec)
const
219 Eigen::VectorXf params = x.cast<
float> ();
220 estimator_->warp_point_->setParam (params);
223 for (
int i = 0; i < values (); ++i)
225 const PointSource & p_src = src_points.
points[i];
226 const PointTarget & p_tgt = tgt_points.
points[i];
229 PointSource p_src_warped;
230 estimator_->warp_point_->warpPoint (p_src, p_src_warped);
233 fvec[i] = estimator_->computeDistance (p_src_warped, p_tgt);
239 template <
typename Po
intSource,
typename Po
intTarget>
int
241 const Eigen::VectorXd &x, Eigen::VectorXd &fvec)
const
245 const std::vector<int> & src_indices = *estimator_->tmp_idx_src_;
246 const std::vector<int> & tgt_indices = *estimator_->tmp_idx_tgt_;
249 Eigen::VectorXf params = x.cast<
float> ();
250 estimator_->warp_point_->setParam (params);
253 for (
int i = 0; i < values (); ++i)
255 const PointSource & p_src = src_points.
points[src_indices[i]];
256 const PointTarget & p_tgt = tgt_points.
points[tgt_indices[i]];
259 PointSource p_src_warped;
260 estimator_->warp_point_->warpPoint (p_src, p_src_warped);
263 fvec[i] = estimator_->computeDistance (p_src_warped, p_tgt);