40 #ifndef PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_SVD_SCALE_HPP_
41 #define PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_SVD_SCALE_HPP_
45 namespace registration {
47 template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
51 const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>& cloud_src_demean,
52 const Eigen::Matrix<Scalar, 4, 1>& centroid_src,
53 const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>& cloud_tgt_demean,
54 const Eigen::Matrix<Scalar, 4, 1>& centroid_tgt,
55 Matrix4& transformation_matrix)
const
57 transformation_matrix.setIdentity();
60 Eigen::Matrix<Scalar, 3, 3> H =
61 (cloud_src_demean * cloud_tgt_demean.transpose()).
template topLeftCorner<3, 3>();
64 Eigen::JacobiSVD<Eigen::Matrix<Scalar, 3, 3>> svd(
65 H, Eigen::ComputeFullU | Eigen::ComputeFullV);
66 Eigen::Matrix<Scalar, 3, 3> u = svd.matrixU();
67 Eigen::Matrix<Scalar, 3, 3> v = svd.matrixV();
70 if (u.determinant() * v.determinant() < 0) {
71 for (
int x = 0; x < 3; ++x)
75 Eigen::Matrix<Scalar, 3, 3> R = v * u.transpose();
78 Eigen::Matrix<Scalar, 4, 4> R4;
79 R4.template topLeftCorner<3, 3>() = R;
85 Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> src_ = R4 * cloud_src_demean;
87 double sum_ss = 0.0f, sum_tt = 0.0f;
88 for (
unsigned corrIdx = 0; corrIdx < cloud_src_demean.cols(); ++corrIdx) {
89 sum_ss += cloud_src_demean(0, corrIdx) * cloud_src_demean(0, corrIdx);
90 sum_ss += cloud_src_demean(1, corrIdx) * cloud_src_demean(1, corrIdx);
91 sum_ss += cloud_src_demean(2, corrIdx) * cloud_src_demean(2, corrIdx);
93 sum_tt += cloud_tgt_demean(0, corrIdx) * src_(0, corrIdx);
94 sum_tt += cloud_tgt_demean(1, corrIdx) * src_(1, corrIdx);
95 sum_tt += cloud_tgt_demean(2, corrIdx) * src_(2, corrIdx);
98 float scale = sum_tt / sum_ss;
99 transformation_matrix.template topLeftCorner<3, 3>() = scale * R;
100 const Eigen::Matrix<Scalar, 3, 1> Rc(scale * R * centroid_src.template head<3>());
101 transformation_matrix.template block<3, 1>(0, 3) =
102 centroid_tgt.template head<3>() - Rc;