41#ifndef PCL_REGISTRATION_IMPL_ICP_HPP_
42#define PCL_REGISTRATION_IMPL_ICP_HPP_
44#include <pcl/correspondence.h>
49template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
54 Eigen::Vector4f pt(0.0f, 0.0f, 0.0f, 1.0f), pt_t;
55 Eigen::Matrix4f tr = transform.template cast<float>();
60 Eigen::Vector3f nt, nt_t;
61 Eigen::Matrix3f rot = tr.block<3, 3>(0, 0);
63 for (std::size_t i = 0; i < input.size(); ++i) {
64 const auto* data_in =
reinterpret_cast<const std::uint8_t*
>(&input[i]);
65 auto* data_out =
reinterpret_cast<std::uint8_t*
>(&output[i]);
70 if (!std::isfinite(pt[0]) || !std::isfinite(pt[1]) || !std::isfinite(pt[2]))
73 pt_t.noalias() = tr * pt;
83 if (!std::isfinite(nt[0]) || !std::isfinite(nt[1]) || !std::isfinite(nt[2]))
86 nt_t.noalias() = rot * nt;
94 for (std::size_t i = 0; i < input.size(); ++i) {
95 const auto* data_in =
reinterpret_cast<const std::uint8_t*
>(&input[i]);
96 auto* data_out =
reinterpret_cast<std::uint8_t*
>(&output[i]);
101 if (!std::isfinite(pt[0]) || !std::isfinite(pt[1]) || !std::isfinite(pt[2]))
104 pt_t.noalias() = tr * pt;
113template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
128 if (guess != Matrix4::Identity()) {
129 input_transformed->resize(
input_->size());
134 *input_transformed = *
input_;
151 if (rej->requiresTargetPoints())
152 rej->setTargetPoints(target_blob);
154 rej->setTargetNormals(target_blob);
190 PCL_DEBUG(
"Applying a correspondence rejector method: %s.\n",
191 rej->getClassName().c_str());
192 if (rej->requiresSourcePoints())
193 rej->setSourcePoints(input_transformed_blob);
195 rej->setSourceNormals(input_transformed_blob);
196 rej->setInputCorrespondences(temp_correspondences);
205 PCL_ERROR(
"[pcl::%s::computeTransformation] Not enough correspondences found. "
206 "Relax your threshold parameters.\n",
210 Scalar>::CONVERGENCE_CRITERIA_NO_CORRESPONDENCES);
231 source_indices_good.emplace_back(corr.index_query);
232 target_indices_good.emplace_back(corr.index_match);
235 *input_transformed, source_indices_good, *
target_, target_indices_good);
238 converged_ =
static_cast<bool>((*convergence_criteria_));
241 Scalar>::CONVERGENCE_CRITERIA_NOT_CONVERGED);
244 PCL_DEBUG(
"Transformation "
245 "is:\n\t%5f\t%5f\t%5f\t%5f\n\t%5f\t%5f\t%5f\t%5f\n\t%5f\t%5f\t%5f\t%5f\n\t%"
246 "5f\t%5f\t%5f\t%5f\n",
270template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
281 PCL_WARN(
"[pcl::%s::determineRequiredBlobData] Estimator expects source normals, "
282 "but we can't provide them.\n",
285 if (correspondence_estimation_->requiresTargetNormals() && !target_has_normals_) {
286 PCL_WARN(
"[pcl::%s::determineRequiredBlobData] Estimator expects target normals, "
287 "but we can't provide them.\n",
288 getClassName().c_str());
291 for (std::size_t i = 0; i < correspondence_rejectors_.size(); i++) {
298 PCL_WARN(
"[pcl::%s::determineRequiredBlobData] Rejector %s expects source "
299 "normals, but we can't provide them.\n",
301 rej->getClassName().c_str());
303 if (rej->requiresTargetNormals() && !target_has_normals_) {
304 PCL_WARN(
"[pcl::%s::determineRequiredBlobData] Rejector %s expects target "
305 "normals, but we can't provide them.\n",
306 getClassName().c_str(),
307 rej->getClassName().c_str());
312template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
typename Registration< PointSource, PointTarget, Scalar >::Matrix4 Matrix4
std::size_t y_idx_offset_
std::size_t nz_idx_offset_
bool use_reciprocal_correspondence_
The correspondence type used for correspondence estimation.
std::size_t ny_idx_offset_
bool need_source_blob_
Checks for whether estimators and rejectors need various data.
pcl::registration::DefaultConvergenceCriteria< Scalar >::Ptr convergence_criteria_
bool source_has_normals_
Internal check whether source dataset has normals or not.
virtual void transformCloud(const PointCloudSource &input, PointCloudSource &output, const Matrix4 &transform)
Apply a rigid transform to a given dataset.
virtual void determineRequiredBlobData()
Looks at the Estimators and Rejectors and determines whether their blob-setter methods need to be cal...
std::size_t nx_idx_offset_
Normal fields offset.
typename Registration< PointSource, PointTarget, Scalar >::PointCloudSource PointCloudSource
void computeTransformation(PointCloudSource &output, const Matrix4 &guess) override
Rigid transformation computation method with initial guess.
bool target_has_normals_
Internal check whether target dataset has normals or not.
typename PointCloudSource::Ptr PointCloudSourcePtr
std::size_t z_idx_offset_
std::size_t x_idx_offset_
XYZ fields offset.
typename IterativeClosestPoint< PointSource, PointTarget, Scalar >::Matrix4 Matrix4
typename IterativeClosestPoint< PointSource, PointTarget, Scalar >::PointCloudSource PointCloudSource
void transformCloud(const PointCloudSource &input, PointCloudSource &output, const Matrix4 &transform) override
Apply a rigid transform to a given dataset.
PointCloudConstPtr input_
Matrix4 final_transformation_
std::function< UpdateVisualizerCallbackSignature > update_visualizer_
double corr_dist_threshold_
CorrespondenceEstimationPtr correspondence_estimation_
Matrix4 previous_transformation_
CorrespondencesPtr correspondences_
TransformationEstimationPtr transformation_estimation_
double transformation_rotation_epsilon_
unsigned int min_number_correspondences_
double euclidean_fitness_epsilon_
double transformation_epsilon_
std::vector< CorrespondenceRejectorPtr > correspondence_rejectors_
PointCloudTargetConstPtr target_
const std::string & getClassName() const
shared_ptr< CorrespondenceRejector > Ptr
DefaultConvergenceCriteria represents an instantiation of ConvergenceCriteria, and implements the fol...
void transformPointCloudWithNormals(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Matrix< Scalar, 4, 4 > &transform, bool copy_all_fields)
Transform a point cloud and rotate its normals using an Eigen transform.
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
shared_ptr< Correspondences > CorrespondencesPtr
IndicesAllocator<> Indices
Type used for indices in PCL.
void toPCLPointCloud2(const pcl::PointCloud< PointT > &cloud, pcl::PCLPointCloud2 &msg, bool padding)
Convert a pcl::PointCloud<T> object to a PCLPointCloud2 binary data blob.
Correspondence represents a match between two entities (e.g., points, descriptors,...
shared_ptr< ::pcl::PCLPointCloud2 > Ptr