AliceVision
Photogrammetric Computer Vision Framework
IntrinsicScaleOffsetDisto.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 "IntrinsicScaleOffset.hpp"
11 #include "IntrinsicInitMode.hpp"
12 #include "Distortion.hpp"
13 #include "Undistortion.hpp"
14 
15 #include <memory>
16 
17 namespace aliceVision {
18 namespace camera {
19 
24 {
25  public:
26  IntrinsicScaleOffsetDisto(unsigned int w,
27  unsigned int h,
28  double scaleX,
29  double scaleY,
30  double offsetX,
31  double offsetY,
32  std::shared_ptr<Distortion> distortion = nullptr,
33  std::shared_ptr<Undistortion> undistortion = nullptr)
34  : IntrinsicScaleOffset(w, h, scaleX, scaleY, offsetX, offsetY),
35  _pDistortion(distortion),
36  _pUndistortion(undistortion)
37  {}
38 
40  : IntrinsicScaleOffset(other),
41  _distortionInitializationMode(other._distortionInitializationMode)
42  {
43  if (other._pDistortion)
44  {
45  _pDistortion = std::shared_ptr<Distortion>(other._pDistortion->clone());
46  }
47  else
48  {
49  _pDistortion = nullptr;
50  }
51 
52  if (other._pUndistortion)
53  {
54  _pUndistortion = std::shared_ptr<Undistortion>(other._pUndistortion->clone());
55  }
56  else
57  {
58  _pUndistortion = nullptr;
59  }
60  }
61 
62  static std::shared_ptr<IntrinsicScaleOffsetDisto> cast(std::shared_ptr<IntrinsicBase> sptr);
63 
64  void assign(const IntrinsicBase& other) override { *this = dynamic_cast<const IntrinsicScaleOffsetDisto&>(other); }
65 
71  bool operator==(const IntrinsicBase& otherBase) const override;
72 
79  bool equalTo(const IntrinsicBase& otherBase, bool ignoreDistortion) const;
80 
81  void setDistortionObject(std::shared_ptr<Distortion> object) { _pDistortion = object; }
82 
83  bool hasDistortion() const override { return _pDistortion != nullptr || _pUndistortion != nullptr; }
84 
90  Vec2 addDistortion(const Vec2& p) const override
91  {
92  if (_pDistortion)
93  {
94  return _pDistortion->addDistortion(p);
95  }
96  else if (_pUndistortion)
97  {
98  return ima2cam(_pUndistortion->inverse(cam2ima(p)));
99  }
100  return p;
101  }
102 
108  Vec2 removeDistortion(const Vec2& p) const override
109  {
110  if (_pUndistortion)
111  {
112  return ima2cam(_pUndistortion->undistort(cam2ima(p)));
113  }
114  else if (_pDistortion)
115  {
116  return _pDistortion->removeDistortion(p);
117  }
118  return p;
119  }
120 
122  Vec2 getUndistortedPixel(const Vec2& p) const override;
123 
125  Vec2 getDistortedPixel(const Vec2& p) const override;
126 
127  std::size_t getDistortionParamsSize() const
128  {
129  if (_pDistortion)
130  {
131  return _pDistortion->getParameters().size();
132  }
133  return 0;
134  }
135 
136  std::vector<double> getDistortionParams() const
137  {
138  if (!_pDistortion)
139  {
140  return std::vector<double>();
141  }
142  return _pDistortion->getParameters();
143  }
144 
145  void setDistortionParams(const std::vector<double>& distortionParams)
146  {
147  std::size_t expected = 0;
148  if (_pDistortion != nullptr)
149  {
150  expected = _pDistortion->getDistortionParametersCount();
151  }
152 
153  if (distortionParams.size() != expected)
154  {
155  throwSetDistortionParamsCountError(expected, distortionParams.size());
156  }
157 
158  if (_pDistortion)
159  {
160  _pDistortion->getParameters() = distortionParams;
161  }
162  }
163 
164  template<class F>
165  void setDistortionParamsFn(F&& callback)
166  {
167  if (_pDistortion == nullptr)
168  return;
169 
170  auto& params = _pDistortion->getParameters();
171  for (std::size_t i = 0; i < params.size(); ++i)
172  {
173  params[i] = callback(i);
174  }
175  }
176 
177  template<class F>
178  void setDistortionParamsFn(std::size_t count, F&& callback)
179  {
180  if (_pDistortion == nullptr)
181  {
182  if (count != 0)
183  {
184  throwSetDistortionParamsCountError(0, count);
185  }
186  return;
187  }
188 
189  auto& params = _pDistortion->getParameters();
190  if (params.size() != count)
191  {
192  throwSetDistortionParamsCountError(params.size(), count);
193  }
194 
195  for (std::size_t i = 0; i < params.size(); ++i)
196  {
197  params[i] = callback(i);
198  }
199  }
200 
201  // Data wrapper for non linear optimization (get data)
202  std::vector<double> getParameters() const override
203  {
204  std::vector<double> params = {_scale(0), _scale(1), _offset(0), _offset(1)};
205 
206  return params;
207  }
208 
209  std::size_t getParametersSize() const override { return 4; }
210 
211  // Data wrapper for non linear optimization (update from data)
212  bool updateFromParams(const std::vector<double>& params) override;
213 
214  float getMaximalDistortion([[maybe_unused]] double minRadius, double maxRadius) const override
215  {
216  if (_pDistortion == nullptr)
217  {
218  return maxRadius;
219  }
220 
221  return _pDistortion->getUndistortedRadius(maxRadius);
222  }
223 
224  Eigen::Matrix<double, 2, 2> getDerivativeAddDistoWrtPt(const Vec2& pt) const
225  {
226  if (this->_pDistortion == nullptr)
227  {
228  return Eigen::Matrix<double, 2, 2>::Identity();
229  }
230  return this->_pDistortion->getDerivativeAddDistoWrtPt(pt);
231  }
232 
233  Eigen::Matrix<double, 2, 2> getDerivativeRemoveDistoWrtPt(const Vec2& pt) const
234  {
235  if (this->_pDistortion == nullptr)
236  {
237  return Eigen::Matrix<double, 2, 2>::Identity();
238  }
239 
240  return this->_pDistortion->getDerivativeRemoveDistoWrtPt(pt);
241  }
242 
243  Eigen::MatrixXd getDerivativeAddDistoWrtDisto(const Vec2& pt) const
244  {
245  if (this->_pDistortion == nullptr)
246  {
247  return Eigen::MatrixXd(0, 0);
248  }
249 
250  return this->_pDistortion->getDerivativeAddDistoWrtDisto(pt);
251  }
252 
253  Eigen::MatrixXd getDerivativeRemoveDistoWrtDisto(const Vec2& pt) const
254  {
255  if (this->_pDistortion == nullptr)
256  {
257  return Eigen::MatrixXd(0, 0);
258  }
259 
260  return this->_pDistortion->getDerivativeRemoveDistoWrtDisto(pt);
261  }
262 
263  virtual Eigen::Matrix<double, 2, Eigen::Dynamic> getDerivativeTransformProjectWrtDistortion(const Eigen::Matrix4d& pose,
264  const Vec4& pt) const = 0;
265 
266  virtual Eigen::Matrix<double, 3, Eigen::Dynamic> getDerivativeBackProjectUnitWrtDistortion(const Vec2& pt2D) const = 0;
267 
272  inline void setDistortionInitializationMode(EInitMode distortionInitializationMode) override
273  {
274  _distortionInitializationMode = distortionInitializationMode;
275  }
276 
281  inline EInitMode getDistortionInitializationMode() const override { return _distortionInitializationMode; }
282 
283  std::shared_ptr<Distortion> getDistortion() const { return _pDistortion; }
284 
285  ~IntrinsicScaleOffsetDisto() override = default;
286 
287  void setUndistortionObject(std::shared_ptr<Undistortion> object) { _pUndistortion = object; }
288 
289  std::shared_ptr<Undistortion> getUndistortion() const { return _pUndistortion; }
290 
291  protected:
292  void throwSetDistortionParamsCountError(std::size_t expected, std::size_t received)
293  {
294  std::stringstream s;
295  s << "IntrinsicScaleOffsetDisto::setDistortionParams*: "
296  << "wrong number of distortion parameters (expected: " << expected << ", given:" << received << ").";
297  throw std::runtime_error(s.str());
298  }
299 
300  std::shared_ptr<Distortion> _pDistortion;
301  std::shared_ptr<Undistortion> _pUndistortion;
302 
303  // Distortion initialization mode
304  EInitMode _distortionInitializationMode = EInitMode::NONE;
305 };
306 
307 } // namespace camera
308 } // namespace aliceVision
aliceVision::camera::IntrinsicScaleOffsetDisto::setDistortionInitializationMode
void setDistortionInitializationMode(EInitMode distortionInitializationMode) override
Set The intrinsic disto initialization mode.
Definition: IntrinsicScaleOffsetDisto.hpp:272
aliceVision::camera::IntrinsicScaleOffsetDisto::hasDistortion
bool hasDistortion() const override
Camera model handles a distortion field.
Definition: IntrinsicScaleOffsetDisto.hpp:83
aliceVision::camera::IntrinsicScaleOffsetDisto::removeDistortion
Vec2 removeDistortion(const Vec2 &p) const override
Create a new point from a given point by removing distortion.
Definition: IntrinsicScaleOffsetDisto.hpp:108
aliceVision::camera::IntrinsicScaleOffset::ima2cam
Vec2 ima2cam(const Vec2 &p) const override
Transform a point from the image plane to the camera plane.
Definition: IntrinsicScaleOffset.cpp:60
aliceVision::camera::IntrinsicScaleOffsetDisto::updateFromParams
bool updateFromParams(const std::vector< double > &params) override
Update intrinsic parameters.
Definition: IntrinsicScaleOffsetDisto.cpp:97
aliceVision::camera::IntrinsicScaleOffsetDisto::equalTo
bool equalTo(const IntrinsicBase &otherBase, bool ignoreDistortion) const
compare to another intrinsic object
Definition: IntrinsicScaleOffsetDisto.cpp:22
aliceVision::camera::IntrinsicBase::h
unsigned int h() const
Get the intrinsic image height.
Definition: IntrinsicBase.hpp:58
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::camera::IntrinsicBase::w
unsigned int w() const
Get the intrinsic image width.
Definition: IntrinsicBase.hpp:52
aliceVision::camera::IntrinsicScaleOffsetDisto
Class with disto.
Definition: IntrinsicScaleOffsetDisto.hpp:23
aliceVision::camera::IntrinsicScaleOffsetDisto::operator==
bool operator==(const IntrinsicBase &otherBase) const override
compare to another intrinsic object
Definition: IntrinsicScaleOffsetDisto.cpp:17
aliceVision::camera::IntrinsicScaleOffsetDisto::addDistortion
Vec2 addDistortion(const Vec2 &p) const override
Create a new point from a given point by adding distortion.
Definition: IntrinsicScaleOffsetDisto.hpp:90
aliceVision::camera::IntrinsicScaleOffset::cam2ima
Vec2 cam2ima(const Vec2 &p) const override
Transform a point from the camera plane to the image plane.
Definition: IntrinsicScaleOffset.cpp:36
aliceVision::camera::IntrinsicScaleOffsetDisto::getDistortionInitializationMode
EInitMode getDistortionInitializationMode() const override
Get the intrinsic disto initialization mode.
Definition: IntrinsicScaleOffsetDisto.hpp:281
aliceVision::camera::IntrinsicScaleOffsetDisto::getUndistortedPixel
Vec2 getUndistortedPixel(const Vec2 &p) const override
Return the un-distorted pixel (with removed distortion)
Definition: IntrinsicScaleOffsetDisto.cpp:93
aliceVision::camera::IntrinsicScaleOffsetDisto::getDistortedPixel
Vec2 getDistortedPixel(const Vec2 &p) const override
Return the distorted pixel (with added distortion)
Definition: IntrinsicScaleOffsetDisto.cpp:95
aliceVision::camera::IntrinsicBase
Basis class for all intrinsic parameters of a camera.
Definition: IntrinsicBase.hpp:27
aliceVision::camera::IntrinsicScaleOffsetDisto::getParameters
std::vector< double > getParameters() const override
Get the intrinsic parameters.
Definition: IntrinsicScaleOffsetDisto.hpp:202
aliceVision::camera::IntrinsicScaleOffsetDisto::getParametersSize
std::size_t getParametersSize() const override
Get the count of intrinsic parameters.
Definition: IntrinsicScaleOffsetDisto.hpp:209
aliceVision::camera::IntrinsicScaleOffsetDisto::assign
void assign(const IntrinsicBase &other) override
Assign object.
Definition: IntrinsicScaleOffsetDisto.hpp:64
aliceVision::camera::IntrinsicScaleOffset
Class with "focal" (scale) and center offset.
Definition: IntrinsicScaleOffset.hpp:18