41 #ifndef PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_POINT_TO_PLANE_LLS_HPP_
42 #define PCL_REGISTRATION_TRANSFORMATION_ESTIMATION_POINT_TO_PLANE_LLS_HPP_
44 #include <pcl/cloud_iterator.h>
48 namespace registration {
50 template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
55 Matrix4& transformation_matrix)
const
57 const auto nr_points = cloud_src.
size();
58 if (cloud_tgt.
size() != nr_points) {
60 "[pcl::TransformationEstimationPointToPlaneLLS::estimateRigidTransformation] "
61 "Number or points in source (%zu) differs than target (%zu)!\n",
62 static_cast<std::size_t
>(nr_points),
63 static_cast<std::size_t
>(cloud_tgt.
size()));
69 estimateRigidTransformation(source_it, target_it, transformation_matrix);
72 template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
78 Matrix4& transformation_matrix)
const
80 const auto nr_points = indices_src.size();
81 if (cloud_tgt.
size() != nr_points) {
83 "[pcl::TransformationEstimationPointToPlaneLLS::estimateRigidTransformation] "
84 "Number or points in source (%zu) differs than target (%zu)!\n",
86 static_cast<std::size_t
>(cloud_tgt.
size()));
92 estimateRigidTransformation(source_it, target_it, transformation_matrix);
95 template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
102 Matrix4& transformation_matrix)
const
104 const auto nr_points = indices_src.size();
105 if (indices_tgt.size() != nr_points) {
107 "[pcl::TransformationEstimationPointToPlaneLLS::estimateRigidTransformation] "
108 "Number or points in source (%zu) differs than target (%zu)!\n",
116 estimateRigidTransformation(source_it, target_it, transformation_matrix);
119 template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
125 Matrix4& transformation_matrix)
const
129 estimateRigidTransformation(source_it, target_it, transformation_matrix);
132 template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
141 Matrix4& transformation_matrix)
const
144 transformation_matrix = Eigen::Matrix<Scalar, 4, 4>::Zero();
145 transformation_matrix(0, 0) =
static_cast<Scalar
>(std::cos(gamma) * std::cos(beta));
146 transformation_matrix(0, 1) =
static_cast<Scalar
>(
147 -sin(gamma) * std::cos(alpha) + std::cos(gamma) * sin(beta) * sin(alpha));
148 transformation_matrix(0, 2) =
static_cast<Scalar
>(
149 sin(gamma) * sin(alpha) + std::cos(gamma) * sin(beta) * std::cos(alpha));
150 transformation_matrix(1, 0) =
static_cast<Scalar
>(sin(gamma) * std::cos(beta));
151 transformation_matrix(1, 1) =
static_cast<Scalar
>(
152 std::cos(gamma) * std::cos(alpha) + sin(gamma) * sin(beta) * sin(alpha));
153 transformation_matrix(1, 2) =
static_cast<Scalar
>(
154 -std::cos(gamma) * sin(alpha) + sin(gamma) * sin(beta) * std::cos(alpha));
155 transformation_matrix(2, 0) =
static_cast<Scalar
>(-sin(beta));
156 transformation_matrix(2, 1) =
static_cast<Scalar
>(std::cos(beta) * sin(alpha));
157 transformation_matrix(2, 2) =
static_cast<Scalar
>(std::cos(beta) * std::cos(alpha));
159 transformation_matrix(0, 3) =
static_cast<Scalar
>(tx);
160 transformation_matrix(1, 3) =
static_cast<Scalar
>(ty);
161 transformation_matrix(2, 3) =
static_cast<Scalar
>(tz);
162 transformation_matrix(3, 3) =
static_cast<Scalar
>(1);
165 template <
typename Po
intSource,
typename Po
intTarget,
typename Scalar>
170 Matrix4& transformation_matrix)
const
172 using Vector6d = Eigen::Matrix<double, 6, 1>;
173 using Matrix6d = Eigen::Matrix<double, 6, 6>;
182 if (!std::isfinite(source_it->x) || !std::isfinite(source_it->y) ||
183 !std::isfinite(source_it->z) || !std::isfinite(target_it->x) ||
184 !std::isfinite(target_it->y) || !std::isfinite(target_it->z) ||
185 !std::isfinite(target_it->normal_x) || !std::isfinite(target_it->normal_y) ||
186 !std::isfinite(target_it->normal_z)) {
192 const float& sx = source_it->x;
193 const float& sy = source_it->y;
194 const float& sz = source_it->z;
195 const float& dx = target_it->x;
196 const float& dy = target_it->y;
197 const float& dz = target_it->z;
198 const float& nx = target_it->normal[0];
199 const float& ny = target_it->normal[1];
200 const float& nz = target_it->normal[2];
202 double a = nz * sy - ny * sz;
203 double b = nx * sz - nz * sx;
204 double c = ny * sx - nx * sy;
213 ATA.coeffRef(0) += a * a;
214 ATA.coeffRef(1) += a * b;
215 ATA.coeffRef(2) += a * c;
216 ATA.coeffRef(3) += a * nx;
217 ATA.coeffRef(4) += a * ny;
218 ATA.coeffRef(5) += a * nz;
219 ATA.coeffRef(7) += b * b;
220 ATA.coeffRef(8) += b * c;
221 ATA.coeffRef(9) += b * nx;
222 ATA.coeffRef(10) += b * ny;
223 ATA.coeffRef(11) += b * nz;
224 ATA.coeffRef(14) += c * c;
225 ATA.coeffRef(15) += c * nx;
226 ATA.coeffRef(16) += c * ny;
227 ATA.coeffRef(17) += c * nz;
228 ATA.coeffRef(21) += nx * nx;
229 ATA.coeffRef(22) += nx * ny;
230 ATA.coeffRef(23) += nx * nz;
231 ATA.coeffRef(28) += ny * ny;
232 ATA.coeffRef(29) += ny * nz;
233 ATA.coeffRef(35) += nz * nz;
235 double d = nx * dx + ny * dy + nz * dz - nx * sx - ny * sy - nz * sz;
236 ATb.coeffRef(0) += a * d;
237 ATb.coeffRef(1) += b * d;
238 ATb.coeffRef(2) += c * d;
239 ATb.coeffRef(3) += nx * d;
240 ATb.coeffRef(4) += ny * d;
241 ATb.coeffRef(5) += nz * d;
247 ATA.coeffRef(6) = ATA.coeff(1);
248 ATA.coeffRef(12) = ATA.coeff(2);
249 ATA.coeffRef(13) = ATA.coeff(8);
250 ATA.coeffRef(18) = ATA.coeff(3);
251 ATA.coeffRef(19) = ATA.coeff(9);
252 ATA.coeffRef(20) = ATA.coeff(15);
253 ATA.coeffRef(24) = ATA.coeff(4);
254 ATA.coeffRef(25) = ATA.coeff(10);
255 ATA.coeffRef(26) = ATA.coeff(16);
256 ATA.coeffRef(27) = ATA.coeff(22);
257 ATA.coeffRef(30) = ATA.coeff(5);
258 ATA.coeffRef(31) = ATA.coeff(11);
259 ATA.coeffRef(32) = ATA.coeff(17);
260 ATA.coeffRef(33) = ATA.coeff(23);
261 ATA.coeffRef(34) = ATA.coeff(29);
264 Vector6d x =
static_cast<Vector6d
>(ATA.inverse() * ATb);
267 constructTransformationMatrix(
268 x(0), x(1), x(2), x(3), x(4), x(5), transformation_matrix);
276 if (!std::isfinite(source_it->x) || !std::isfinite(source_it->y) ||
277 !std::isfinite(source_it->z) || !std::isfinite(target_it->x) ||
278 !std::isfinite(target_it->y) || !std::isfinite(target_it->z) ||
279 !std::isfinite(target_it->normal_x) || !std::isfinite(target_it->normal_y) ||
280 !std::isfinite(target_it->normal_z)) {
285 const float& sx = source_it->x;
286 const float& sy = source_it->y;
287 const float& sz = source_it->z;
288 const float& dx = target_it->x;
289 const float& dy = target_it->y;
290 const float& dz = target_it->z;
291 const float& nx = target_it->normal[0];
292 const float& ny = target_it->normal[1];
293 const float& nz = target_it->normal[2];
294 double a = nz * sy - ny * sz;
295 double b = nx * sz - nz * sx;
296 double c = ny * sx - nx * sy;
297 double d = nx * dx + ny * dy + nz * dz - nx * sx - ny * sy - nz * sz;
299 Arow << a, b, c, nx, ny, nz;
300 loss += pow(Arow.transpose() * x - d, 2);
306 PCL_DEBUG(
"[pcl::registration::TransformationEstimationPointToPlaneLLS::"
307 "estimateRigidTransformation] Loss :%.10e\n",
Iterator class for point clouds with or without given indices.
PCL_EXPORTS bool isVerbosityLevelEnabled(VERBOSITY_LEVEL severity)
is verbosity level enabled?
std::vector< pcl::Correspondence, Eigen::aligned_allocator< pcl::Correspondence > > Correspondences
IndicesAllocator<> Indices
Type used for indices in PCL.