ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
TransformationEstimation.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "pipelines/registration/TransformationEstimation.h"
9 
10 #include <Eigen.h>
11 #include <ecvPointCloud.h>
12 
13 #include <Eigen/Geometry>
14 
15 namespace cloudViewer {
16 namespace pipelines {
17 namespace registration {
18 
20  const ccPointCloud &source,
21  const ccPointCloud &target,
22  const CorrespondenceSet &corres) const {
23  if (corres.empty()) return 0.0;
24  double err = 0.0;
25  for (const auto &c : corres) {
26  err += (source.getEigenPoint(c[0]) - target.getEigenPoint(c[1]))
27  .squaredNorm();
28  }
29  return std::sqrt(err / (double)corres.size());
30 }
31 
33  const ccPointCloud &source,
34  const ccPointCloud &target,
35  const CorrespondenceSet &corres) const {
36  if (corres.empty()) return Eigen::Matrix4d::Identity();
37  Eigen::MatrixXd source_mat(3, corres.size());
38  Eigen::MatrixXd target_mat(3, corres.size());
39  for (size_t i = 0; i < corres.size(); i++) {
40  source_mat.block<3, 1>(0, i) = source.getEigenPoint(corres[i][0]);
41  target_mat.block<3, 1>(0, i) = target.getEigenPoint(corres[i][1]);
42  }
43  return Eigen::umeyama(source_mat, target_mat, with_scaling_);
44 }
45 
47  const ccPointCloud &source,
48  const ccPointCloud &target,
49  const CorrespondenceSet &corres) const {
50  if (corres.empty() || target.hasNormals() == false) return 0.0;
51  double err = 0.0, r;
52  for (const auto &c : corres) {
53  r = (source.getEigenPoint(c[0]) - target.getEigenPoint(c[1]))
54  .dot(target.getEigenNormal(c[1]));
55  err += r * r;
56  }
57  return std::sqrt(err / (double)corres.size());
58 }
59 
61  const ccPointCloud &source,
62  const ccPointCloud &target,
63  const CorrespondenceSet &corres) const {
64  if (corres.empty() || target.hasNormals() == false)
65  return Eigen::Matrix4d::Identity();
66 
67  auto compute_jacobian_and_residual = [&](int i, Eigen::Vector6d &J_r,
68  double &r, double &w) {
69  const Eigen::Vector3d &vs = source.getEigenPoint(corres[i][0]);
70  const Eigen::Vector3d &vt = target.getEigenPoint(corres[i][1]);
71  const Eigen::Vector3d &nt = target.getEigenNormal(corres[i][1]);
72  r = (vs - vt).dot(nt);
73  w = kernel_->Weight(r);
74  J_r.block<3, 1>(0, 0) = vs.cross(nt);
75  J_r.block<3, 1>(3, 0) = nt;
76  };
77 
78  Eigen::Matrix6d JTJ;
79  Eigen::Vector6d JTr;
80  double r2;
81  std::tie(JTJ, JTr, r2) =
84  compute_jacobian_and_residual, (int)corres.size());
85 
86  bool is_success;
87  Eigen::Matrix4d extrinsic;
88  std::tie(is_success, extrinsic) =
90  JTJ, JTr);
91 
92  return is_success ? extrinsic : Eigen::Matrix4d::Identity();
93 };
94 
95 } // namespace registration
96 } // namespace pipelines
97 } // namespace cloudViewer
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
Eigen::Vector3d getEigenNormal(size_t index) const
bool hasNormals() const override
Returns whether normals are enabled or not.
Eigen::Vector3d getEigenPoint(size_t index) const
std::shared_ptr< RobustKernel > kernel_
shared_ptr to an Abstract RobustKernel that could mutate at runtime.
double ComputeRMSE(const ccPointCloud &source, const ccPointCloud &target, const CorrespondenceSet &corres) const override
Eigen::Matrix4d ComputeTransformation(const ccPointCloud &source, const ccPointCloud &target, const CorrespondenceSet &corres) const override
bool with_scaling_
Set to True to estimate scaling, False to force scaling to be 1.
Eigen::Matrix4d ComputeTransformation(const ccPointCloud &source, const ccPointCloud &target, const CorrespondenceSet &corres) const override
double ComputeRMSE(const ccPointCloud &source, const ccPointCloud &target, const CorrespondenceSet &corres) const override
__host__ __device__ float dot(float2 a, float2 b)
Definition: cutil_math.h:1119
Eigen::Matrix< double, 6, 1 > Vector6d
Definition: Eigen.h:107
Eigen::Matrix< double, 6, 6 > Matrix6d
Extending Eigen namespace by adding frequently used matrix type.
Definition: Eigen.h:106
std::vector< Eigen::Vector2i > CorrespondenceSet
std::tuple< bool, Eigen::Matrix4d > SolveJacobianSystemAndObtainExtrinsicMatrix(const Eigen::Matrix6d &JTJ, const Eigen::Vector6d &JTr)
Definition: Eigen.cpp:105
std::tuple< MatType, VecType, double > ComputeJTJandJTr(std::function< void(int, VecType &, double &, double &)> f, int iteration_num, bool verbose=true)
Definition: Eigen.cpp:148
Generic file read and write utility for python interface.