41 #include <boost/unordered_map.hpp>
44 template <
typename Po
intSource,
typename Po
intTarget>
void
48 std::vector<int> nn_indices (1);
49 std::vector<float> nn_dists (1);
52 PointCloudTarget input_corresp;
53 input_corresp.points.resize (indices_->size ());
57 double dist_threshold = corr_dist_threshold_ * corr_dist_threshold_;
60 if (guess != Eigen::Matrix4f::Identity ())
63 final_transformation_ = guess;
69 std::vector<float> previous_correspondence_distances (indices_->size ());
70 correspondence_distances_.resize (indices_->size ());
75 previous_transformation_ = transformation_;
77 previous_correspondence_distances = correspondence_distances_;
80 std::vector<int> source_indices (indices_->size ());
81 std::vector<int> target_indices (indices_->size ());
84 for (
size_t idx = 0; idx < indices_->size (); ++idx)
86 if (!this->searchForNeighbors (output, (*indices_)[idx], nn_indices, nn_dists))
88 PCL_ERROR (
"[pcl::%s::computeTransformation] Unable to find a nearest neighbor in the target dataset for point %d in the source!\n", getClassName ().c_str (), (*indices_)[idx]);
93 if (nn_dists[0] < dist_threshold)
95 source_indices[cnt] = (*indices_)[idx];
96 target_indices[cnt] = nn_indices[0];
101 correspondence_distances_[(*indices_)[idx]] = std::min (nn_dists[0], static_cast<float> (dist_threshold));
103 if (cnt < min_number_correspondences_)
105 PCL_ERROR (
"[pcl::%s::computeTransformation] Not enough correspondences found. Relax your threshold parameters.\n", getClassName ().c_str ());
111 source_indices.resize (cnt); target_indices.resize (cnt);
113 std::vector<int> source_indices_good;
114 std::vector<int> target_indices_good;
118 typedef typename SampleConsensusModelRegistration<PointSource>::Ptr SampleConsensusModelRegistrationPtr;
119 SampleConsensusModelRegistrationPtr model;
120 model.reset (
new SampleConsensusModelRegistration<PointSource> (output.makeShared (), source_indices));
122 model->setInputTarget (target_, target_indices);
124 RandomSampleConsensus<PointSource> sac (model, inlier_threshold_);
125 sac.setMaxIterations (ransac_iterations_);
128 if (!sac.computeModel ())
130 source_indices_good = source_indices;
131 target_indices_good = target_indices;
135 std::vector<int> inliers;
137 sac.getInliers (inliers);
138 source_indices_good.resize (inliers.size ());
139 target_indices_good.resize (inliers.size ());
141 boost::unordered_map<int, int> source_to_target;
142 for (
unsigned int i = 0; i < source_indices.size(); ++i)
143 source_to_target[source_indices[i]] = target_indices[i];
146 std::copy(inliers.begin(), inliers.end(), source_indices_good.begin());
147 for (
size_t i = 0; i < inliers.size (); ++i)
148 target_indices_good[i] = source_to_target[inliers[i]];
153 cnt =
static_cast<int> (source_indices_good.size ());
154 if (cnt < min_number_correspondences_)
156 PCL_ERROR (
"[pcl::%s::computeTransformation] Not enough correspondences found. Relax your threshold parameters.\n", getClassName ().c_str ());
161 PCL_DEBUG (
"[pcl::%s::computeTransformation] Number of correspondences %d [%f%%] out of %zu points [100.0%%], RANSAC rejected: %zu [%f%%].\n",
162 getClassName ().c_str (),
164 (static_cast<float> (cnt) * 100.0f) / static_cast<float> (indices_->size ()),
166 source_indices.size () - cnt,
167 static_cast<float> (source_indices.size () - cnt) * 100.0f / static_cast<float> (source_indices.size ()));
171 transformation_estimation_->estimateRigidTransformation (output, source_indices_good, *target_, target_indices_good, transformation_);
177 final_transformation_ = transformation_ * final_transformation_;
182 if (update_visualizer_ != 0)
183 update_visualizer_(output, source_indices_good, *target_, target_indices_good );
193 if (nr_iterations_ >= max_iterations_ ||
194 (transformation_ - previous_transformation_).array ().abs ().sum () < transformation_epsilon_ ||
195 fabs (this->getFitnessScore (correspondence_distances_, previous_correspondence_distances)) <= euclidean_fitness_epsilon_
199 PCL_DEBUG (
"[pcl::%s::computeTransformation] Convergence reached. Number of iterations: %d out of %d. Transformation difference: %f\n",
200 getClassName ().c_str (), nr_iterations_, max_iterations_, (transformation_ - previous_transformation_).array ().abs ().sum ());
202 PCL_DEBUG (
"nr_iterations_ (%d) >= max_iterations_ (%d)\n", nr_iterations_, max_iterations_);
203 PCL_DEBUG (
"(transformation_ - previous_transformation_).array ().abs ().sum () (%f) < transformation_epsilon_ (%f)\n",
204 (transformation_ - previous_transformation_).array ().abs ().sum (), transformation_epsilon_);
205 PCL_DEBUG (
"fabs (getFitnessScore (correspondence_distances_, previous_correspondence_distances)) (%f) <= euclidean_fitness_epsilon_ (%f)\n",
206 fabs (this->getFitnessScore (correspondence_distances_, previous_correspondence_distances)),
207 euclidean_fitness_epsilon_);