AliceVision
Photogrammetric Computer Vision Framework
TriangulationSphericalKernel.hpp
1 // This file is part of the AliceVision project.
2 // Copyright (c) 2024 AliceVision contributors.
3 // This Source Code Form is subject to the terms of the Mozilla Public License,
4 // v. 2.0. If a copy of the MPL was not distributed with this file,
5 // You can obtain one at https://mozilla.org/MPL/2.0/.
6 #include <aliceVision/robustEstimation/ISolver.hpp>
7 #include <aliceVision/robustEstimation/IRansacKernel.hpp>
8 
9 namespace aliceVision {
10 namespace multiview {
11 
16 class TriangulationSphericalKernel : public robustEstimation::IRansacKernel<robustEstimation::MatrixModel<Vec4>>
17 {
18 public:
20 public:
29  const std::vector<Vec2> & observations,
30  const std::vector<double> & weights,
31  const std::vector<Eigen::Matrix4d>& poses,
32  std::vector<std::shared_ptr<camera::IntrinsicBase>> & intrinsics
33  )
34  : _poses(poses)
35  , _intrinsics(intrinsics)
36  , _weights(weights)
37  {
38  for (int id = 0; id < observations.size(); id++)
39  {
40  //Lift all points onto the metric unit sphere
41  const Vec2 & obs = observations[id];
42  std::shared_ptr<camera::IntrinsicBase> camera = _intrinsics[id];
43 
44  _observations.push_back(camera->getUndistortedPixel(obs));
45  _lifted.push_back(camera->toUnitSphere(camera->removeDistortion(camera->ima2cam(obs))));
46  }
47  }
48 
53  inline std::size_t getMinimumNbRequiredSamples() const override
54  {
55  return 2;
56  }
57 
62  inline std::size_t getMaximumNbModels() const override
63  {
64  return 1;
65  }
66 
67  inline std::size_t getMinimumNbRequiredSamplesLS() const override
68  {
69  return 2;
70  }
71 
77  void fit(const std::vector<std::size_t>& samples, std::vector<ModelT>& models) const override
78  {
79  std::vector<Vec3> sampledPts;
80  std::vector<Eigen::Matrix4d> sampledMats;
81 
82  for (int i = 0; i < samples.size(); i++)
83  {
84  std::size_t idx = samples[i];
85  sampledMats.push_back(_poses[idx]);
86  sampledPts.push_back(_lifted[idx]);
87  }
88 
89  _solver.solve(sampledPts, sampledMats, models);
90  }
91 
98  void fitLS(const std::vector<std::size_t>& inliers,
99  std::vector<ModelT>& models,
100  const std::vector<double> *weights = nullptr) const override
101  {
102  std::vector<Vec3> sampledPts;
103  std::vector<Eigen::Matrix4d> sampledMats;
104 
105  for (int i = 0; i < inliers.size(); i++)
106  {
107  std::size_t idx = inliers[i];
108  sampledMats.push_back(_poses[idx]);
109  sampledPts.push_back(_lifted[idx]);
110  }
111 
112  if(weights != nullptr)
113  _solver.solve(sampledPts, sampledMats, models, *weights);
114  else
115  _solver.solve(sampledPts, sampledMats, models);
116  }
117 
118 
127  void computeWeights(const ModelT & model,
128  const std::vector<std::size_t> &inliers,
129  std::vector<double>& weights,
130  const double eps = 0.001) const override
131  {
132  const auto numInliers = inliers.size();
133  weights.resize(numInliers);
134 
135  for(std::size_t sample = 0; sample < numInliers; ++sample)
136  {
137  const auto idx = inliers[sample];
138  weights[sample] = 1.0 / std::pow(std::max(eps, error(idx, model)), 2);
139  }
140  }
141 
148  double error(std::size_t sample, const ModelT & model) const override
149  {
150  Vec4 X = model.getMatrix();
151  if (std::abs(X(3)) > 1e-16)
152  {
153  X = X / X(3);
154  }
155 
156  double w = _weights[sample];
157 
158  Vec2 residual = _intrinsics[sample]->residual(_poses[sample], X, _observations[sample], false);
159 
160  return residual.norm() * w;
161  }
162 
168  void errors(const ModelT & model, std::vector<double>& errors) const override
169  {
170  errors.resize(nbSamples());
171  for(Mat::Index i = 0; i < _lifted.size(); ++i)
172  {
173  errors[i] = error(i, model);
174  }
175  }
176 
182  {
183 
184  }
185 
190  std::size_t nbSamples() const override
191  {
192  return _lifted.size();
193  }
194 
195  double logalpha0() const override
196  {
197  std::runtime_error("Method 'logalpha0()' is not defined for 'NViewsTriangulationLORansac'.");
198  return 0.0;
199  }
200 
201  double errorVectorDimension() const override
202  {
203  std::runtime_error("Method 'errorVectorDimension()' is not defined for 'NViewsTriangulationLORansac'.");
204  return 0.0;
205  }
206 
207  double unormalizeError(double val) const override
208  {
209  std::runtime_error("Method 'unormalizeError()' is not defined for 'NViewsTriangulationLORansac'.");
210  return 0.0;
211  }
212 
213  Mat3 normalizer1() const override
214  {
215  std::runtime_error("Method 'normalizer1()' is not defined for 'NViewsTriangulationLORansac'.");
216  return Mat3();
217  }
218 
219  double thresholdNormalizer() const override
220  {
221  std::runtime_error("Method 'thresholdNormalizer()' is not defined for 'NViewsTriangulationLORansac'.");
222  return 0.0;
223  }
224 
225 private:
226  std::vector<Vec3> _lifted;
227  std::vector<Vec2> _observations;
228  std::vector<double> _weights;
229  const std::vector<Eigen::Matrix4d> _poses;
230  const std::vector<std::shared_ptr<camera::IntrinsicBase>> _intrinsics;
231  multiview::TriangulateNViewsSphericalSolver _solver;
232 };
233 
234 }
235 }
aliceVision::multiview::TriangulationSphericalKernel::computeWeights
void computeWeights(const ModelT &model, const std::vector< std::size_t > &inliers, std::vector< double > &weights, const double eps=0.001) const override
Compute the weights..
Definition: TriangulationSphericalKernel.hpp:127
aliceVision::multiview::TriangulationSphericalKernel::error
double error(std::size_t sample, const ModelT &model) const override
Error for the i-th observation.
Definition: TriangulationSphericalKernel.hpp:148
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::multiview::TriangulationSphericalKernel::fit
void fit(const std::vector< std::size_t > &samples, std::vector< ModelT > &models) const override
Triangulate 2 points.
Definition: TriangulationSphericalKernel.hpp:77
aliceVision::multiview::TriangulationSphericalKernel::getMinimumNbRequiredSamples
std::size_t getMinimumNbRequiredSamples() const override
Return the minimum number of required samples.
Definition: TriangulationSphericalKernel.hpp:53
aliceVision::robustEstimation::MatrixModel
Matrix based model to be used in a solver.
Definition: ISolver.hpp:88
aliceVision::multiview::TriangulationSphericalKernel::getMaximumNbModels
std::size_t getMaximumNbModels() const override
Return the maximum number of models.
Definition: TriangulationSphericalKernel.hpp:62
aliceVision::multiview::TriangulationSphericalKernel::TriangulationSphericalKernel
TriangulationSphericalKernel(const std::vector< Vec2 > &observations, const std::vector< double > &weights, const std::vector< Eigen::Matrix4d > &poses, std::vector< std::shared_ptr< camera::IntrinsicBase >> &intrinsics)
Constructor.
Definition: TriangulationSphericalKernel.hpp:28
aliceVision::multiview::TriangulationSphericalKernel::unnormalize
void unnormalize(robustEstimation::MatrixModel< Vec4 > &model) const override
Unnormalize the model. (not used)
Definition: TriangulationSphericalKernel.hpp:181
aliceVision::multiview::TriangulationSphericalKernel::fitLS
void fitLS(const std::vector< std::size_t > &inliers, std::vector< ModelT > &models, const std::vector< double > *weights=nullptr) const override
Triangulate N points using the least squared solver.
Definition: TriangulationSphericalKernel.hpp:98
aliceVision::multiview::TriangulationSphericalKernel::errors
void errors(const ModelT &model, std::vector< double > &errors) const override
Error for each view.
Definition: TriangulationSphericalKernel.hpp:168
aliceVision::multiview::TriangulationSphericalKernel
Definition: TriangulationSphericalKernel.hpp:16
aliceVision::multiview::TriangulationSphericalKernel::nbSamples
std::size_t nbSamples() const override
Return the number of view.
Definition: TriangulationSphericalKernel.hpp:190
aliceVision::robustEstimation::IRansacKernel
A generic kernel used for the ACRANSAC / LORANSAC framework.
Definition: IRansacKernel.hpp:24