39 #ifndef PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_POINT_TO_PLANE_WEIGHTED_HPP_
40 #define PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_POINT_TO_PLANE_WEIGHTED_HPP_
42 #include <pcl/registration/distances.h>
43 #include <pcl/registration/warp_point_rigid.h>
44 #include <pcl/registration/warp_point_rigid_6d.h>
46 #include <unsupported/Eigen/NonLinearOptimization>
49 template <
typename Po
intSource,
typename Po
intTarget,
typename MatScalar>
60 template <
typename Po
intSource,
typename Po
intTarget,
typename MatScalar>
66 Matrix4& transformation_matrix)
const
70 if (cloud_src.
size() != cloud_tgt.
size()) {
71 PCL_ERROR(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
72 "estimateRigidTransformation] ");
73 PCL_ERROR(
"Number or points in source (%zu) differs than target (%zu)!\n",
74 static_cast<std::size_t
>(cloud_src.
size()),
75 static_cast<std::size_t
>(cloud_tgt.
size()));
78 if (cloud_src.
size() < 4)
80 PCL_ERROR(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
81 "estimateRigidTransformation] ");
82 PCL_ERROR(
"Need at least 4 points to estimate a transform! Source and target have "
84 static_cast<std::size_t
>(cloud_src.
size()));
88 if (correspondence_weights_.size() != cloud_src.
size()) {
89 PCL_ERROR(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
90 "estimateRigidTransformation] ");
91 PCL_ERROR(
"Number of weights (%zu) differs than number of points (%zu)!\n",
92 correspondence_weights_.size(),
93 static_cast<std::size_t
>(cloud_src.
size()));
97 int n_unknowns = warp_point_->getDimension();
98 VectorX x(n_unknowns);
102 tmp_src_ = &cloud_src;
103 tmp_tgt_ = &cloud_tgt;
105 OptimizationFunctor functor(
static_cast<int>(cloud_src.
size()),
this);
106 Eigen::NumericalDiff<OptimizationFunctor> num_diff(functor);
107 Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctor>, MatScalar> lm(
109 int info = lm.minimize(x);
112 PCL_DEBUG(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
113 "estimateRigidTransformation]");
114 PCL_DEBUG(
"LM solver finished with exit code %i, having a residual norm of %g. \n",
117 PCL_DEBUG(
"Final solution: [%f", x[0]);
118 for (
int i = 1; i < n_unknowns; ++i)
119 PCL_DEBUG(
" %f", x[i]);
123 warp_point_->setParam(x);
124 transformation_matrix = warp_point_->getTransform();
131 template <
typename Po
intSource,
typename Po
intTarget,
typename MatScalar>
138 Matrix4& transformation_matrix)
const
140 if (indices_src.size() != cloud_tgt.
size()) {
141 PCL_ERROR(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
142 "estimateRigidTransformation] Number or points in source (%zu) differs "
143 "than target (%zu)!\n",
145 static_cast<std::size_t
>(cloud_tgt.
size()));
149 if (correspondence_weights_.size() != indices_src.size()) {
150 PCL_ERROR(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
151 "estimateRigidTransformation] ");
152 PCL_ERROR(
"Number of weights (%zu) differs than number of points (%zu)!\n",
153 correspondence_weights_.size(),
159 transformation_matrix.setIdentity();
161 const auto nr_correspondences = cloud_tgt.
size();
163 indices_tgt.resize(nr_correspondences);
164 for (std::size_t i = 0; i < nr_correspondences; ++i)
167 estimateRigidTransformation(
168 cloud_src, indices_src, cloud_tgt, indices_tgt, transformation_matrix);
172 template <
typename Po
intSource,
typename Po
intTarget,
typename MatScalar>
180 Matrix4& transformation_matrix)
const
182 if (indices_src.size() != indices_tgt.size()) {
183 PCL_ERROR(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
184 "estimateRigidTransformation] Number or points in source (%lu) differs "
185 "than target (%lu)!\n",
191 if (indices_src.size() < 4)
193 PCL_ERROR(
"[pcl::IterativeClosestPointNonLinear::estimateRigidTransformationLM] ");
194 PCL_ERROR(
"Need at least 4 points to estimate a transform! Source and target have "
200 if (correspondence_weights_.size() != indices_src.size()) {
201 PCL_ERROR(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
202 "estimateRigidTransformation] ");
203 PCL_ERROR(
"Number of weights (%lu) differs than number of points (%lu)!\n",
204 correspondence_weights_.size(),
209 int n_unknowns = warp_point_->getDimension();
211 x.setConstant(n_unknowns, 0);
214 tmp_src_ = &cloud_src;
215 tmp_tgt_ = &cloud_tgt;
216 tmp_idx_src_ = &indices_src;
217 tmp_idx_tgt_ = &indices_tgt;
220 Eigen::NumericalDiff<OptimizationFunctorWithIndices> num_diff(functor);
221 Eigen::LevenbergMarquardt<Eigen::NumericalDiff<OptimizationFunctorWithIndices>,
224 int info = lm.minimize(x);
227 PCL_DEBUG(
"[pcl::registration::TransformationEstimationPointToPlaneWeighted::"
228 "estimateRigidTransformation] LM solver finished with exit code %i, having "
229 "a residual norm of %g. \n",
232 PCL_DEBUG(
"Final solution: [%f", x[0]);
233 for (
int i = 1; i < n_unknowns; ++i)
234 PCL_DEBUG(
" %f", x[i]);
238 warp_point_->setParam(x);
239 transformation_matrix = warp_point_->getTransform();
243 tmp_idx_src_ = tmp_idx_tgt_ =
nullptr;
247 template <
typename Po
intSource,
typename Po
intTarget,
typename MatScalar>
254 Matrix4& transformation_matrix)
const
256 const int nr_correspondences =
static_cast<int>(correspondences.size());
259 for (
int i = 0; i < nr_correspondences; ++i) {
260 indices_src[i] = correspondences[i].index_query;
261 indices_tgt[i] = correspondences[i].index_match;
264 if (use_correspondence_weights_) {
265 correspondence_weights_.resize(nr_correspondences);
266 for (std::size_t i = 0; i < nr_correspondences; ++i)
267 correspondence_weights_[i] = correspondences[i].weight;
270 estimateRigidTransformation(
271 cloud_src, indices_src, cloud_tgt, indices_tgt, transformation_matrix);
275 template <
typename Po
intSource,
typename Po
intTarget,
typename MatScalar>
280 MatScalar>::OptimizationFunctor::operator()(
const VectorX& x,
VectorX& fvec)
const
286 estimator_->warp_point_->setParam(x);
290 for (
int i = 0; i < values(); ++i) {
291 const PointSource& p_src = src_points[i];
292 const PointTarget& p_tgt = tgt_points[i];
296 estimator_->warp_point_->warpPoint(p_src, p_src_warped);
299 fvec[i] = estimator_->correspondence_weights_[i] *
300 estimator_->computeDistance(p_src_warped, p_tgt);
306 template <
typename Po
intSource,
typename Po
intTarget,
typename MatScalar>
311 MatScalar>::OptimizationFunctorWithIndices::operator()(
const VectorX& x,
316 const pcl::Indices& src_indices = *estimator_->tmp_idx_src_;
317 const pcl::Indices& tgt_indices = *estimator_->tmp_idx_tgt_;
320 estimator_->warp_point_->setParam(x);
324 for (
int i = 0; i < values(); ++i) {
325 const PointSource& p_src = src_points[src_indices[i]];
326 const PointTarget& p_tgt = tgt_points[tgt_indices[i]];
330 estimator_->warp_point_->warpPoint(p_src, p_src_warped);
333 fvec[i] = estimator_->correspondence_weights_[i] *
334 estimator_->computeDistance(p_src_warped, p_tgt);
WarpPointRigid3D enables 6D (3D rotation + 3D translation) transformations for points.
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
IndicesAllocator<> Indices
Type used for indices in PCL.