31 |
jakw |
1 |
#include "eigentools.h"
|
|
|
2 |
|
|
|
3 |
namespace eigentools{
|
|
|
4 |
|
|
|
5 |
// Function to fit two sets of corresponding transformation data.
|
|
|
6 |
// Algorithm and notation according to Mili Shah, Comparing two sets ofcorresponding six degree of freedom data, CVIU 2011.
|
|
|
7 |
// DTU, 2013, Oline V. Olesen, Jakob Wilm
|
|
|
8 |
void fitSixDofData(const std::vector<Eigen::Affine3f> X, const std::vector<Eigen::Affine3f> X_mark, Eigen::Affine3f &H){
|
|
|
9 |
// NOT DEBUGGED!
|
|
|
10 |
int N = X.size();
|
|
|
11 |
assert(N == X_mark.size());
|
|
|
12 |
|
|
|
13 |
// Mean translations
|
|
|
14 |
Eigen::Vector3f t;
|
|
|
15 |
Eigen::Vector3f t_mark;
|
|
|
16 |
for(int i=0; i<N; i++){
|
|
|
17 |
t += 1.0/N * X[i].translation();
|
|
|
18 |
t_mark += 1.0/N * X[i].translation();
|
|
|
19 |
}
|
|
|
20 |
|
|
|
21 |
// Data with mean adjusted translations
|
|
|
22 |
Eigen::MatrixXf X_bar(3, 4*N);
|
|
|
23 |
Eigen::MatrixXf X_mark_bar(3, 4*N);
|
|
|
24 |
for(int i=0; i<N; i++){
|
|
|
25 |
X_bar.block(0,i*4,3,3) = X[i].rotation();
|
|
|
26 |
X_bar.block(0,i*4+3,3,1) = X[i].translation() - t;
|
|
|
27 |
X_mark_bar.block(0,i*4,3,3) = X_mark[i].rotation();
|
|
|
28 |
X_mark_bar.block(0,i*4+3,3,1) = X_mark[i].translation() - t_mark;
|
|
|
29 |
}
|
|
|
30 |
|
|
|
31 |
// SVD
|
|
|
32 |
Eigen::JacobiSVD<Eigen::MatrixXf> svd(X_bar*X_mark_bar.transpose(), Eigen::ComputeThinU | Eigen::ComputeThinV);
|
|
|
33 |
|
|
|
34 |
Eigen::Matrix3f D = Eigen::Matrix3f::Identity();
|
|
|
35 |
if((svd.matrixV()*svd.matrixU().transpose()).determinant() < 0)
|
|
|
36 |
D(3,3) = -1;
|
|
|
37 |
|
|
|
38 |
// Best rotation
|
|
|
39 |
Eigen::Matrix3f Omega = svd.matrixV()*D*svd.matrixU().transpose();
|
|
|
40 |
|
|
|
41 |
// Best translation
|
|
|
42 |
Eigen::Vector3f tau = t_mark - Omega*t;
|
|
|
43 |
|
|
|
44 |
// Complete solution
|
|
|
45 |
H.linear() = Omega;
|
|
|
46 |
H.translation() = tau;
|
|
|
47 |
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
|
|
|
51 |
}
|