53 if (sources_.size() != targets_.size() || sources_.empty() || targets_.empty()) {
54 PCL_ERROR(
"[pcl::%s::computeTransformation] Must set InputSources and InputTargets "
55 "to the same, nonzero size!\n",
56 getClassName().c_str());
59 bool manual_correspondence_estimations_set =
true;
60 if (correspondence_estimations_.empty()) {
61 manual_correspondence_estimations_set =
false;
62 correspondence_estimations_.resize(sources_.size());
63 for (std::size_t i = 0; i < sources_.size(); i++) {
64 correspondence_estimations_[i] = correspondence_estimation_->clone();
67 if (correspondence_estimations_.size() != sources_.size()) {
68 PCL_ERROR(
"[pcl::%s::computeTransform] Must set CorrespondenceEstimations to be "
69 "the same size as the joint\n",
70 getClassName().c_str());
73 std::vector<PointCloudSourcePtr> inputs_transformed(sources_.size());
74 for (std::size_t i = 0; i < sources_.size(); i++) {
82 final_transformation_ = guess;
85 std::vector<std::size_t> input_offsets(sources_.size());
86 std::vector<std::size_t> target_offsets(targets_.size());
90 std::size_t input_offset = 0;
91 std::size_t target_offset = 0;
92 for (std::size_t i = 0; i < sources_.size(); i++) {
94 if (guess != Matrix4::Identity()) {
96 this->transformCloud(*sources_[i], *inputs_transformed[i], guess);
99 *inputs_transformed[i] = *sources_[i];
101 *sources_combined += *sources_[i];
102 *inputs_transformed_combined += *inputs_transformed[i];
103 *targets_combined += *targets_[i];
104 input_offsets[i] = input_offset;
105 target_offsets[i] = target_offset;
106 input_offset += inputs_transformed[i]->size();
107 target_offset += targets_[i]->size();
110 transformation_ = Matrix4::Identity();
112 determineRequiredBlobData();
114 for (std::size_t i = 0; i < sources_.size(); i++) {
115 correspondence_estimations_[i]->setInputTarget(targets_[i]);
116 if (correspondence_estimations_[i]->requiresTargetNormals()) {
119 correspondence_estimations_[i]->setTargetNormals(target_blob);
124 if (!correspondence_rejectors_.empty() && need_target_blob_)
127 for (std::size_t i = 0; i < correspondence_rejectors_.size(); ++i) {
129 if (rej->requiresTargetPoints())
130 rej->setTargetPoints(targets_combined_blob);
131 if (rej->requiresTargetNormals() && target_has_normals_)
132 rej->setTargetNormals(targets_combined_blob);
135 convergence_criteria_->setMaximumIterations(max_iterations_);
136 convergence_criteria_->setRelativeMSE(euclidean_fitness_epsilon_);
137 convergence_criteria_->setTranslationThreshold(transformation_epsilon_);
138 convergence_criteria_->setRotationThreshold(1.0 - transformation_epsilon_);
141 std::vector<CorrespondencesPtr> partial_correspondences_(sources_.size());
142 for (std::size_t i = 0; i < sources_.size(); i++) {
148 previous_transformation_ = transformation_;
151 correspondences_->clear();
152 for (std::size_t i = 0; i < correspondence_estimations_.size(); i++) {
153 correspondence_estimations_[i]->setInputSource(inputs_transformed[i]);
155 if (correspondence_estimations_[i]->requiresSourceNormals()) {
158 correspondence_estimations_[i]->setSourceNormals(input_transformed_blob);
162 if (use_reciprocal_correspondence_) {
163 correspondence_estimations_[i]->determineReciprocalCorrespondences(
164 *partial_correspondences_[i], corr_dist_threshold_);
167 correspondence_estimations_[i]->determineCorrespondences(
168 *partial_correspondences_[i], corr_dist_threshold_);
170 PCL_DEBUG(
"[pcl::%s::computeTransformation] Found %d partial correspondences for "
172 getClassName().c_str(),
173 partial_correspondences_[i]->size(),
175 for (std::size_t j = 0; j < partial_correspondences_[i]->size(); j++) {
180 correspondences_->push_back(corr);
183 PCL_DEBUG(
"[pcl::%s::computeTransformation] Total correspondences: %d\n",
184 getClassName().c_str(),
185 correspondences_->size());
188 if (need_source_blob_) {
190 toPCLPointCloud2(*inputs_transformed_combined, *inputs_transformed_combined_blob);
193 for (std::size_t i = 0; i < correspondence_rejectors_.size(); ++i) {
194 PCL_DEBUG(
"Applying a correspondence rejector method: %s.\n",
195 correspondence_rejectors_[i]->getClassName().c_str());
197 PCL_DEBUG(
"Applying a correspondence rejector method: %s.\n",
198 rej->getClassName().c_str());
199 if (rej->requiresSourcePoints())
200 rej->setSourcePoints(inputs_transformed_combined_blob);
201 if (rej->requiresSourceNormals() && source_has_normals_)
202 rej->setSourceNormals(inputs_transformed_combined_blob);
203 rej->setInputCorrespondences(temp_correspondences);
204 rej->getCorrespondences(*correspondences_);
206 if (i < correspondence_rejectors_.size() - 1)
207 *temp_correspondences = *correspondences_;
211 if (correspondences_->size() < min_number_correspondences_) {
212 PCL_ERROR(
"[pcl::%s::computeTransformation] Not enough correspondences found. "
213 "Relax your threshold parameters.\n",
214 getClassName().c_str());
215 convergence_criteria_->setConvergenceState(
217 Scalar>::CONVERGENCE_CRITERIA_NO_CORRESPONDENCES);
223 transformation_estimation_->estimateRigidTransformation(
224 *inputs_transformed_combined,
230 this->transformCloud(
231 *inputs_transformed_combined, *inputs_transformed_combined, transformation_);
233 for (std::size_t i = 0; i < sources_.size(); i++) {
234 this->transformCloud(
235 *inputs_transformed[i], *inputs_transformed[i], transformation_);
239 final_transformation_ = transformation_ * final_transformation_;
247 converged_ =
static_cast<bool>((*convergence_criteria_));
248 }
while (!converged_);
250 PCL_DEBUG(
"Transformation "
251 "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%"
252 "5f\t%5f\t%5f\t%5f\n",
253 final_transformation_(0, 0),
254 final_transformation_(0, 1),
255 final_transformation_(0, 2),
256 final_transformation_(0, 3),
257 final_transformation_(1, 0),
258 final_transformation_(1, 1),
259 final_transformation_(1, 2),
260 final_transformation_(1, 3),
261 final_transformation_(2, 0),
262 final_transformation_(2, 1),
263 final_transformation_(2, 2),
264 final_transformation_(2, 3),
265 final_transformation_(3, 0),
266 final_transformation_(3, 1),
267 final_transformation_(3, 2),
268 final_transformation_(3, 3));
279 if (!manual_correspondence_estimations_set) {
280 correspondence_estimations_.clear();