NDEVR
API Documentation
TransformPointToPlaneLLS.h
1#pragma once
2#include "Base/Headers/Matrix.hpp"
3#include "Base/Headers/Vertex.hpp"
4#include "Base/Headers/Buffer.hpp"
5namespace NDEVR
6{
16
19 template<typename t_type = float>
21 {
22 public:
26 void setReference(Buffer<Vertex<3, t_type>>* reference_points, Buffer<Ray<3, t_type>>* reference_normals)
27 {
28 m_reference_points = reference_points;
29 m_reference_normals = reference_normals;
30 }
31
37 , const Buffer<Correspondance>& correspondences
38 , Matrix<t_type>& transformation_matrix) const
39 {
41 Vertex<6, t_type> ATb(0);
42
43 // Approximate as a linear least squares problem
44 for(const Correspondance& correspondence : correspondences)
45 {
46 t_type sx = points[correspondence.to_register_idx][X];
47 t_type sy = points[correspondence.to_register_idx][Y];
48 t_type sz = points[correspondence.to_register_idx][Z];
49 t_type dx = (*m_reference_points)[correspondence.reference_idx][X];
50 t_type dy = (*m_reference_points)[correspondence.reference_idx][Y];
51 t_type dz = (*m_reference_points)[correspondence.reference_idx][Z];
52 t_type nx = (*m_reference_normals)[correspondence.reference_idx][X];
53 t_type ny = (*m_reference_normals)[correspondence.reference_idx][Y];
54 t_type nz = (*m_reference_normals)[correspondence.reference_idx][Z];
55
56 t_type a = nz * sy - ny * sz;
57 t_type b = nx * sz - nz * sx;
58 t_type c = ny * sx - nx * sy;
59 ATA[0][0] += a * a;
60 ATA[0][1] += a * b;
61 ATA[0][2] += a * c;
62 ATA[0][3] += a * nx;
63 ATA[0][4] += a * ny;
64 ATA[0][5] += a * nz;
65 ATA[1][1] += b * b;
66 ATA[1][2] += b * c;
67 ATA[1][3] += b * nx;
68 ATA[1][4] += b * ny;
69 ATA[1][5] += b * nz;
70 ATA[0][2] += c * c;
71 ATA[0][3] += c * nx;
72 ATA[0][4] += c * ny;
73 ATA[0][5] += c * nz;
74 ATA[0][3] += nx * nx;
75 ATA[0][4] += nx * ny;
76 ATA[0][5] += nx * nz;
77 ATA[0][4] += ny * ny;
78 ATA[0][5] += ny * nz;
79 ATA[0][5] += nz * nz;
80
81 t_type d = nx * dx + ny * dy + nz * dz - nx * sx - ny * sy - nz * sz;
82 ATb[0] += a * d;
83 ATb[1] += b * d;
84 ATb[2] += c * d;
85 ATb[3] += nx * d;
86 ATb[4] += ny * d;
87 ATb[5] += nz * d;
88
89 ++target_it;
90 ++source_it;
91 }
92 // 0 1 2 3 4 5
93 // 6 7 8 9 10 11
94 // 12 13 14 15 16 17
95 // 18 19 20 21 22 23
96 // 24 25 26 27 28 29
97 // 30 31 32 33 34 35
98 ATA[1][0] = ATA[0][1];
99 ATA[2][0] = ATA[0][2];
100 ATA[2][1] = ATA[1][2];
101 ATA[3][0] = ATA[0][3];
102 ATA[3][1] = ATA[1][3];
103 ATA[3][2] = ATA[2][3];
104 ATA[4][0] = ATA[0][4];
105 ATA[4][1] = ATA[1][4];
106 ATA[4][2] = ATA[2][4];
107 ATA[4][3] = ATA[3][4];
108 ATA[5][0] = ATA[0][5];
109 ATA[5][1] = ATA[1][5];
110 ATA[5][2] = ATA[2][5];
111 ATA[5][3] = ATA[3][5];
112 ATA[5][4] = ATA[4][5];
113
114 // Solve A*x = b
115 Vertex<6, t_type> x = ATA.invert() * ATb;
116
117 // Construct the transformation matrix from x
118 constructTransformationMatrix(x[0], x[1], x[2], x[3], x[4], x[5], transformation_matrix);
119
120 }
121
127 protected:
128 inline void constructTransformationMatrix(t_type alpha,
129 t_type beta,
130 t_type gamma,
131 t_type tx,
132 t_type ty,
133 t_type tz,
134 Matrix<t_type>& transformation_matrix) const
135 {
136 // Construct the transformation matrix from rotation and translation
137 transformation_matrix = Matrix<t_type>(0);
138 transformation_matrix[0][0] = cast<t_type>(std::cos(gamma) * std::cos(beta));
139 transformation_matrix[0][1] = cast<t_type>(
140 -std::sin(gamma) * std::cos(alpha) + std::cos(gamma) * std::sin(beta) * std::sin(alpha));
141 transformation_matrix[0][2] = cast<t_type>(
142 std::sin(gamma) * sin(alpha) + std::cos(gamma) * sin(beta) * std::cos(alpha));
143 transformation_matrix[1][0] = cast<t_type>(sin(gamma) * std::cos(beta));
144 transformation_matrix[1][1] = cast<t_type>(
145 std::cos(gamma) * std::cos(alpha) + std::sin(gamma) * std::sin(beta) * std::sin(alpha));
146 transformation_matrix[1][2] = cast<t_type>(
147 -std::cos(gamma) * sin(alpha) + sin(gamma) * sin(beta) * std::cos(alpha));
148 transformation_matrix[2][0] = cast<t_type>(-std::sin(beta));
149 transformation_matrix[2][1] = cast<t_type>(std::cos(beta) * std::sin(alpha));
150 transformation_matrix[2][2] = cast<t_type>(std::cos(beta) * std::cos(alpha));
151
152 transformation_matrix[0][3] = cast<t_type>(tx);
153 transformation_matrix[1][3] = cast<t_type>(ty);
154 transformation_matrix[2][3] = cast<t_type>(tz);
155 transformation_matrix[3][3] = cast<t_type>(1);
156 }
159 };
160}
The equivelent of std::vector but with a bit more control.
Definition Buffer.hpp:58
Templated logic for doing matrix multiplication.
Definition Matrix.hpp:182
Estimates a rigid transformation using point-to-plane linear least squares minimization.
void setReference(Buffer< Vertex< 3, t_type > > *reference_points, Buffer< Ray< 3, t_type > > *reference_normals)
Sets the reference point cloud and its normals.
void estimateRigidTransformation(const Buffer< Vertex< 3, t_type > > *points, const Buffer< Correspondance > &correspondences, Matrix< t_type > &transformation_matrix) const
Estimate a rigid rotation transformation between a source and a target.
void constructTransformationMatrix(t_type alpha, t_type beta, t_type gamma, t_type tx, t_type ty, t_type tz, Matrix< t_type > &transformation_matrix) const
Construct a 4 by 4 transformation matrix from the provided rotation and translation.
const Buffer< Ray< 3, t_type > > * m_reference_normals
The reference surface normals.
const Buffer< Vertex< 3, t_type > > * m_reference_points
The reference point cloud.
A point in N-dimensional space, used primarily for spatial location information.
Definition Vertex.hpp:44
The primary namespace for the NDEVR SDK.
float fltp04
Defines an alias representing a 4 byte floating-point number Bit layout is as follows: -Sign: 1 bit a...
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type sin(const Angle< t_type > &angle)
Performs optimized sine operation on the given angle using pre-computed lookup table for optimal spee...
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408
Stores a correspondence between a reference point and a point to register.
uint04 to_register_idx
Index into the point buffer being registered.
fltp04 distance
Distance between the corresponding points.
uint04 reference_idx
Index into the reference point buffer.