Skip to content

Commit 46f15a6

Browse files
committed
Make GICP use CorrespondenceEstimation
The main benefit is that CorrespondenceEstimation is parallelized, so GICP can benefit from that. But even with 1 thread, the new code is slightly faster due to the improved way of computing the mahalanobis matrix (invert3x3SymMatrix uses the fact that the matrix is symmetric and is thus faster than the general-case .inverse()).
1 parent d3769b1 commit 46f15a6

File tree

1 file changed

+23
-31
lines changed
  • registration/include/pcl/registration/impl

1 file changed

+23
-31
lines changed

registration/include/pcl/registration/impl/gicp.hpp

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -790,11 +790,20 @@ GeneralizedIterativeClosestPoint<PointSource, PointTarget, Scalar>::
790790
base_transformation_ = Matrix4::Identity();
791791
nr_iterations_ = 0;
792792
converged_ = false;
793-
double dist_threshold = corr_dist_threshold_ * corr_dist_threshold_;
794793
pcl::Indices nn_indices(1);
795794
std::vector<float> nn_dists(1);
796795

797796
pcl::transformPointCloud(output, output, guess);
797+
pcl::registration::CorrespondenceEstimation<PointSource, PointTarget, Scalar>
798+
corr_estimation;
799+
corr_estimation.setNumberOfThreads(threads_);
800+
// setSearchMethodSource is not necessary because we do not use
801+
// determineReciprocalCorrespondences
802+
corr_estimation.setSearchMethodTarget(this->getSearchMethodTarget());
803+
corr_estimation.setInputTarget(target_);
804+
auto output_transformed = pcl::make_shared<PointCloudSource>();
805+
output_transformed->resize(output.size());
806+
pcl::Correspondences correspondences;
798807

799808
while (!converged_) {
800809
std::size_t cnt = 0;
@@ -811,36 +820,19 @@ GeneralizedIterativeClosestPoint<PointSource, PointTarget, Scalar>::
811820

812821
Eigen::Matrix3d R = transform_R.topLeftCorner<3, 3>();
813822

814-
for (std::size_t i = 0; i < N; i++) {
815-
PointSource query = output[i];
816-
query.getVector4fMap() =
817-
transformation_.template cast<float>() * query.getVector4fMap();
818-
819-
if (!searchForNeighbors(query, nn_indices, nn_dists)) {
820-
PCL_ERROR("[pcl::%s::computeTransformation] Unable to find a nearest neighbor "
821-
"in the target dataset for point %d in the source!\n",
822-
getClassName().c_str(),
823-
(*indices_)[i]);
824-
return;
825-
}
826-
827-
// Check if the distance to the nearest neighbor is smaller than the user imposed
828-
// threshold
829-
if (nn_dists[0] < dist_threshold) {
830-
Eigen::Matrix3d& C1 = (*input_covariances_)[i];
831-
Eigen::Matrix3d& C2 = (*target_covariances_)[nn_indices[0]];
832-
Eigen::Matrix3d& M = mahalanobis_[i];
833-
// M = R*C1
834-
M = R * C1;
835-
// temp = M*R' + C2 = R*C1*R' + C2
836-
Eigen::Matrix3d temp = M * R.transpose();
837-
temp += C2;
838-
// M = temp^-1
839-
M = temp.inverse();
840-
source_indices[cnt] = static_cast<int>(i);
841-
target_indices[cnt] = nn_indices[0];
842-
cnt++;
843-
}
823+
transformPointCloud(
824+
output, *output_transformed, transformation_.template cast<float>(), false);
825+
corr_estimation.setInputSource(output_transformed);
826+
corr_estimation.determineCorrespondences(correspondences, corr_dist_threshold_);
827+
cnt = 0;
828+
for (const auto& corr : correspondences) {
829+
source_indices[cnt] = corr.index_query;
830+
target_indices[cnt] = corr.index_match;
831+
const Eigen::Matrix3d& C1 = (*input_covariances_)[corr.index_query];
832+
const Eigen::Matrix3d& C2 = (*target_covariances_)[corr.index_match];
833+
pcl::invert3x3SymMatrix<Eigen::Matrix3d>(R * C1 * R.transpose() + C2,
834+
mahalanobis_[corr.index_query]);
835+
++cnt;
844836
}
845837
// Resize to the actual number of valid correspondences
846838
source_indices.resize(cnt);

0 commit comments

Comments
 (0)