AliceVision
Photogrammetric Computer Vision Framework
IntrinsicBase.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/types.hpp>
11 #include <aliceVision/numeric/numeric.hpp>
12 #include <aliceVision/camera/cameraCommon.hpp>
13 #include <aliceVision/camera/IntrinsicInitMode.hpp>
14 #include <aliceVision/geometry/Pose3.hpp>
15 #include <aliceVision/version.hpp>
16 
17 #include <vector>
18 
19 namespace aliceVision {
20 namespace camera {
21 
28 {
29  public:
30  using sptr = std::shared_ptr<IntrinsicBase>;
31  using ptr = IntrinsicBase*;
32 
33  public:
34  explicit IntrinsicBase(unsigned int width, unsigned int height, const std::string& serialNumber = "")
35  : _w(width),
36  _h(height),
37  _serialNumber(serialNumber)
38  {}
39 
40  virtual ~IntrinsicBase() = default;
41 
46  inline bool isLocked() const { return _locked; }
47 
52  inline unsigned int w() const { return _w; }
53 
58  inline unsigned int h() const { return _h; }
59 
64  inline double sensorWidth() const { return _sensorWidth; }
65 
70  inline double sensorHeight() const { return _sensorHeight; }
71 
76  inline const std::string& serialNumber() const { return _serialNumber; }
77 
82  inline EInitMode getInitializationMode() const { return _initializationMode; }
83 
89  virtual bool operator==(const IntrinsicBase& other) const;
90 
91  inline bool operator!=(const IntrinsicBase& other) const { return !(*this == other); }
92 
100  Vec2 transformProject(const geometry::Pose3& pose, const Vec4& pt3D, bool applyDistortion = true) const
101  {
102  return transformProject(pose.getHomogeneous(), pt3D, applyDistortion);
103  }
104 
112  virtual Vec2 transformProject(const Eigen::Matrix4d& pose, const Vec4& pt3D, bool applyDistortion = true) const = 0;
113 
120  virtual Vec2 project(const Vec4& pt3D, bool applyDistortion = true) const = 0;
121 
130  Vec3 backprojectTransform(const Vec2& pt2D,
131  bool applyUndistortion = true,
132  const geometry::Pose3& pose = geometry::Pose3(),
133  double depth = 1.0) const;
134 
140  Vec3 backProjectUnit(const Vec2& pt2D) const;
141 
142  Vec4 getCartesianfromSphericalCoordinates(const Vec3& pt);
143 
144  Eigen::Matrix<double, 4, 3> getDerivativeCartesianfromSphericalCoordinates(const Vec3& pt);
145 
152  virtual Eigen::Matrix<double, 2, 3> getDerivativeTransformProjectWrtPoint3(const Eigen::Matrix4d& pose, const Vec4& pt3D) const = 0;
153 
160  virtual Eigen::Matrix<double, 2, Eigen::Dynamic> getDerivativeTransformProjectWrtParams(const Eigen::Matrix4d& pos, const Vec4& pt3D) const = 0;
161 
167  virtual Eigen::Matrix<double, 3, Eigen::Dynamic> getDerivativeBackProjectUnitWrtParams(const Vec2& pt2D) const = 0;
168 
177  inline Vec2 residual(const geometry::Pose3& pose, const Vec4& X, const Vec2& x, bool applyDistortion = true) const
178  {
179  // We will compare to an undistorted point, so always ignore the distortion when computing coordinates
180  const Vec2 proj = this->transformProject(pose, X, false);
181 
182  return ((applyDistortion) ? this->getUndistortedPixel(x) : x) - proj;
183  }
184 
192  inline Mat2X residuals(const geometry::Pose3& pose, const Mat3X& X, const Mat2X& x) const
193  {
194  assert(X.cols() == x.cols());
195  const std::size_t numPts = x.cols();
196  Mat2X residuals = Mat2X::Zero(2, numPts);
197  for (std::size_t i = 0; i < numPts; ++i)
198  {
199  residuals.col(i) = residual(pose, ((const Vec3&)X.col(i)).homogeneous(), x.col(i));
200  }
201  return residuals;
202  }
203 
207  inline void lock() { _locked = true; }
208 
212  inline void unlock() { _locked = false; }
213 
218  inline void setWidth(unsigned int width) { _w = width; }
219 
224  inline void setHeight(unsigned int height) { _h = height; }
225 
230  inline void setSensorWidth(double width) { _sensorWidth = width; }
231 
236  inline void setSensorHeight(double height) { _sensorHeight = height; }
237 
242  inline void setSerialNumber(const std::string& serialNumber) { _serialNumber = serialNumber; }
243 
248  inline void setInitializationMode(EInitMode initializationMode) { _initializationMode = initializationMode; }
249 
250  // Virtual members
251 
255  virtual IntrinsicBase* clone() const = 0;
256 
261  virtual void assign(const IntrinsicBase& other) = 0;
262 
267  virtual EINTRINSIC getType() const = 0;
268 
273  std::string getTypeStr() const { return EINTRINSIC_enumToString(getType()); }
274 
279  virtual std::vector<double> getParameters() const = 0;
280 
285  virtual std::size_t getParametersSize() const = 0;
286 
292  virtual bool updateFromParams(const std::vector<double>& params) = 0;
293 
300  virtual bool importFromParams(const std::vector<double>& params, const Version& inputVersion) = 0;
301 
307  virtual Vec2 cam2ima(const Vec2& p) const = 0;
308 
314  virtual Vec2 ima2cam(const Vec2& p) const = 0;
315 
320  virtual bool hasDistortion() const { return false; }
321 
327  virtual Vec2 addDistortion(const Vec2& p) const = 0;
328 
334  virtual Vec2 removeDistortion(const Vec2& p) const = 0;
335 
341  virtual Vec2 getUndistortedPixel(const Vec2& p) const = 0;
342 
348  virtual Vec2 getDistortedPixel(const Vec2& p) const = 0;
349 
354  virtual void setDistortionInitializationMode(EInitMode distortionInitializationMode) = 0;
355 
360  virtual EInitMode getDistortionInitializationMode() const = 0;
361 
367  virtual double imagePlaneToCameraPlaneError(double value) const = 0;
368 
373  virtual double pixelProbability() const = 0;
374 
379  virtual bool isValid() const { return _w != 0 && _h != 0; }
380 
386  virtual bool isVisibleRay(const Vec3& ray) const = 0;
387 
393  virtual bool isVisible(const Vec2& pix) const;
394 
400  virtual bool isVisible(const Vec2f& pix) const;
401 
409  virtual float getMaximalDistortion(double minRadius, double maxRadius) const;
410 
415  virtual std::size_t hashValue() const;
416 
422  virtual void rescale(float factorW, float factorH);
423 
429  virtual Vec3 toUnitSphere(const Vec2& pt) const = 0;
430 
435  virtual double getHorizontalFov() const = 0;
436 
441  virtual double getVerticalFov() const = 0;
442 
449  virtual void initializeState()
450  {
451  if (_locked)
452  {
453  _state = EEstimatorParameterState::CONSTANT;
454  }
455  else
456  {
457  _state = EEstimatorParameterState::REFINED;
458  }
459  }
460 
465  EEstimatorParameterState getState() const { return _state; }
466 
471  void setState(EEstimatorParameterState state) { _state = state; }
472 
473  protected:
474  std::string _serialNumber;
475  double _sensorWidth = 36.0;
476  double _sensorHeight = 24.0;
477  unsigned int _w = 0;
478  unsigned int _h = 0;
479 
481  EInitMode _initializationMode = EInitMode::NONE;
482 
484  bool _locked = false;
485  EEstimatorParameterState _state = EEstimatorParameterState::REFINED;
486 };
487 
496 inline Vec3 applyIntrinsicExtrinsic(const geometry::Pose3& pose, const IntrinsicBase* intrinsic, const Vec2& x)
497 {
498  // x = (u, v, 1.0) // image coordinates
499  // X = R.t() * K.inv() * x + C // Camera world point
500  // getting the ray:
501  // ray = X - C = R.t() * K.inv() * x
502  return (pose.rotation().transpose() * intrinsic->toUnitSphere(intrinsic->removeDistortion(intrinsic->ima2cam(x)))).normalized();
503 }
504 
511 inline double angleBetweenRays(const Vec3& ray1, const Vec3& ray2)
512 {
513  const double mag = ray1.norm() * ray2.norm();
514  const double dotAngle = ray1.dot(ray2);
515  return radianToDegree(acos(clamp(dotAngle / mag, -1.0 + 1.e-8, 1.0 - 1.e-8)));
516 }
517 
528 inline double angleBetweenRays(const geometry::Pose3& pose1,
529  const IntrinsicBase* intrinsic1,
530  const geometry::Pose3& pose2,
531  const IntrinsicBase* intrinsic2,
532  const Vec2& x1,
533  const Vec2& x2)
534 {
535  const Vec3 ray1 = applyIntrinsicExtrinsic(pose1, intrinsic1, x1);
536  const Vec3 ray2 = applyIntrinsicExtrinsic(pose2, intrinsic2, x2);
537  return angleBetweenRays(ray1, ray2);
538 }
539 
547 inline double angleBetweenRays(const geometry::Pose3& pose1, const geometry::Pose3& pose2, const Vec3& pt3D)
548 {
549  const Vec3 ray1 = pt3D - pose1.center();
550  const Vec3 ray2 = pt3D - pose2.center();
551  return angleBetweenRays(ray1, ray2);
552 }
553 
554 } // namespace camera
555 
556 } // namespace aliceVision
aliceVision::camera::IntrinsicBase::getHorizontalFov
virtual double getHorizontalFov() const =0
Get the horizontal FOV in radians.
aliceVision::camera::IntrinsicBase::setWidth
void setWidth(unsigned int width)
Set the intrinsic image width.
Definition: IntrinsicBase.hpp:218
aliceVision::EEstimatorParameterState
EEstimatorParameterState
Defines the state of a parameter for an estimator.
Definition: types.hpp:38
aliceVision::camera::IntrinsicBase::sensorWidth
double sensorWidth() const
Get the intrinsic sensor width.
Definition: IntrinsicBase.hpp:64
aliceVision::camera::IntrinsicBase::_locked
bool _locked
intrinsic lock
Definition: IntrinsicBase.hpp:484
aliceVision::camera::IntrinsicBase::getVerticalFov
virtual double getVerticalFov() const =0
Get the vertical FOV in radians.
aliceVision::camera::IntrinsicBase::setDistortionInitializationMode
virtual void setDistortionInitializationMode(EInitMode distortionInitializationMode)=0
Set The intrinsic disto initialization mode.
aliceVision::camera::IntrinsicBase::getInitializationMode
EInitMode getInitializationMode() const
Get the intrinsic initialization mode.
Definition: IntrinsicBase.hpp:82
aliceVision::camera::IntrinsicBase::transformProject
Vec2 transformProject(const geometry::Pose3 &pose, const Vec4 &pt3D, bool applyDistortion=true) const
Projection of a 3D point into the camera plane (Apply pose, disto (if any) and Intrinsics)
Definition: IntrinsicBase.hpp:100
aliceVision::camera::IntrinsicBase::assign
virtual void assign(const IntrinsicBase &other)=0
Assign object.
aliceVision::camera::IntrinsicBase::hashValue
virtual std::size_t hashValue() const
Generate an unique Hash from the camera parameters (used for grouping)
Definition: IntrinsicBase.cpp:87
aliceVision::camera::IntrinsicBase::getParametersSize
virtual std::size_t getParametersSize() const =0
Get the count of intrinsic parameters.
aliceVision::camera::IntrinsicBase::sensorHeight
double sensorHeight() const
Get the intrinsic sensor height.
Definition: IntrinsicBase.hpp:70
aliceVision::camera::IntrinsicBase::initializeState
virtual void initializeState()
Initialize state with default values The estimator state is used in the bundle adjustment to decide i...
Definition: IntrinsicBase.hpp:449
aliceVision::camera::IntrinsicBase::getState
EEstimatorParameterState getState() const
accessor to estimator state
Definition: IntrinsicBase.hpp:465
aliceVision::camera::IntrinsicBase::importFromParams
virtual bool importFromParams(const std::vector< double > &params, const Version &inputVersion)=0
Import intrinsic parameters from external array.
aliceVision::camera::IntrinsicBase::cam2ima
virtual Vec2 cam2ima(const Vec2 &p) const =0
Transform a point from the camera plane to the image plane.
aliceVision::camera::IntrinsicBase::h
unsigned int h() const
Get the intrinsic image height.
Definition: IntrinsicBase.hpp:58
aliceVision::camera::IntrinsicBase::lock
void lock()
Lock the intrinsic.
Definition: IntrinsicBase.hpp:207
aliceVision::camera::IntrinsicBase::backprojectTransform
Vec3 backprojectTransform(const Vec2 &pt2D, bool applyUndistortion=true, const geometry::Pose3 &pose=geometry::Pose3(), double depth=1.0) const
Back-projection of a 2D point at a specific depth into a 3D point.
Definition: IntrinsicBase.cpp:20
aliceVision::camera::IntrinsicBase::getMaximalDistortion
virtual float getMaximalDistortion(double minRadius, double maxRadius) const
Assuming the distortion is a function of radius, estimate the maximal undistorted radius for a range ...
Definition: IntrinsicBase.cpp:81
aliceVision::camera::IntrinsicBase::isValid
virtual bool isValid() const
Return true if the intrinsic is valid.
Definition: IntrinsicBase.hpp:379
aliceVision::camera::IntrinsicBase::operator==
virtual bool operator==(const IntrinsicBase &other) const
operator ==
Definition: IntrinsicBase.cpp:14
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::camera::IntrinsicBase::toUnitSphere
virtual Vec3 toUnitSphere(const Vec2 &pt) const =0
Transform a given point (in pixels) to unit sphere in meters.
aliceVision::camera::IntrinsicBase::updateFromParams
virtual bool updateFromParams(const std::vector< double > &params)=0
Update intrinsic parameters.
aliceVision::camera::IntrinsicBase::w
unsigned int w() const
Get the intrinsic image width.
Definition: IntrinsicBase.hpp:52
aliceVision::camera::IntrinsicBase::serialNumber
const std::string & serialNumber() const
Get the intrinsic serial number.
Definition: IntrinsicBase.hpp:76
aliceVision::camera::IntrinsicBase::getDerivativeTransformProjectWrtPoint3
virtual Eigen::Matrix< double, 2, 3 > getDerivativeTransformProjectWrtPoint3(const Eigen::Matrix4d &pose, const Vec4 &pt3D) const =0
Get the derivative of a projection of a 3D point into the camera plane.
aliceVision::camera::IntrinsicBase::residuals
Mat2X residuals(const geometry::Pose3 &pose, const Mat3X &X, const Mat2X &x) const
Compute the residuals between the 3D projected point X and an image observation x.
Definition: IntrinsicBase.hpp:192
aliceVision::camera::IntrinsicBase::isVisible
virtual bool isVisible(const Vec2 &pix) const
Return true if these pixel coordinates should be visible in the image.
Definition: IntrinsicBase.cpp:61
aliceVision::camera::IntrinsicBase::getParameters
virtual std::vector< double > getParameters() const =0
Get the intrinsic parameters.
aliceVision::camera::IntrinsicBase::isLocked
bool isLocked() const
Get the lock state of the intrinsic.
Definition: IntrinsicBase.hpp:46
aliceVision::camera::IntrinsicBase::addDistortion
virtual Vec2 addDistortion(const Vec2 &p) const =0
Add the distortion field to a point (that is in normalized camera frame)
aliceVision::camera::IntrinsicBase::getDistortionInitializationMode
virtual EInitMode getDistortionInitializationMode() const =0
Get the intrinsic disto initialization mode.
aliceVision::camera::IntrinsicBase::setSensorHeight
void setSensorHeight(double height)
Set the intrinsic sensor height.
Definition: IntrinsicBase.hpp:236
aliceVision::Version
Definition: version.hpp:30
aliceVision::camera::IntrinsicBase::clone
virtual IntrinsicBase * clone() const =0
Polymorphic clone.
aliceVision::camera::IntrinsicBase::setState
void setState(EEstimatorParameterState state)
mutator for the estimator state
Definition: IntrinsicBase.hpp:471
aliceVision::camera::IntrinsicBase::setSerialNumber
void setSerialNumber(const std::string &serialNumber)
Set the serial number.
Definition: IntrinsicBase.hpp:242
aliceVision::camera::IntrinsicBase::unlock
void unlock()
Unlock the intrinsic.
Definition: IntrinsicBase.hpp:212
aliceVision::camera::IntrinsicBase::backProjectUnit
Vec3 backProjectUnit(const Vec2 &pt2D) const
Back-projection of a 2D point on a unitsphere.
Definition: IntrinsicBase.cpp:30
aliceVision::camera::IntrinsicBase::getDerivativeBackProjectUnitWrtParams
virtual Eigen::Matrix< double, 3, Eigen::Dynamic > getDerivativeBackProjectUnitWrtParams(const Vec2 &pt2D) const =0
Get the derivative of the unit sphere backprojection.
aliceVision::clamp
T clamp(const T &val, const T &min, const T &max)
Clamp return the number if inside range, else min or max range.
Definition: numeric.hpp:140
aliceVision::camera::IntrinsicBase::getUndistortedPixel
virtual Vec2 getUndistortedPixel(const Vec2 &p) const =0
Return the undistorted pixel (with removed distortion)
aliceVision::camera::IntrinsicBase::setSensorWidth
void setSensorWidth(double width)
Set the intrinsic sensor width.
Definition: IntrinsicBase.hpp:230
aliceVision::camera::IntrinsicBase::imagePlaneToCameraPlaneError
virtual double imagePlaneToCameraPlaneError(double value) const =0
Normalize a given unit pixel error to the camera plane.
aliceVision::camera::IntrinsicBase::isVisibleRay
virtual bool isVisibleRay(const Vec3 &ray) const =0
Return true if this ray should be visible in the image.
aliceVision::camera::IntrinsicBase
Basis class for all intrinsic parameters of a camera.
Definition: IntrinsicBase.hpp:27
aliceVision::camera::IntrinsicBase::project
virtual Vec2 project(const Vec4 &pt3D, bool applyDistortion=true) const =0
Projection of a 3D point into the camera plane (Apply disto (if any) and Intrinsics)
aliceVision::camera::IntrinsicBase::getType
virtual EINTRINSIC getType() const =0
Get embed camera type.
aliceVision::camera::IntrinsicBase::pixelProbability
virtual double pixelProbability() const =0
What is the probability of a pixel wrt the whole fov.
aliceVision::camera::IntrinsicBase::rescale
virtual void rescale(float factorW, float factorH)
Rescale intrinsics to reflect a rescale of the camera image.
Definition: IntrinsicBase.cpp:106
aliceVision::camera::IntrinsicBase::getDistortedPixel
virtual Vec2 getDistortedPixel(const Vec2 &p) const =0
Return the distorted pixel (with added distortion)
aliceVision::camera::IntrinsicBase::getTypeStr
std::string getTypeStr() const
Get the string describing the intrinsic type.
Definition: IntrinsicBase.hpp:273
aliceVision::camera::IntrinsicBase::residual
Vec2 residual(const geometry::Pose3 &pose, const Vec4 &X, const Vec2 &x, bool applyDistortion=true) const
Compute the residual between the 3D projected point X and an image observation x.
Definition: IntrinsicBase.hpp:177
aliceVision::camera::IntrinsicBase::ima2cam
virtual Vec2 ima2cam(const Vec2 &p) const =0
Transform a point from the image plane to the camera plane.
aliceVision::camera::IntrinsicBase::setInitializationMode
void setInitializationMode(EInitMode initializationMode)
Set the intrinsic initialization mode.
Definition: IntrinsicBase.hpp:248
aliceVision::camera::IntrinsicBase::hasDistortion
virtual bool hasDistortion() const
Camera model handles a distortion field.
Definition: IntrinsicBase.hpp:320
aliceVision::camera::IntrinsicBase::setHeight
void setHeight(unsigned int height)
Set the intrinsic image height.
Definition: IntrinsicBase.hpp:224
aliceVision::camera::IntrinsicBase::getDerivativeTransformProjectWrtParams
virtual Eigen::Matrix< double, 2, Eigen::Dynamic > getDerivativeTransformProjectWrtParams(const Eigen::Matrix4d &pos, const Vec4 &pt3D) const =0
Get the derivative of a projection of a 3D point into the camera plane.
aliceVision::camera::IntrinsicBase::removeDistortion
virtual Vec2 removeDistortion(const Vec2 &p) const =0
Remove the distortion to a camera point (that is in normalized camera frame)
aliceVision::geometry::Pose3
Definition: Pose3.hpp:18
aliceVision::camera::IntrinsicBase::_initializationMode
EInitMode _initializationMode
initialization mode
Definition: IntrinsicBase.hpp:481