AliceVision
Photogrammetric Computer Vision Framework
triplet_tijsAndXis_kernel.hpp
1 // This file is part of the AliceVision project.
2 // Copyright (c) 2016 AliceVision contributors.
3 // Copyright (c) 2012 openMVG contributors.
4 // This Source Code Form is subject to the terms of the Mozilla Public License,
5 // v. 2.0. If a copy of the MPL was not distributed with this file,
6 // You can obtain one at https://mozilla.org/MPL/2.0/.
7 
8 #pragma once
9 
10 #include "aliceVision/numeric/numeric.hpp"
11 #include "aliceVision/config.hpp"
12 
13 #include "aliceVision/numeric/projection.hpp"
14 #include "aliceVision/robustEstimation/conditioning.hpp"
15 #include "aliceVision/multiview/triangulation/Triangulation.hpp"
16 
17 // Linear programming solver(s)
18 #include "aliceVision/linearProgramming/ISolver.hpp"
19 #include "aliceVision/linearProgramming/OSIXSolver.hpp"
20 #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_MOSEK)
21  #include "aliceVision/linearProgramming/MOSEKSolver.hpp"
22 #endif
23 
24 #include "aliceVision/linearProgramming/bisectionLP.hpp"
25 #include "aliceVision/linearProgramming/lInfinityCV/tijsAndXis_From_xi_Ri.hpp"
26 
27 namespace aliceVision {
28 namespace trifocal {
29 namespace kernel {
30 
33 {
34  Mat34 P1, P2, P3;
35 
36  static double Error(const TrifocalTensorModel& t, const Vec2& pt1, const Vec2& pt2, const Vec2& pt3)
37  {
38  // Triangulate
39  multiview::Triangulation triangulationObj;
40  triangulationObj.add(t.P1, pt1);
41  triangulationObj.add(t.P2, pt2);
42  triangulationObj.add(t.P3, pt3);
43  const Vec3 X = triangulationObj.compute();
44 
45  // Return the maximum observed reprojection error
46  const double pt1ReProj = (project(t.P1, X) - pt1).squaredNorm();
47  const double pt2ReProj = (project(t.P2, X) - pt2).squaredNorm();
48  const double pt3ReProj = (project(t.P3, X) - pt3).squaredNorm();
49 
50  return std::max(pt1ReProj, std::max(pt2ReProj, pt3ReProj));
51  }
52 };
53 
54 } // namespace kernel
55 } // namespace trifocal
56 } // namespace aliceVision
57 
58 namespace aliceVision {
59 
60 using namespace aliceVision::trifocal::kernel;
61 
64 {
69  std::size_t getMinimumNbRequiredSamples() const { return 4; }
70 
75  std::size_t getMaximumNbModels() const { return 1; }
76 
78  void solve(const Mat& pt0,
79  const Mat& pt1,
80  const Mat& pt2,
81  const std::vector<Mat3>& vec_KR,
82  std::vector<TrifocalTensorModel>& P,
83  const double ThresholdUpperBound) const
84  {
85  // Build the megaMatMatrix
86  const int n_obs = pt0.cols();
87  Mat4X megaMat(4, n_obs * 3);
88  {
89  size_t cpt = 0;
90  for (size_t i = 0; i < n_obs; ++i)
91  {
92  megaMat.col(cpt++) << pt0.col(i)(0), pt0.col(i)(1), (double)i, 0.0;
93  megaMat.col(cpt++) << pt1.col(i)(0), pt1.col(i)(1), (double)i, 1.0;
94  megaMat.col(cpt++) << pt2.col(i)(0), pt2.col(i)(1), (double)i, 2.0;
95  }
96  }
97  //-- Solve the LInfinity translation and structure from Rotation and points data.
98  std::vector<double> vec_solution((3 + getMinimumNbRequiredSamples()) * 3);
99 
100  using namespace aliceVision::lInfinityCV;
101 
102 #if ALICEVISION_IS_DEFINED(ALICEVISION_HAVE_MOSEK)
103  MOSEKSolver LPsolver(static_cast<int>(vec_solution.size()));
104 #else
105  OSI_CISolverWrapper LPsolver(static_cast<int>(vec_solution.size()));
106 #endif
107 
108  Translation_Structure_L1_ConstraintBuilder cstBuilder(vec_KR, megaMat);
109  double gamma;
110  if (BisectionLP<Translation_Structure_L1_ConstraintBuilder, LPConstraintsSparse>(
111  LPsolver, cstBuilder, &vec_solution, ThresholdUpperBound, 0.0, 1e-8, 2, &gamma, false))
112  {
113  const std::vector<Vec3> vec_tis = {Vec3(vec_solution[0], vec_solution[1], vec_solution[2]),
114  Vec3(vec_solution[3], vec_solution[4], vec_solution[5]),
115  Vec3(vec_solution[6], vec_solution[7], vec_solution[8])};
116 
117  TrifocalTensorModel PTemp;
118  PTemp.P1 = HStack(vec_KR[0], vec_tis[0]);
119  PTemp.P2 = HStack(vec_KR[1], vec_tis[1]);
120  PTemp.P3 = HStack(vec_KR[2], vec_tis[2]);
121 
122  P.push_back(PTemp);
123  }
124  }
125 
126  // Compute the residual of reprojections
127  static double error(const TrifocalTensorModel& Tensor, const Vec2& pt0, const Vec2& pt1, const Vec2& pt2)
128  {
129  return TrifocalTensorModel::Error(Tensor, pt0, pt1, pt2);
130  }
131 };
132 
133 } // namespace aliceVision
aliceVision::translations_Triplet_Solver::getMaximumNbModels
std::size_t getMaximumNbModels() const
Return the maximum number of models.
Definition: triplet_tijsAndXis_kernel.hpp:75
aliceVision::translations_Triplet_Solver::getMinimumNbRequiredSamples
std::size_t getMinimumNbRequiredSamples() const
Return the minimum number of required samples.
Definition: triplet_tijsAndXis_kernel.hpp:69
aliceVision::trifocal::kernel::TrifocalTensorModel
A trifocal tensor seen as 3 projective cameras.
Definition: triplet_tijsAndXis_kernel.hpp:32
aliceVision::project
Vec2 project(const Mat34 &P, const Vec3 &X)
Compute P*[X|1.0]. Transformed from homogeneous to euclidean coordinates.
Definition: projection.cpp:146
aliceVision::translations_Triplet_Solver::solve
void solve(const Mat &pt0, const Mat &pt1, const Mat &pt2, const std::vector< Mat3 > &vec_KR, std::vector< TrifocalTensorModel > &P, const double ThresholdUpperBound) const
Solve the computation of the "tensor".
Definition: triplet_tijsAndXis_kernel.hpp:78
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::linearProgramming::MOSEKSolver
MOSEK wrapper for the ISolver.
Definition: MOSEKSolver.hpp:24
aliceVision::multiview::Triangulation
Definition: Triangulation.hpp:105
aliceVision::translations_Triplet_Solver
Solve the translations and the structure of a view-triplet that have known rotations.
Definition: triplet_tijsAndXis_kernel.hpp:63
aliceVision::lInfinityCV::Translation_Structure_L1_ConstraintBuilder
Definition: tijsAndXis_From_xi_Ri.hpp:158