67 template <
typename VectorT >
70 center_of_gravity(
const std::vector< VectorT >& _points ) {
71 VectorT cog(0.0,0.0,0.0);
73 for (uint i = 0 ; i < _points.size() ; ++i ) {
74 cog = cog + _points[i];
77 cog = cog / (
typename VectorT::value_type )_points.size();
83 template <
typename VectorT ,
typename QuaternionT >
85 icp(
const std::vector< VectorT >& _points1 ,
const std::vector< VectorT >& _points2 , VectorT& _cog1 , VectorT& _cog2 ,
double& _scale1 ,
double& _scale2 , QuaternionT& _rotation )
88 _cog1 = center_of_gravity(_points1);
89 _cog2 = center_of_gravity(_points2);
95 for ( uint i = 0 ; i < _points1.size() ; ++i ) {
96 diff = _points1[i] - _cog1;
97 _scale1 = std::max( _scale1 , sqrt( diff.norm() ) );
98 diff = _points2[i] - _cog2;
99 _scale2 = std::max( _scale2 , sqrt( diff.norm() ) );
114 for ( uint i = 0 ; i < _points1.size() ; ++i ) {
115 Sxx += ( _points1[i][0] - _cog1[0] ) * ( _points2[i][0] - _cog2[0] );
116 Sxy += ( _points1[i][0] - _cog1[0] ) * ( _points2[i][1] - _cog2[1] );
117 Sxz += ( _points1[i][0] - _cog1[0] ) * ( _points2[i][2] - _cog2[2] );
119 Syx += ( _points1[i][1] - _cog1[1] ) * ( _points2[i][0] - _cog2[0] );
120 Syy += ( _points1[i][1] - _cog1[1] ) * ( _points2[i][1] - _cog2[1] );
121 Syz += ( _points1[i][1] - _cog1[1] ) * ( _points2[i][2] - _cog2[2] );
123 Szx += ( _points1[i][2] - _cog1[2] ) * ( _points2[i][0] - _cog2[0] );
124 Szy += ( _points1[i][2] - _cog1[2] ) * ( _points2[i][1] - _cog2[1] );
125 Szz += ( _points1[i][2] - _cog1[2] ) * ( _points2[i][2] - _cog2[2] );
128 const double scale = _scale1 * _scale2;
130 Sxx = Sxx * 1.0 / scale;
131 Sxy = Sxy * 1.0 / scale;
132 Sxz = Sxz * 1.0 / scale;
133 Syx = Syx * 1.0 / scale;
134 Syy = Syy * 1.0 / scale;
135 Syz = Syz * 1.0 / scale;
136 Szx = Szx * 1.0 / scale;
137 Szy = Szy * 1.0 / scale;
138 Szz = Szz * 1.0 / scale;
140 gmm::dense_matrix<double> N; gmm::resize(N,4,4); gmm::clear(N);
141 N(0,0) = Sxx + Syy + Szz;
147 N(1,1) = Sxx - Syy - Szz;
153 N(2,2) = -Sxx + Syy - Szz;
159 N(3,3) = -Sxx - Syy + Szz;
161 std::vector< double > eigval; eigval.resize(4);
162 gmm::dense_matrix< double > eigvect; gmm::resize(eigvect, 4,4); gmm::clear(eigvect);
163 gmm::symmetric_qr_algorithm(N, eigval, eigvect);
166 double max = -FLT_MAX;
167 for (
int i = 0; i < 4; i++)
174 _rotation[0] = eigvect(0,gr);
175 _rotation[1] = eigvect(1,gr);
176 _rotation[2] = eigvect(2,gr);
177 _rotation[3] = eigvect(3,gr);
183 template <
typename VectorT ,
typename QuaternionT >
185 icp(
const std::vector< VectorT >& _points1 ,
const std::vector< VectorT >& _points2 , VectorT& _cog1 , VectorT& _cog2 , QuaternionT& _rotation )
188 _cog1 = center_of_gravity(_points1);
189 _cog2 = center_of_gravity(_points2);
201 for ( uint i = 0 ; i < _points1.size() ; ++i ) {
202 Sxx += ( _points1[i][0] - _cog1[0] ) * ( _points2[i][0] - _cog2[0] );
203 Sxy += ( _points1[i][0] - _cog1[0] ) * ( _points2[i][1] - _cog2[1] );
204 Sxz += ( _points1[i][0] - _cog1[0] ) * ( _points2[i][2] - _cog2[2] );
206 Syx += ( _points1[i][1] - _cog1[1] ) * ( _points2[i][0] - _cog2[0] );
207 Syy += ( _points1[i][1] - _cog1[1] ) * ( _points2[i][1] - _cog2[1] );
208 Syz += ( _points1[i][1] - _cog1[1] ) * ( _points2[i][2] - _cog2[2] );
210 Szx += ( _points1[i][2] - _cog1[2] ) * ( _points2[i][0] - _cog2[0] );
211 Szy += ( _points1[i][2] - _cog1[2] ) * ( _points2[i][1] - _cog2[1] );
212 Szz += ( _points1[i][2] - _cog1[2] ) * ( _points2[i][2] - _cog2[2] );
215 gmm::dense_matrix<double> N; gmm::resize(N,4,4); gmm::clear(N);
216 N(0,0) = Sxx + Syy + Szz;
222 N(1,1) = Sxx - Syy - Szz;
228 N(2,2) = -Sxx + Syy - Szz;
234 N(3,3) = -Sxx - Syy + Szz;
236 std::vector< double > eigval; eigval.resize(4);
237 gmm::dense_matrix< double > eigvect; gmm::resize(eigvect, 4,4); gmm::clear(eigvect);
238 gmm::symmetric_qr_algorithm(N, eigval, eigvect);
241 double max = -FLT_MAX;
242 for (
int i = 0; i < 4; i++)
249 _rotation[0] = eigvect(0,gr);
250 _rotation[1] = eigvect(1,gr);
251 _rotation[2] = eigvect(2,gr);
252 _rotation[3] = eigvect(3,gr);
Classes for ICP Algorithm.
void icp(const std::vector< VectorT > &_points1, const std::vector< VectorT > &_points2, VectorT &_cog1, VectorT &_cog2, double &_scale1, double &_scale2, QuaternionT &_rotation)
Compute rigid transformation from first point set to second point set.