40 #ifndef IA_RANSAC_HPP_
41 #define IA_RANSAC_HPP_
46 template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
void
49 if (features == NULL || features->empty ())
51 PCL_ERROR (
"[pcl::%s::setSourceFeatures] Invalid or empty point cloud dataset given!\n", getClassName ().c_str ());
54 input_features_ = features;
58 template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
void
61 if (features == NULL || features->empty ())
63 PCL_ERROR (
"[pcl::%s::setTargetFeatures] Invalid or empty point cloud dataset given!\n", getClassName ().c_str ());
66 target_features_ = features;
67 feature_tree_->setInputCloud (target_features_);
71 template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
void
73 const PointCloudSource &cloud,
int nr_samples,
float min_sample_distance,
74 std::vector<int> &sample_indices)
76 if (nr_samples > static_cast<int> (cloud.points.size ()))
78 PCL_ERROR (
"[pcl::%s::selectSamples] ", getClassName ().c_str ());
79 PCL_ERROR (
"The number of samples (%d) must not be greater than the number of points (%zu)!\n",
80 nr_samples, cloud.points.size ());
85 int iterations_without_a_sample = 0;
86 int max_iterations_without_a_sample =
static_cast<int> (3 * cloud.points.size ());
87 sample_indices.clear ();
88 while (static_cast<int> (sample_indices.size ()) < nr_samples)
91 int sample_index = getRandomIndex (static_cast<int> (cloud.points.size ()));
94 bool valid_sample =
true;
95 for (
size_t i = 0; i < sample_indices.size (); ++i)
97 float distance_between_samples =
euclideanDistance (cloud.points[sample_index], cloud.points[sample_indices[i]]);
99 if (sample_index == sample_indices[i] || distance_between_samples < min_sample_distance)
101 valid_sample =
false;
109 sample_indices.push_back (sample_index);
110 iterations_without_a_sample = 0;
114 ++iterations_without_a_sample;
118 if (iterations_without_a_sample >= max_iterations_without_a_sample)
120 PCL_WARN (
"[pcl::%s::selectSamples] ", getClassName ().c_str ());
121 PCL_WARN (
"No valid sample found after %d iterations. Relaxing min_sample_distance_ to %f\n",
122 iterations_without_a_sample, 0.5*min_sample_distance);
124 min_sample_distance_ *= 0.5f;
125 min_sample_distance = min_sample_distance_;
126 iterations_without_a_sample = 0;
133 template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
void
135 const FeatureCloud &input_features,
const std::vector<int> &sample_indices,
136 std::vector<int> &corresponding_indices)
138 std::vector<int> nn_indices (k_correspondences_);
139 std::vector<float> nn_distances (k_correspondences_);
141 corresponding_indices.resize (sample_indices.size ());
142 for (
size_t i = 0; i < sample_indices.size (); ++i)
145 feature_tree_->nearestKSearch (input_features, sample_indices[i], k_correspondences_, nn_indices, nn_distances);
148 int random_correspondence = getRandomIndex (k_correspondences_);
149 corresponding_indices[i] = nn_indices[random_correspondence];
154 template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
float
156 const PointCloudSource &cloud,
float)
158 std::vector<int> nn_index (1);
159 std::vector<float> nn_distance (1);
161 const ErrorFunctor & compute_error = *error_functor_;
164 for (
int i = 0; i < static_cast<int> (cloud.points.size ()); ++i)
167 tree_->nearestKSearch (cloud, i, 1, nn_index, nn_distance);
170 error += compute_error (nn_distance[0]);
176 template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
void
179 if (!input_features_)
181 PCL_ERROR (
"[pcl::%s::computeTransformation] ", getClassName ().c_str ());
182 PCL_ERROR (
"No source features were given! Call setSourceFeatures before aligning.\n");
185 if (!target_features_)
187 PCL_ERROR (
"[pcl::%s::computeTransformation] ", getClassName ().c_str ());
188 PCL_ERROR (
"No target features were given! Call setTargetFeatures before aligning.\n");
194 error_functor_.reset (
new TruncatedError (static_cast<float> (corr_dist_threshold_)));
197 std::vector<int> sample_indices (nr_samples_);
198 std::vector<int> corresponding_indices (nr_samples_);
199 PointCloudSource input_transformed;
200 float error, lowest_error (0);
202 final_transformation_ = guess;
204 if (!guess.isApprox(Eigen::Matrix4f::Identity (), 0.01f))
207 lowest_error = computeErrorMetric (input_transformed, static_cast<float> (corr_dist_threshold_));
211 for (; i_iter < max_iterations_; ++i_iter)
214 selectSamples (*input_, nr_samples_, min_sample_distance_, sample_indices);
217 findSimilarFeatures (*input_features_, sample_indices, corresponding_indices);
220 transformation_estimation_->estimateRigidTransformation (*input_, sample_indices, *target_, corresponding_indices, transformation_);
224 error = computeErrorMetric (input_transformed, static_cast<float> (corr_dist_threshold_));
227 if (i_iter == 0 || error < lowest_error)
229 lowest_error = error;
230 final_transformation_ = transformation_;
238 #endif //#ifndef IA_RANSAC_HPP_