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_POINT_TO_PLANE_LLS_HPP_
00039 #define PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_POINT_TO_PLANE_LLS_HPP_
00040
00042 template <typename PointSource, typename PointTarget> inline void
00043 pcl::registration::TransformationEstimationPointToPlaneLLS<PointSource, PointTarget>::
00044 estimateRigidTransformation (const pcl::PointCloud<PointSource> &cloud_src,
00045 const pcl::PointCloud<PointTarget> &cloud_tgt,
00046 Eigen::Matrix4f &transformation_matrix)
00047 {
00048 size_t nr_points = cloud_src.points.size ();
00049 if (cloud_tgt.points.size () != nr_points)
00050 {
00051 PCL_ERROR ("[pcl::TransformationSVD::estimateRigidTransformation] Number or points in source (%zu) differs than target (%zu)!\n", nr_points, cloud_tgt.points.size ());
00052 return;
00053 }
00054
00055
00056 Eigen::MatrixXf A (nr_points, 6);
00057 Eigen::MatrixXf b (nr_points, 1);
00058 for (size_t i = 0; i < nr_points; ++i)
00059 {
00060 const float & sx = cloud_src.points[i].x;
00061 const float & sy = cloud_src.points[i].y;
00062 const float & sz = cloud_src.points[i].z;
00063 const float & dx = cloud_tgt.points[i].x;
00064 const float & dy = cloud_tgt.points[i].y;
00065 const float & dz = cloud_tgt.points[i].z;
00066 const float & nx = cloud_tgt.points[i].normal[0];
00067 const float & ny = cloud_tgt.points[i].normal[1];
00068 const float & nz = cloud_tgt.points[i].normal[2];
00069 A (i, 0) = nz*sy - ny*sz;
00070 A (i, 1) = nx*sz - nz*sx;
00071 A (i, 2) = ny*sx - nx*sy;
00072 A (i, 3) = nx;
00073 A (i, 4) = ny;
00074 A (i, 5) = nz;
00075 b (i, 0) = nx*dx + ny*dy + nz*dz - nx*sx - ny*sy - nz*sz;
00076 }
00077
00078
00079 Eigen::VectorXf x = A.colPivHouseholderQr ().solve (b);
00080
00081
00082 constructTransformationMatrix (x (0), x (1), x (2), x (3), x (4), x (5), transformation_matrix);
00083
00084 }
00085
00087 template <typename PointSource, typename PointTarget> void
00088 pcl::registration::TransformationEstimationPointToPlaneLLS<PointSource, PointTarget>::
00089 estimateRigidTransformation (const pcl::PointCloud<PointSource> &cloud_src,
00090 const std::vector<int> &indices_src,
00091 const pcl::PointCloud<PointTarget> &cloud_tgt,
00092 Eigen::Matrix4f &transformation_matrix)
00093 {
00094 size_t nr_points = indices_src.size ();
00095 if (cloud_tgt.points.size () != nr_points)
00096 {
00097 PCL_ERROR ("[pcl::TransformationSVD::estimateRigidTransformation] Number or points in source (%zu) differs than target (%zu)!\n", indices_src.size (), cloud_tgt.points.size ());
00098 return;
00099 }
00100
00101
00102 Eigen::MatrixXf A (nr_points, 6);
00103 Eigen::MatrixXf b (nr_points, 1);
00104 for (size_t i = 0; i < nr_points; ++i)
00105 {
00106 const float & sx = cloud_src.points[indices_src[i]].x;
00107 const float & sy = cloud_src.points[indices_src[i]].y;
00108 const float & sz = cloud_src.points[indices_src[i]].z;
00109 const float & dx = cloud_tgt.points[i].x;
00110 const float & dy = cloud_tgt.points[i].y;
00111 const float & dz = cloud_tgt.points[i].z;
00112 const float & nx = cloud_tgt.points[i].normal[0];
00113 const float & ny = cloud_tgt.points[i].normal[1];
00114 const float & nz = cloud_tgt.points[i].normal[2];
00115 A (i, 0) = nz*sy - ny*sz;
00116 A (i, 1) = nx*sz - nz*sx;
00117 A (i, 2) = ny*sx - nx*sy;
00118 A (i, 3) = nx;
00119 A (i, 4) = ny;
00120 A (i, 5) = nz;
00121 b (i, 0) = nx*dx + ny*dy + nz*dz - nx*sx - ny*sy - nz*sz;
00122 }
00123
00124
00125 Eigen::VectorXf x = A.colPivHouseholderQr ().solve (b);
00126
00127
00128 constructTransformationMatrix (x (0), x (1), x (2), x (3), x (4), x (5), transformation_matrix);
00129 }
00130
00131
00133 template <typename PointSource, typename PointTarget> inline void
00134 pcl::registration::TransformationEstimationPointToPlaneLLS<PointSource, PointTarget>::
00135 estimateRigidTransformation (const pcl::PointCloud<PointSource> &cloud_src,
00136 const std::vector<int> &indices_src,
00137 const pcl::PointCloud<PointTarget> &cloud_tgt,
00138 const std::vector<int> &indices_tgt,
00139 Eigen::Matrix4f &transformation_matrix)
00140 {
00141 size_t nr_points = indices_src.size ();
00142 if (indices_tgt.size () != nr_points)
00143 {
00144 PCL_ERROR ("[pcl::TransformationEstimationPointToPlaneLLS::estimateRigidTransformation] Number or points in source (%zu) differs than target (%zu)!\n", indices_src.size (), indices_tgt.size ());
00145 return;
00146 }
00147
00148
00149 Eigen::MatrixXf A (nr_points, 6);
00150 Eigen::MatrixXf b (nr_points, 1);
00151 for (size_t i = 0; i < nr_points; ++i)
00152 {
00153 const float & sx = cloud_src.points[indices_src[i]].x;
00154 const float & sy = cloud_src.points[indices_src[i]].y;
00155 const float & sz = cloud_src.points[indices_src[i]].z;
00156 const float & dx = cloud_tgt.points[indices_tgt[i]].x;
00157 const float & dy = cloud_tgt.points[indices_tgt[i]].y;
00158 const float & dz = cloud_tgt.points[indices_tgt[i]].z;
00159 const float & nx = cloud_tgt.points[indices_tgt[i]].normal[0];
00160 const float & ny = cloud_tgt.points[indices_tgt[i]].normal[1];
00161 const float & nz = cloud_tgt.points[indices_tgt[i]].normal[2];
00162 A (i, 0) = nz*sy - ny*sz;
00163 A (i, 1) = nx*sz - nz*sx;
00164 A (i, 2) = ny*sx - nx*sy;
00165 A (i, 3) = nx;
00166 A (i, 4) = ny;
00167 A (i, 5) = nz;
00168 b (i, 0) = nx*dx + ny*dy + nz*dz - nx*sx - ny*sy - nz*sz;
00169 }
00170
00171
00172 Eigen::VectorXf x = A.colPivHouseholderQr ().solve (b);
00173
00174
00175 constructTransformationMatrix (x (0), x (1), x (2), x (3), x (4), x (5), transformation_matrix);
00176 }
00177
00179 template <typename PointSource, typename PointTarget> inline void
00180 pcl::registration::TransformationEstimationPointToPlaneLLS<PointSource, PointTarget>::
00181 estimateRigidTransformation (const pcl::PointCloud<PointSource> &cloud_src,
00182 const pcl::PointCloud<PointTarget> &cloud_tgt,
00183 const pcl::Correspondences &correspondences,
00184 Eigen::Matrix4f &transformation_matrix)
00185 {
00186 size_t nr_points = correspondences.size ();
00187
00188
00189 Eigen::MatrixXf A (nr_points, 6);
00190 Eigen::MatrixXf b (nr_points, 1);
00191 for (size_t i = 0; i < nr_points; ++i)
00192 {
00193 const int & src_idx = correspondences[i].index_query;
00194 const int & tgt_idx = correspondences[i].index_match;
00195 const float & sx = cloud_src.points[src_idx].x;
00196 const float & sy = cloud_src.points[src_idx].y;
00197 const float & sz = cloud_src.points[src_idx].z;
00198 const float & dx = cloud_tgt.points[tgt_idx].x;
00199 const float & dy = cloud_tgt.points[tgt_idx].y;
00200 const float & dz = cloud_tgt.points[tgt_idx].z;
00201 const float & nx = cloud_tgt.points[tgt_idx].normal[0];
00202 const float & ny = cloud_tgt.points[tgt_idx].normal[1];
00203 const float & nz = cloud_tgt.points[tgt_idx].normal[2];
00204 A (i, 0) = nz*sy - ny*sz;
00205 A (i, 1) = nx*sz - nz*sx;
00206 A (i, 2) = ny*sx - nx*sy;
00207 A (i, 3) = nx;
00208 A (i, 4) = ny;
00209 A (i, 5) = nz;
00210 b (i, 0) = nx*dx + ny*dy + nz*dz - nx*sx - ny*sy - nz*sz;
00211 }
00212
00213
00214 Eigen::VectorXf x = A.colPivHouseholderQr ().solve (b);
00215
00216
00217 constructTransformationMatrix (x (0), x (1), x (2), x (3), x (4), x (5), transformation_matrix);
00218 }
00219
00220 template <typename PointSource, typename PointTarget> inline void
00221 pcl::registration::TransformationEstimationPointToPlaneLLS<PointSource, PointTarget>::
00222 constructTransformationMatrix (const float & alpha, const float & beta, const float & gamma,
00223 const float & tx, const float & ty, const float & tz,
00224 Eigen::Matrix4f &transformation_matrix)
00225 {
00226
00227
00228 transformation_matrix = Eigen::Matrix4f::Zero ();
00229 transformation_matrix (0, 0) = cosf (gamma) * cosf (beta);
00230 transformation_matrix (0, 1) = -sinf (gamma) * cosf (alpha) + cosf (gamma) * sinf (beta) * sinf (alpha);
00231 transformation_matrix (0, 2) = sinf (gamma) * sinf (alpha) + cosf (gamma) * sinf (beta) * cosf (alpha);
00232 transformation_matrix (1, 0) = sinf (gamma) * cosf (beta);
00233 transformation_matrix (1, 1) = cosf (gamma) * cosf (alpha) + sinf (gamma) * sinf (beta) * sinf (alpha);
00234 transformation_matrix (1, 2) = -cosf (gamma) * sinf (alpha) + sinf (gamma) * sinf (beta) * cosf (alpha);
00235 transformation_matrix (2, 0) = -sinf (beta);
00236 transformation_matrix (2, 1) = cosf (beta) * sinf (alpha);
00237 transformation_matrix (2, 2) = cosf (beta) * cosf (alpha);
00238
00239 transformation_matrix (0, 3) = tx;
00240 transformation_matrix (1, 3) = ty;
00241 transformation_matrix (2, 3) = tz;
00242 transformation_matrix (3, 3) = 1;
00243 }
00244
00245 #endif