AliceVision
Photogrammetric Computer Vision Framework
Triangulation.hpp
1 // This file is part of the AliceVision project.
2 // Copyright (c) 2016 AliceVision contributors.
3 // Copyright (c) 2012 openMVG contributors.
4 // Copyright (c) 2010 libmv contributors.
5 // This Source Code Form is subject to the terms of the Mozilla Public License,
6 // v. 2.0. If a copy of the MPL was not distributed with this file,
7 // You can obtain one at https://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
11 #include <aliceVision/numeric/numeric.hpp>
12 #include <aliceVision/robustEstimation/ISolver.hpp>
13 #include <aliceVision/numeric/algebra.hpp>
14 
15 #include <vector>
16 #include <random>
17 
18 namespace aliceVision {
19 namespace multiview {
20 
33 void TriangulateNView(const Mat2X& x, const std::vector<Mat34>& Ps, Vec4& X, const std::vector<double>* weights = nullptr);
34 
35 
48 template<class ContainerT>
49 void TriangulateNViewAlgebraic(const ContainerT& x, const std::vector<Mat34>& Ps, Vec4& X, const std::vector<double>* weights = nullptr)
50 
51 {
52  Mat2X::Index nviews = CountElements(x);
53  assert(static_cast<std::size_t>(nviews) == Ps.size());
54 
55  Mat design(2 * nviews, 4);
56  for (Mat2X::Index i = 0; i < nviews; ++i)
57  {
58  design.block<2, 4>(2 * i, 0) = SkewMatMinimal(getElement<ContainerT>(x, i)) * Ps[i];
59  if (weights != nullptr)
60  {
61  design.block<2, 4>(2 * i, 0) *= (*weights)[i];
62  }
63  }
64  Nullspace(design, X);
65 }
66 
79 void TriangulateNViewAlgebraicSpherical(const std::vector<Vec3> &xs,
80  const std::vector<Eigen::Matrix4d> & Ts,
81  Vec4 & X,
82  const std::vector<double> *weights = nullptr);
83 
96 void TriangulateNViewLORANSAC(const std::vector<Vec2>& x,
97  const std::vector<Mat34>& Ps,
98  std::mt19937& generator,
99  Vec4& X,
100  std::vector<std::size_t>* inliersIndex = NULL,
101  const double& thresholdError = 4.0);
102 
103 // Iterated linear method
104 
106 {
107  public:
108  std::size_t size() const { return views.size(); }
109 
110  void clear() { views.clear(); }
111 
112  void add(const Mat34& projMatrix, const Vec2& p) { views.emplace_back(projMatrix, p); }
113 
114  // Return squared L2 sum of error
115  double error(const Vec3& X) const;
116 
117  Vec3 compute(int iter = 3) const;
118 
120  // Accessors
121 
122  // These values are defined after a successful call to compute
123  double minDepth() const { return zmin; }
124  double maxDepth() const { return zmax; }
125  double error() const { return err; }
126 
128  // Data members
129 
130  protected:
131  mutable double zmin; // min depth, mutable since modified in compute(...) const;
132  mutable double zmax; // max depth, mutable since modified in compute(...) const;
133  mutable double err; // re-projection error, mutable since modified in compute(...) const;
134  std::vector<std::pair<Mat34, Vec2>> views; // Proj matrix and associated image point
135 };
136 
137 template<class ContainerT>
139 {
144  inline std::size_t getMinimumNbRequiredSamples() const { return 2; }
145 
150  inline std::size_t getMaximumNbModels() const { return 1; }
151 
152  void solve(const ContainerT& x, const std::vector<Mat34>& Ps, std::vector<robustEstimation::MatrixModel<Vec4>>& X) const
153  {
154  Vec4 pt3d;
155  TriangulateNViewAlgebraic(x, Ps, pt3d);
156  X.push_back(robustEstimation::MatrixModel<Vec4>(pt3d));
157  assert(X.size() == 1);
158  }
159 
160  void solve(const ContainerT& x,
161  const std::vector<Mat34>& Ps,
162  std::vector<robustEstimation::MatrixModel<Vec4>>& X,
163  const std::vector<double>& weights) const
164  {
165  Vec4 pt3d;
166  TriangulateNViewAlgebraic(x, Ps, pt3d, &weights);
167  X.push_back(robustEstimation::MatrixModel<Vec4>(pt3d));
168  assert(X.size() == 1);
169  }
170 };
171 
173 {
178  inline std::size_t getMinimumNbRequiredSamples() const
179  {
180  return 2;
181  }
182 
187  inline std::size_t getMaximumNbModels() const
188  {
189  return 1;
190  }
191 
192  void solve(const std::vector<Vec3> & x, const std::vector<Eigen::Matrix4d>& Ts, std::vector<robustEstimation::MatrixModel<Vec4>>& X) const
193  {
194  Vec4 pt3d;
195  TriangulateNViewAlgebraicSpherical(x, Ts, pt3d);
196  X.push_back(robustEstimation::MatrixModel<Vec4>(pt3d));
197  assert(X.size() == 1);
198  }
199 
200 
201 
202  void solve(const std::vector<Vec3> & x, const std::vector<Eigen::Matrix4d>& Ts, std::vector<robustEstimation::MatrixModel<Vec4>>& X, const std::vector<double>& weights) const
203  {
204  Vec4 pt3d;
205  TriangulateNViewAlgebraicSpherical(x, Ts, pt3d, &weights);
206  X.push_back(robustEstimation::MatrixModel<Vec4>(pt3d));
207  assert(X.size() == 1);
208  }
209 
210 };
211 
212 } // namespace multiview
213 } // namespace aliceVision
aliceVision::multiview::TriangulateNViewsSphericalSolver::getMinimumNbRequiredSamples
std::size_t getMinimumNbRequiredSamples() const
Return the minimum number of required samples.
Definition: Triangulation.hpp:178
aliceVision::multiview::TriangulateNViewsSolver::getMinimumNbRequiredSamples
std::size_t getMinimumNbRequiredSamples() const
Return the minimum number of required samples.
Definition: Triangulation.hpp:144
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::multiview::TriangulateNViewsSolver
Definition: Triangulation.hpp:138
aliceVision::multiview::TriangulateNViewsSphericalSolver::getMaximumNbModels
std::size_t getMaximumNbModels() const
Return the maximum number of models.
Definition: Triangulation.hpp:187
aliceVision::robustEstimation::MatrixModel
Matrix based model to be used in a solver.
Definition: ISolver.hpp:88
aliceVision::multiview::TriangulateNViewsSphericalSolver
Definition: Triangulation.hpp:172
aliceVision::multiview::Triangulation
Definition: Triangulation.hpp:105
aliceVision::multiview::TriangulateNViewsSolver::getMaximumNbModels
std::size_t getMaximumNbModels() const
Return the maximum number of models.
Definition: Triangulation.hpp:150
aliceVision::SkewMatMinimal
Mat23 SkewMatMinimal(const Vec2 &x)
Create a minimal skew matrix from a 2d vector.
Definition: numeric.cpp:17