37#ifndef PCL_REGISTRATION_IMPL_IA_KFPCS_H_
38#define PCL_REGISTRATION_IMPL_IA_KFPCS_H_
44template <
typename Po
intSource,
typename Po
intTarget,
typename NormalT,
typename Scalar>
53 reg_name_ =
"pcl::registration::KFPCSInitialAlignment";
56template <
typename Po
intSource,
typename Po
intTarget,
typename NormalT,
typename Scalar>
62 PCL_WARN(
"[%s::initCompute] Delta should be set according to keypoint precision! "
63 "Normalization according to point cloud density is ignored.\n",
95 std::size_t nr_indices =
indices_->size();
105template <
typename Po
intSource,
typename Po
intTarget,
typename NormalT,
typename Scalar>
109 std::vector<pcl::Indices>& matches,
115 for (
auto& match : matches) {
116 Eigen::Matrix4f transformation_temp;
118 float fitness_score =
126 if (
validateMatch(base_indices, match, correspondences_temp, transformation_temp) <
135 candidates.push_back(
140template <
typename Po
intSource,
typename Po
intTarget,
typename NormalT,
typename Scalar>
150 const std::size_t nr_points = source_transformed.
size();
151 float score_a = 0.f, score_b = 0.f;
155 std::vector<float> dists_sqr;
156 for (PointCloudSourceIterator it = source_transformed.
begin(),
157 it_e = source_transformed.
end();
161 tree_->nearestKSearch(*it, 1, ids, dists_sqr);
173 float trl = transformation.rightCols<1>().head(3).norm();
178 (trl_ratio < 0.f ? 1.f
179 : (trl_ratio > 1.f ? 0.f
186 float fitness_score_temp = (score_a +
lambda_ * score_b) / scale;
187 if (fitness_score_temp > fitness_score)
190 fitness_score = fitness_score_temp;
194template <
typename Po
intSource,
typename Po
intTarget,
typename NormalT,
typename Scalar>
197 const std::vector<MatchingCandidates>& candidates)
200 std::size_t total_size = 0;
201 for (
const auto& candidate : candidates)
202 total_size += candidate.size();
207 for (
const auto& candidate : candidates)
208 for (
const auto& match : candidate)
231template <
typename Po
intSource,
typename Po
intTarget,
typename NormalT,
typename Scalar>
239 for (MatchingCandidates::iterator it_candidate =
candidates_.begin(),
241 it_candidate != it_e;
244 if (it_candidate->fitness_score == FLT_MAX)
250 MatchingCandidates::iterator it = candidates.begin(), it_e2 = candidates.end();
251 while (unique && it != it_e2) {
252 Eigen::Matrix4f diff =
253 it_candidate->transformation.colPivHouseholderQr().solve(it->transformation);
254 const float angle3d = Eigen::AngleAxisf(diff.block<3, 3>(0, 0)).angle();
255 const float translation3d = diff.block<3, 1>(0, 3).norm();
256 unique = angle3d > min_angle3d && translation3d > min_translation3d;
262 candidates.push_back(*it_candidate);
265 if (candidates.size() == n)
270template <
typename Po
intSource,
typename Po
intTarget,
typename NormalT,
typename Scalar>
278 for (MatchingCandidates::iterator it_candidate =
candidates_.begin(),
280 it_candidate != it_e;
283 if (it_candidate->fitness_score > t)
289 MatchingCandidates::iterator it = candidates.begin(), it_e2 = candidates.end();
290 while (unique && it != it_e2) {
291 Eigen::Matrix4f diff =
292 it_candidate->transformation.colPivHouseholderQr().solve(it->transformation);
293 const float angle3d = Eigen::AngleAxisf(diff.block<3, 3>(0, 0)).angle();
294 const float translation3d = diff.block<3, 1>(0, 3).norm();
295 unique = angle3d > min_angle3d && translation3d > min_translation3d;
301 candidates.push_back(*it_candidate);
PointCloudConstPtr input_
iterator begin() noexcept
Matrix4 final_transformation_
pcl::PointCloud< PointSource > PointCloudSource
CorrespondencesPtr correspondences_
float coincidation_limit_
virtual void linkMatchWithBase(const pcl::Indices &base_indices, pcl::Indices &match_indices, pcl::Correspondences &correspondences)
float max_inlier_dist_sqr_
virtual int validateMatch(const pcl::Indices &base_indices, const pcl::Indices &match_indices, const pcl::Correspondences &correspondences, Eigen::Matrix4f &transformation)
virtual bool initCompute()
Internal computation initialization.
void getTBestCandidates(float t, float min_angle3d, float min_translation3d, MatchingCandidates &candidates)
Get all unique candidate matches with fitness scores above a threshold t.
pcl::IndicesPtr indices_validation_
Subset of input indices on which we evaluate candidates.
float upper_trl_boundary_
Upper boundary for translation costs calculation.
void finalCompute(const std::vector< MatchingCandidates > &candidates) override
Final computation of best match out of vector of matches.
void handleMatches(const pcl::Indices &base_indices, std::vector< pcl::Indices > &matches, MatchingCandidates &candidates) override
Method to handle current candidate matches.
float lambda_
Weighting factor for translation costs (standard = 0.5).
KFPCSInitialAlignment()
Constructor.
void getNBestCandidates(int n, float min_angle3d, float min_translation3d, MatchingCandidates &candidates)
Get the N best unique candidate matches according to their fitness score.
MatchingCandidates candidates_
Container for resulting vector of registration candidates.
int validateTransformation(Eigen::Matrix4f &transformation, float &fitness_score) override
Validate the transformation by calculating the score value after transforming the input source cloud.
float lower_trl_boundary_
Lower boundary for translation costs calculation.
bool use_trl_score_
Flag if translation score should be used in validation (internal calculation).
bool initCompute() override
Internal computation initialization.
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.
std::vector< MatchingCandidate, Eigen::aligned_allocator< MatchingCandidate > > MatchingCandidates
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
IndicesAllocator<> Indices
Type used for indices in PCL.
Container for matching candidate consisting of.
Sorting of candidates based on fitness score value.