41#ifndef PCL_REGISTRATION_SAMPLE_CONSENSUS_PREREJECTIVE_HPP_
42#define PCL_REGISTRATION_SAMPLE_CONSENSUS_PREREJECTIVE_HPP_
46template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
53 "[pcl::%s::setSourceFeatures] Invalid or empty point cloud dataset given!\n",
60template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
67 "[pcl::%s::setTargetFeatures] Invalid or empty point cloud dataset given!\n",
75template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
80 if (nr_samples >
static_cast<int>(cloud.size())) {
81 PCL_ERROR(
"[pcl::%s::selectSamples] ",
getClassName().c_str());
82 PCL_ERROR(
"The number of samples (%d) must not be greater than the number of "
85 static_cast<std::size_t
>(cloud.size()));
89 sample_indices.resize(nr_samples);
93 for (
int i = 0; i < nr_samples; i++) {
95 sample_indices[i] =
getRandomIndex(
static_cast<int>(cloud.size()) - i);
98 for (
int j = 0; j < i; j++) {
101 if (sample_indices[i] >= sample_indices[j]) {
107 temp_sample = sample_indices[i];
108 for (
int k = i; k > j; k--)
109 sample_indices[k] = sample_indices[k - 1];
111 sample_indices[j] = temp_sample;
118template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
122 std::vector<pcl::Indices>& similar_features,
126 corresponding_indices.resize(sample_indices.size());
130 for (std::size_t i = 0; i < sample_indices.size(); ++i) {
132 const auto& idx = sample_indices[i];
136 if (similar_features[idx].empty())
140 similar_features[idx],
145 corresponding_indices[i] = similar_features[idx][0];
147 corresponding_indices[i] =
152template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
159 PCL_ERROR(
"[pcl::%s::computeTransformation] ",
getClassName().c_str());
161 "No source features were given! Call setSourceFeatures before aligning.\n");
165 PCL_ERROR(
"[pcl::%s::computeTransformation] ",
getClassName().c_str());
167 "No target features were given! Call setTargetFeatures before aligning.\n");
172 PCL_ERROR(
"[pcl::%s::computeTransformation] ",
getClassName().c_str());
173 PCL_ERROR(
"The source points and source feature points need to be in a one-to-one "
174 "relationship! Current input cloud sizes: %ld vs %ld.\n",
181 PCL_ERROR(
"[pcl::%s::computeTransformation] ",
getClassName().c_str());
182 PCL_ERROR(
"The target points and target feature points need to be in a one-to-one "
183 "relationship! Current input cloud sizes: %ld vs %ld.\n",
189 if (inlier_fraction_ < 0.0f || inlier_fraction_ > 1.0f) {
190 PCL_ERROR(
"[pcl::%s::computeTransformation] ",
getClassName().c_str());
191 PCL_ERROR(
"Illegal inlier fraction %f, must be in [0,1]!\n",
inlier_fraction_);
195 const float similarity_threshold =
197 if (similarity_threshold < 0.0f || similarity_threshold >= 1.0f) {
198 PCL_ERROR(
"[pcl::%s::computeTransformation] ",
getClassName().c_str());
199 PCL_ERROR(
"Illegal prerejection similarity threshold %f, must be in [0,1[!\n",
200 similarity_threshold);
205 PCL_ERROR(
"[pcl::%s::computeTransformation] ",
getClassName().c_str());
206 PCL_ERROR(
"Illegal correspondence randomness %d, must be > 0!\n",
216 int num_rejections = 0;
221 float lowest_error = std::numeric_limits<float>::max();
226 float inlier_fraction;
230 if (!guess.isApprox(Eigen::Matrix4f::Identity(), 0.01f)) {
233 static_cast<float>(inliers.size()) /
static_cast<float>(
input_->size());
237 lowest_error = error;
243 std::vector<pcl::Indices> similar_features(
input_->size());
259 corresponding_indices)) {
282 static_cast<float>(inliers.size()) /
static_cast<float>(
input_->size());
287 lowest_error = error;
298 PCL_DEBUG(
"[pcl::%s::computeTransformation] Rejected %i out of %i generated pose "
305template <
typename Po
intSource,
typename Po
intTarget,
typename FeatureT>
312 inliers.reserve(
input_->size());
313 fitness_score = 0.0f;
320 input_transformed.resize(
input_->size());
324 for (std::size_t i = 0; i < input_transformed.size(); ++i) {
327 std::vector<float> nn_dists(1);
328 tree_->nearestKSearch(input_transformed[i], 1, nn_indices, nn_dists);
331 if (nn_dists[0] < max_range) {
333 inliers.push_back(i);
336 fitness_score += nn_dists[0];
341 if (!inliers.empty())
342 fitness_score /=
static_cast<float>(inliers.size());
344 fitness_score = std::numeric_limits<float>::max();
PointCloudConstPtr input_
Matrix4 final_transformation_
The final transformation matrix estimated by the registration method after N iterations.
double corr_dist_threshold_
The maximum distance threshold between two correspondent points in source <-> target.
Matrix4 transformation_
The transformation matrix estimated by the registration method.
KdTreePtr tree_
A pointer to the spatial search object.
bool converged_
Holds internal convergence state, given user parameters.
TransformationEstimationPtr transformation_estimation_
A TransformationEstimation object, used to calculate the 4x4 rigid transformation.
int max_iterations_
The maximum number of iterations the internal optimization should run for.
PointCloudTargetConstPtr target_
The input point cloud dataset target.
const std::string & getClassName() const
Abstract class get name method.
float inlier_fraction_
The fraction [0,1] of inlier points required for accepting a transformation.
pcl::Indices inliers_
Inlier points of final transformation as indices into source.
FeatureCloudConstPtr input_features_
The source point cloud's feature descriptors.
FeatureKdTreePtr feature_tree_
The KdTree used to compare feature descriptors.
void setTargetFeatures(const FeatureCloudConstPtr &features)
Provide a boost shared pointer to the target point cloud's feature descriptors.
CorrespondenceRejectorPolyPtr correspondence_rejector_poly_
The polygonal correspondence rejector used for prerejection.
void computeTransformation(PointCloudSource &output, const Eigen::Matrix4f &guess) override
Rigid transformation computation method.
typename FeatureCloud::ConstPtr FeatureCloudConstPtr
typename Registration< PointSource, PointTarget >::PointCloudSource PointCloudSource
void findSimilarFeatures(const pcl::Indices &sample_indices, std::vector< pcl::Indices > &similar_features, pcl::Indices &corresponding_indices)
For each of the sample points, find a list of points in the target cloud whose features are similar t...
void setSourceFeatures(const FeatureCloudConstPtr &features)
Provide a boost shared pointer to the source point cloud's feature descriptors.
FeatureCloudConstPtr target_features_
The target point cloud's feature descriptors.
void selectSamples(const PointCloudSource &cloud, int nr_samples, pcl::Indices &sample_indices)
Select nr_samples sample points from cloud while making sure that their pairwise distances are greate...
int getRandomIndex(int n) const
Choose a random index between 0 and n-1.
int nr_samples_
The number of samples to use during each iteration.
typename Registration< PointSource, PointTarget >::Matrix4 Matrix4
int k_correspondences_
The number of neighbors to use when selecting a random feature correspondence.
void getFitness(pcl::Indices &inliers, float &fitness_score)
Obtain the fitness of a transformation The following metrics are calculated, based on final_transform...
void transformPointCloud(const pcl::PointCloud< PointT > &cloud_in, pcl::PointCloud< PointT > &cloud_out, const Eigen::Matrix< Scalar, 4, 4 > &transform, bool copy_all_fields)
Apply a rigid transform defined by a 4x4 matrix.
IndicesAllocator<> Indices
Type used for indices in PCL.