Skip to content

Commit ff20238

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 ff20238

File tree

1 file changed

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

1 file changed

+23
-30
lines changed

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

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,16 @@ GeneralizedIterativeClosestPoint<PointSource, PointTarget, Scalar>::
795795
std::vector<float> nn_dists(1);
796796

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

799809
while (!converged_) {
800810
std::size_t cnt = 0;
@@ -811,36 +821,19 @@ GeneralizedIterativeClosestPoint<PointSource, PointTarget, Scalar>::
811821

812822
Eigen::Matrix3d R = transform_R.topLeftCorner<3, 3>();
813823

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-
}
824+
transformPointCloud(
825+
output, *output_transformed, transformation_.template cast<float>(), false);
826+
corr_estimation.setInputSource(output_transformed);
827+
corr_estimation.determineCorrespondences(correspondences, corr_dist_threshold_);
828+
cnt = 0;
829+
for (const auto& corr : correspondences) {
830+
source_indices[cnt] = corr.index_query;
831+
target_indices[cnt] = corr.index_match;
832+
const Eigen::Matrix3d& C1 = (*input_covariances_)[corr.index_query];
833+
const Eigen::Matrix3d& C2 = (*target_covariances_)[corr.index_match];
834+
pcl::invert3x3SymMatrix<Eigen::Matrix3d>(R * C1 * R.transpose() + C2,
835+
mahalanobis_[corr.index_query]);
836+
++cnt;
844837
}
845838
// Resize to the actual number of valid correspondences
846839
source_indices.resize(cnt);

0 commit comments

Comments
 (0)