Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TriangulationMidPoint.cpp
1 #include "TriangulationMidPoint.hh"
2 #include <Base/Math/Matrix.hh>
3 #include <MathAlgo/LeastSquares.hh>
4 #include <MathAlgo/SVD.hh>
5 
6 using namespace BIAS;
7 using namespace std;
8 
9 
11 {
12 }
13 
14 
17 {
18 }
19 
20 
22 Intersect_(const std::vector< BIAS::Vector3<double> >& pos,
23  const std::vector< BIAS::Vector3<double> >& dir,
24  BIAS::Vector3<double>& res, double& dist,
25  const bool computeDist)
26 {
27  const unsigned int num = pos.size();
28  BIASASSERT(dir.size() == pos.size());
29 
30 /*
31  // Solve least squares problem directly via SVD
32  BIAS::Matrix<double> ATA(num+3, num+3, BIAS::MatrixIdentity);
33  BIAS::Matrix<double> AT(num+3, 3*num, BIAS::MatrixZero);
34  BIAS::Vector<double> b(3*num);
35  for (unsigned int k = 0; k < 3; k++)
36  ATA[k][k] = num;
37  for (unsigned int i = 0; i < num; i++) {
38  for (unsigned int k = 0; k < 3; k++) {
39  ATA[k][i+3] = -dir[i][k];
40  ATA[i+3][k] = -dir[i][k];
41  }
42  }
43  unsigned int j = 0;
44  for (unsigned int i = 0; i < num; i++) {
45  for (unsigned int k = 0; k < 3; k++, j++) {
46  AT[k][j] = 1.0;
47  AT[i+3][j] = -dir[i][k];
48  b[j] = pos[i][k];
49  }
50  }
51  BIAS::SVD solver;
52  if (solver.Compute(ATA) != 0) return -1;
53  BIAS::Matrix<double> ATAinv = solver.Invert();
54  BIAS::Vector<double> x = ATAinv * (AT * b);
55  */
56 
57  // Solve linear least squares problem
58  BIAS::Matrix<double> A(3*num, num+3, BIAS::MatrixZero);
59  BIAS::Vector<double> b(3*num), x(num+3);
60  unsigned int j = 0;
61  for (unsigned int i = 0; i < num; i++) {
62  for (unsigned int k = 0; k < 3; k++, j++) {
63  A[j][k] = 1.0;
64  A[j][i+3] = -dir[i][k];
65  b[j] = pos[i][k];
66  }
67  }
69  if (solver.Solve(A, b, x) != 0) return -1;
70 
71  // Check if resulting 3d point is valid
72  for (unsigned int k = 0; k < 3; k++) {
73  res[k] = x[k];
74  if (BIAS_ISNAN(x[k])) return -1;
75  }
76 
77  // Compute average distance
78  if (computeDist) {
79  dist = 0.0;
81  for (unsigned int i = 0; i < num; i++) {
82  d = pos[i] + x[i+3]*dir[i] - res;
83  dist += d.NormL2();
84  }
85  dist /= (double)num;
86  }
87 
88  // Check if result is in front of all cameras
89  for (unsigned int i = 0; i < num; i++) {
90  if (x[i+3] < 0) return i+1;
91  }
92  return 0;
93 }
94 
95 
97 Triangulate_(const std::vector< BIAS::ProjectionParametersBase* >& cams,
98  const std::vector< BIAS::HomgPoint2D >& points2d,
99  BIAS::Vector3<double>& point3d, double& dist,
100  const bool computeDist)
101 {
102  const unsigned int num = cams.size();
103  BIASASSERT(points2d.size() == num);
104  std::vector< BIAS::Vector3<double> > pos;
105  std::vector< BIAS::Vector3<double> > dir;
106  pos.reserve(num);
107  dir.reserve(num);
108 
110  for (unsigned int i = 0; i < num; i++) {
111  BIASASSERT(points2d[i].IsHomogenized());
112  cams[i]->UnProjectToRay(points2d[i], p, d);
113 #ifdef BIAS_DEBUG
114  BIASASSERT(BIAS::Equal(d.NormL2(), 1.0));
115 #endif
116  dir.push_back(d);
117  pos.push_back(p);
118  }
119  return Intersect_(pos, dir, point3d, dist, computeDist);
120 }
121 
122 
124 Triangulate_(const std::vector< BIAS::PoseParametrization >& poses,
125  const std::vector< BIAS::HomgPoint2D >& rays,
126  BIAS::Vector3<double>& point3d, double& dist,
127  const bool computeDist)
128 {
129  const unsigned int num = poses.size();
130  BIASASSERT(rays.size() == num);
131  std::vector< BIAS::Vector3<double> > pos;
132  std::vector< BIAS::Vector3<double> > dir;
133  pos.reserve(num);
134  dir.reserve(num);
135 
136  for (unsigned int i = 0; i < num; i++) {
137  pos.push_back(poses[i].GetPosition());
138  BIASASSERT(BIAS::Equal(rays[i].NormL2(), 1.0));
139  dir.push_back(poses[i].GetOrientation().MultVec(BIAS::Vector3<double>(rays[i])));
140  }
141  return Intersect_(pos, dir, point3d, dist, computeDist);
142 }
int Intersect_(const std::vector< BIAS::Vector3< double > > &pos, const std::vector< BIAS::Vector3< double > > &dir, BIAS::Vector3< double > &res, double &dist, const bool computeDist)
Linear least squares solver based on Lapack routines.
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
virtual int Solve(Matrix< double > &A, Vector< double > &b, Vector< double > &x)
LeastSquaresLapack.
int Triangulate_(const std::vector< BIAS::ProjectionParametersBase * > &cams, const std::vector< BIAS::HomgPoint2D > &points2d, BIAS::Vector3< double > &point3d, double &dist, const bool computeDist)
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633