00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_SVD_HPP_
00039 #define PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_SVD_HPP_
00040
00042 template <typename PointSource, typename PointTarget> inline void
00043 pcl::registration::TransformationEstimationSVD<PointSource, PointTarget>::estimateRigidTransformation (
00044 const pcl::PointCloud<PointSource> &cloud_src,
00045 const pcl::PointCloud<PointTarget> &cloud_tgt,
00046 Eigen::Matrix4f &transformation_matrix)
00047 {
00048
00049 transformation_matrix.setIdentity ();
00050
00051 Eigen::Vector4f centroid_src, centroid_tgt;
00052
00053 compute3DCentroid (cloud_src, centroid_src);
00054 compute3DCentroid (cloud_tgt, centroid_tgt);
00055
00056
00057 Eigen::MatrixXf cloud_src_demean;
00058 demeanPointCloud (cloud_src, centroid_src, cloud_src_demean);
00059
00060 Eigen::MatrixXf cloud_tgt_demean;
00061 demeanPointCloud (cloud_tgt, centroid_tgt, cloud_tgt_demean);
00062
00063 getTransformationFromCorrelation (cloud_src_demean, centroid_src, cloud_tgt_demean, centroid_tgt, transformation_matrix);
00064 }
00065
00067 template <typename PointSource, typename PointTarget> void
00068 pcl::registration::TransformationEstimationSVD<PointSource, PointTarget>::estimateRigidTransformation (
00069 const pcl::PointCloud<PointSource> &cloud_src,
00070 const std::vector<int> &indices_src,
00071 const pcl::PointCloud<PointTarget> &cloud_tgt,
00072 Eigen::Matrix4f &transformation_matrix)
00073 {
00074 if (indices_src.size () != cloud_tgt.points.size ())
00075 {
00076 PCL_ERROR ("[pcl::TransformationSVD::estimateRigidTransformation] Number or points in source (%zu) differs than target (%zu)!\n", indices_src.size (), cloud_tgt.points.size ());
00077 return;
00078 }
00079
00080
00081 transformation_matrix.setIdentity ();
00082
00083 Eigen::Vector4f centroid_src, centroid_tgt;
00084
00085 compute3DCentroid (cloud_src, indices_src, centroid_src);
00086 compute3DCentroid (cloud_tgt, centroid_tgt);
00087
00088
00089 Eigen::MatrixXf cloud_src_demean;
00090 demeanPointCloud (cloud_src, indices_src, centroid_src, cloud_src_demean);
00091
00092 Eigen::MatrixXf cloud_tgt_demean;
00093 demeanPointCloud (cloud_tgt, centroid_tgt, cloud_tgt_demean);
00094
00095 getTransformationFromCorrelation (cloud_src_demean, centroid_src, cloud_tgt_demean, centroid_tgt, transformation_matrix);
00096 }
00097
00098
00100 template <typename PointSource, typename PointTarget> inline void
00101 pcl::registration::TransformationEstimationSVD<PointSource, PointTarget>::estimateRigidTransformation (
00102 const pcl::PointCloud<PointSource> &cloud_src,
00103 const std::vector<int> &indices_src,
00104 const pcl::PointCloud<PointTarget> &cloud_tgt,
00105 const std::vector<int> &indices_tgt,
00106 Eigen::Matrix4f &transformation_matrix)
00107 {
00108 if (indices_src.size () != indices_tgt.size ())
00109 {
00110 PCL_ERROR ("[pcl::TransformationEstimationSVD::estimateRigidTransformation] Number or points in source (%zu) differs than target (%zu)!\n", indices_src.size (), indices_tgt.size ());
00111 return;
00112 }
00113
00114
00115 transformation_matrix.setIdentity ();
00116
00117 Eigen::Vector4f centroid_src, centroid_tgt;
00118
00119 compute3DCentroid (cloud_src, indices_src, centroid_src);
00120 compute3DCentroid (cloud_tgt, indices_tgt, centroid_tgt);
00121
00122
00123 Eigen::MatrixXf cloud_src_demean;
00124 demeanPointCloud (cloud_src, indices_src, centroid_src, cloud_src_demean);
00125
00126 Eigen::MatrixXf cloud_tgt_demean;
00127 demeanPointCloud (cloud_tgt, indices_tgt, centroid_tgt, cloud_tgt_demean);
00128
00129 getTransformationFromCorrelation (cloud_src_demean, centroid_src, cloud_tgt_demean, centroid_tgt, transformation_matrix);
00130 }
00131
00133 template <typename PointSource, typename PointTarget> void
00134 pcl::registration::TransformationEstimationSVD<PointSource, PointTarget>::estimateRigidTransformation (
00135 const pcl::PointCloud<PointSource> &cloud_src,
00136 const pcl::PointCloud<PointTarget> &cloud_tgt,
00137 const pcl::Correspondences &correspondences,
00138 Eigen::Matrix4f &transformation_matrix)
00139 {
00140 std::vector<int> indices_src, indices_tgt;
00141 pcl::registration::getQueryIndices (correspondences, indices_src);
00142 pcl::registration::getMatchIndices (correspondences, indices_tgt);
00143
00144
00145 Eigen::Vector4f centroid_src, centroid_tgt;
00146
00147 compute3DCentroid (cloud_src, indices_src, centroid_src);
00148 compute3DCentroid (cloud_tgt, indices_tgt, centroid_tgt);
00149
00150
00151 Eigen::MatrixXf cloud_src_demean;
00152 demeanPointCloud (cloud_src, indices_src, centroid_src, cloud_src_demean);
00153
00154 Eigen::MatrixXf cloud_tgt_demean;
00155 demeanPointCloud (cloud_tgt, indices_tgt, centroid_tgt, cloud_tgt_demean);
00156
00157 getTransformationFromCorrelation (cloud_src_demean, centroid_src, cloud_tgt_demean, centroid_tgt, transformation_matrix);
00158 }
00159
00161 template <typename PointSource, typename PointTarget> void
00162 pcl::registration::TransformationEstimationSVD<PointSource, PointTarget>::getTransformationFromCorrelation (
00163 const Eigen::MatrixXf &cloud_src_demean,
00164 const Eigen::Vector4f ¢roid_src,
00165 const Eigen::MatrixXf &cloud_tgt_demean,
00166 const Eigen::Vector4f ¢roid_tgt,
00167 Eigen::Matrix4f &transformation_matrix)
00168 {
00169 transformation_matrix.setIdentity ();
00170
00171
00172 Eigen::Matrix3f H = (cloud_src_demean * cloud_tgt_demean.transpose ()).topLeftCorner<3, 3>();
00173
00174
00175 Eigen::JacobiSVD<Eigen::Matrix3f> svd (H, Eigen::ComputeFullU | Eigen::ComputeFullV);
00176 Eigen::Matrix3f u = svd.matrixU ();
00177 Eigen::Matrix3f v = svd.matrixV ();
00178
00179
00180 if (u.determinant () * v.determinant () < 0)
00181 {
00182 for (int x = 0; x < 3; ++x)
00183 v (x, 2) *= -1;
00184 }
00185
00186 Eigen::Matrix3f R = v * u.transpose ();
00187
00188
00189 transformation_matrix.topLeftCorner<3, 3> () = R;
00190 const Eigen::Vector3f Rc (R * centroid_src.head<3> ());
00191 transformation_matrix.block <3, 1> (0, 3) = centroid_tgt.head<3> () - Rc;
00192 }
00193
00194
00195
00196 #endif