Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ProjectionParametersCylindric.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 BIAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
13 
14 BIAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18 
19 You should have received a copy of the GNU Lesser General Public License
20 along with BIAS; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23 
24 
25 #ifndef __BIAS_ProjectionParametersCylindric_hh__
26 #define __BIAS_ProjectionParametersCylindric_hh__
27 
28 #include <bias_config.h>
29 
30 #include <math.h>
31 
32 #include <Base/Common/BIASpragmaStart.hh>
33 
34 #include <Geometry/ProjectionParametersBase.hh>
35 
36 
37 namespace BIAS {
38 
39  /** @class ProjectionParametersCylindric
40  * @ingroup g_geometry
41  @brief Camera parameters which define the mapping between rays in the
42  camera coordinate system and pixels in the image as well as external
43  pose. This projection can be thought of as a projection onto an
44  image located at the hull of a virtual cylinder around the camera
45  center. The following image shows the optical axis (z,blue) of the
46  camera being orthogonal to the cylinder axis.
47  \image html "cylinder.png"
48  The axis of the virtual cylinder can be set parallel or
49  orthogonal to the camera viewing direction modeling different
50  types of cylinder cameras.
51  Optionally, the virtual cylinder axis can be rotated arbitrarily,
52  and an offset of the cylinder origin with respect to the local
53  camera coordinate system can be given. Projection becomes computationally
54  expensive in this case since the intersection of viewing
55  rays with the cylinder hull must be computed explicitly here.
56  Note that the radius of the virtual cylinder is fixed as 1.
57  @note Here, x/phi are the horizontal/vertical coordinates in the cylinder
58  hull image. This x is NOT directly related to the x-axis of the
59  camera coordinate system!
60 
61  @author bartczak/esquivel
62  */
63  class BIASGeometry_EXPORT ProjectionParametersCylindric:
64 
66 
67  public:
68 
69  /** @brief Enumeration of typical directions of the cylinder axis, i.e.
70  orthogonal (standard) or parallel to camera's viewing direction. */
71  enum ProjectionCylinderAxisEnum { AXIS_ORTHOGONAL = 0, AXIS_PARALLEL };
72 
73  /**
74  * Note: Angles are given in radians
75  */
76  ProjectionParametersCylindric(const double xMin, const double xMax,
77  const double phiMin, const double phiMax,
78  const unsigned int width,
79  const unsigned int height)
80  : ProjectionParametersBase(width, height)
81  {
82  phiMin_ = phiMin;
83  phiMax_ = phiMax;
84  xMin_ = xMin;
85  xMax_ = xMax;
86  //SetQ(Quaternion<double>(0, 0, 0, 1));
87  //SetC(Vector3<double>(0.0, 0.0, 0.0));
88  SetCylinderType(AXIS_ORTHOGONAL);
89  UseAxisOffset_ = false;
90  SetCylinderOffset(Vector3<double>(0.0));
91  UpdateQuasiK_();
92  };
93 
94 
95 
96  ProjectionParametersCylindric(const unsigned int width = 0,
97  const unsigned int height = 0)
98  : ProjectionParametersBase(width, height)
99  {
100  phiMin_ = 0.0;
101  phiMax_ = 2.0*M_PI;
102  xMin_ = 0.0;
103  xMax_ = 1.0;
104  focallengthPhi_ = 1.0;
105  focallengthX_ = 1.0;
106  //SetQ(Quaternion<double>(0, 0, 0, 1));
107  //SetC(Vector3<double>(0.0, 0.0, 0.0));
108  SetCylinderType(AXIS_ORTHOGONAL);
109  UseAxisOffset_ = false;
110  SetCylinderOffset(Vector3<double>(0.0));
111  };
112 
113  void SetParameters(const double xMin, const double xMax,
114  const double phiMin, const double phiMax,
115  const unsigned int width,
116  const unsigned int height){
117  phiMin_ = phiMin;
118  phiMax_ = phiMax;
119  xMin_ = xMin;
120  xMax_ = xMax;
121  width_ = width;
122  height_ = height;
123  UpdateQuasiK_();
124  }
125 
127  *this = P;
128  };
129 
132  phiMin_ = P.phiMin_;
133  phiMax_ = P.phiMax_;
134  xMin_ = P.xMin_;
135  xMax_ = P.xMax_;
136  focallengthPhi_ = P.focallengthPhi_;
137  focallengthX_ = P.focallengthX_;
138  AxisRotation_ = P.AxisRotation_;
139  AxisOffset_ = P.AxisOffset_;
140  AxisRotationInv_= P.AxisRotationInv_;
141  AxisOffsetInv_ = P.AxisOffsetInv_;
142  UseAxisOffset_ = P.UseAxisOffset_;
143  return *this;
144  };
145 
147 
148  virtual const bool DoIntrinsicsDiffer(const ProjectionParametersBase *p) const;
149 
150  bool DoesPointProjectIntoImageLocal(const BIAS::Vector3<double> &localP,
151  HomgPoint2D &p,
152  bool IgnoreDistortion = false) const;
153 
154  /** @brief calculates the projection of a point
155  in the camera coordinate system
156  to a pixel in the image plane of the camera
157 
158  In the simplest case perspective pinhole projection x = K * y
159  where y is the projection of X using y = (R^T | -R^T C) X
160  */
161  virtual HomgPoint2D ProjectLocal(const Vector3<double> &point,
162  bool IgnoreDistortion = false) const;
163 
164  /** @brief calculates the projection of a point in the local camera
165  coordinate system to a pixel in the image plane of the camera. The
166  only case when this function may not compute the 2d point is when the
167  camera center and the 3d point coincide. This case must be indicated
168  by a negative return value. In all other cases, a 2d point must be
169  computed, *particularily* when the 3d point is behind the camera
170  or when the resulting 2d point is at infinity.
171 
172  In the simplest case perspective pinhole projection x = K * point
173  where point is transformed of X using point = (R^T | -R^T C) X
174  @author woelk 08/2008 (c) www.vision-n.de */
175  virtual int ProjectLocal(const Vector3<double>& point, HomgPoint2D &p2d,
176  bool IgnoreDistortion = false) const;
177 
178  /** @brief map points from image onto unit diameter image plane in 3D.
179  * Chosen is the cylindric image plane with radius of one from the
180  * image center.
181  */
182  HomgPoint3D UnProjectToImagePlane(const HomgPoint2D& pos,
183  const double& depth = 1.0,
184  bool IgnoreDistortion = false) const;
185 
186 
187  virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3<double>& pointOnRay,
188  Vector3<double>& direction,
189  bool IgnoreDistortion = false) const;
190 
191  /** @brief covariant virtual copy constructor for use in Projection */
193  return new ProjectionParametersCylindric(*this);
194  };
195 
196  //virtual double ViewDifference(const ProjectionParametersBase* pPPB) const;
197 
198  /** @brief Calculates a 3D point in a local camera coordinate system
199  specified by camSystem, which belongs to the image position pos in
200  cam with distance depth to the camera center cam. Overload to have
201  have return value (0,0,0) for undefined or out of image radius pixels.
202  @author streckel */
203  virtual Vector3<double> UnProjectToPointLocal(const HomgPoint2D &pos,
204  const double &depth,
205  bool IgnoreDistortion = false) const;
206 
207  /** @brief Calculates the 3D point on the cylinder hull local to the camera which
208  belongs to the image position pos. We assume that the image points
209  describe the surface of a cylinder stretched around the camera center.
210  @author esquivel */
211  virtual Vector3<double> UnProjectToCylinderPoint(const HomgPoint2D &pos,
212  bool IgnoreDistortion = false) const;
213 
214  virtual bool Distort(BIAS::HomgPoint2D& point2d) const;
215 
216  virtual bool Undistort(BIAS::HomgPoint2D& point2d) const;
217 
218 
219  /** @brief Calculates difference of cylinder centers weighted with
220  orientation angle up to now.
221  @author esquivel */
222  virtual double ViewDifference(const ProjectionParametersBase* pPPB) const;
223 
224 #ifdef BIAS_HAVE_XML2
225  /** @brief specialization of XML block name function */
226  virtual int XMLGetClassName(std::string &TopLevelTag,
227  double &Version) const;
228 
229  /** @brief specialization of XML write function */
230  virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const;
231 
232  /** @brief specialization of XML read function */
233  virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject);
234 #endif
235 
236  inline double GetFocallengthX() { return focallengthX_; };
237 
238  inline double GetFocallengthPhi() { return focallengthPhi_; };
239 
240  void SetCylinderRotation(const Vector3<double> &rotAxis, double rotAngle,
241  const ProjectionCylinderAxisEnum axisType = AXIS_ORTHOGONAL);
242 
243  void SetCylinderRotation(const Quaternion<double> &rotation,
244  const ProjectionCylinderAxisEnum axisType = AXIS_ORTHOGONAL);
245 
246  void SetCylinderType(const ProjectionCylinderAxisEnum axisType);
247 
248  void SetCylinderOffset(const Vector3<double> &offset);
249 
250  virtual void Rescale(double ratio, const double offset = 0.0){
251  // make sure *this is consistent
252  BIASASSERT(Equal(focallengthX_, double(width_)/(xMax_-xMin_)));
253  BIASASSERT(Equal(principalX_, (-1.0)*xMin_*focallengthX_));
254  BIASASSERT(Equal(focallengthPhi_, double(height_)/(phiMax_-phiMin_)));
255  BIASASSERT(Equal(principalY_, (-1.0)*phiMin_*focallengthPhi_));
256  ProjectionParametersBase::Rescale(ratio, offset);
257  UpdateQuasiK_();
258  }
259 
260  virtual void Rescale(unsigned int width, unsigned int height){
261  // make sure *this is consistent
262  BIASASSERT(Equal(focallengthX_, double(width_)/(xMax_-xMin_)));
263  BIASASSERT(Equal(principalX_, (-1.0)*xMin_*focallengthX_));
264  BIASASSERT(Equal(focallengthPhi_, double(height_)/(phiMax_-phiMin_)));
265  BIASASSERT(Equal(principalY_, (-1.0)*phiMin_*focallengthPhi_));
266  ProjectionParametersBase::Rescale(width, height);
267  UpdateQuasiK_();
268  }
269 
270 
271 
272 
273  friend std::ostream&
274  operator<<(std::ostream &os, const ProjectionParametersCylindric& p);
275 
276  protected:
277 
278  inline void ProjectToNormalizedCoords_(const Vector3<double> &point,
279  Vector2<double> &xPhi) const {
280  xPhi[0] = point[0];
281  xPhi[1] = atan2(point[1], point[2]);
282  };
283 
284  /**
285  * Description of coordinate range in normalized frame.
286  *
287  *@{
288  */
289  double phiMin_, phiMax_;
290  double xMin_, xMax_;
291 
292  /** @brief uses internal params to calculate normalized coordinate ranges.
293  */
294  void UpdateFromQuasiK_();
295 
296  /** @brief Uses normalized coordinate ranges and image dimensions to
297  calculate internals.
298  */
299  void UpdateQuasiK_();
300 
301  /** @brief quasi K (principle point already contained in base class)
302  */
303  /* ratio between zylinder angle range and samples within this range:
304  focallengthPhi_ = samples/angle range;
305  */
307 
308  /* ratio between zylinder axis range and samples within this range:
309  focallengthPhi_ = samples/angle range;
310  */
312 
313  /** @brief Rotation of cylinder axis */
315 
316  /** @brief Offset for cylinder axis origin (optional) */
319 
320  };
321 
322 
323  ///////// inline code ///////////////////
324 
325  inline std::ostream& operator<<(std::ostream &os,
327  {
328  os << "ProjectionParametersCylindric:" << std::endl;
329  os << "- focallenghtX_ = " << p.focallengthX_ << std::endl;
330  os << "- focallenghtPhi_ = " << p.focallengthPhi_ << std::endl;
331  os << "- principalX_ = " << p.principalX_ << std::endl;
332  os << "- principalY_ = " << p.principalY_ << std::endl;
333  os << "- xMin_ = " << p.xMin_ << std::endl;
334  os << "- xMax_ = " << p.xMax_ << std::endl;
335  os << "- phiMin_ = " << p.phiMin_ << std::endl;
336  os << "- phiMax_ = " << p.phiMax_ << std::endl;
337  os << "- width_ = " << p.width_ << std::endl;
338  os << "- height_ = " << p.height_ << std::endl << std::endl;
339  double angle;
340  Vector3<double> axis;
341  p.AxisRotation_.GetAxisAngle(axis, angle);
342  os << "- cylinder axis adaption rotation axis is "
343  << axis[0] << "," << axis[1] << "," << axis[2]
344  << ", rotation angle is " << 180.0*angle/M_PI << ", offset is "
345  << p.AxisOffset_[0] << "," << p.AxisOffset_[1] << "," << p.AxisOffset_[2]
346  << "." << std::endl;
347  return os;
348  }
349 
350 
351 } // end namespace
352 
353 #include <Base/Common/BIASpragmaEnd.hh>
354 
355 #endif
356 
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
ProjectionParametersCylindric(const unsigned int width=0, const unsigned int height=0)
virtual void Rescale(double ratio, const double offset=0.0)
Adapt internal parameters to resampled image.
void SetParameters(const double xMin, const double xMax, const double phiMin, const double phiMax, const unsigned int width, const unsigned int height)
void ProjectToNormalizedCoords_(const Vector3< double > &point, Vector2< double > &xPhi) const
Vector3< double > AxisOffset_
Offset for cylinder axis origin (optional)
double focallengthPhi_
quasi K (principle point already contained in base class)
int GetAxisAngle(Vector3< QUAT_TYPE > &axis, QUAT_TYPE &angle) const
Returns rotation in axis and angle notation (angle in radians).
ProjectionParametersCylindric & operator=(const ProjectionParametersCylindric &P)
ProjectionParametersCylindric(const double xMin, const double xMax, const double phiMin, const double phiMax, const unsigned int width, const unsigned int height)
Note: Angles are given in radians.
Wrapper class for reading and writing XML files based on the XML library libxml2. ...
Definition: XMLIO.hh:72
Quaternion< double > AxisRotation_
Rotation of cylinder axis.
unsigned int height_
height of image in pixels
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
Definition: Array2D.hh:260
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
unsigned int width_
width of image in pixels
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual void Rescale(unsigned int width, unsigned int height)
adapt internal parameters to new image size
double phiMin_
Description of coordinate range in normalized frame.
double principalX_
principal point in pixel coordinates (one for all zoom settings)
ProjectionParametersCylindric(const ProjectionParametersCylindric &P)
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual void Rescale(double ratio, const double offset=0.0)
Adapt internal parameters to resampled image.
ProjectionCylinderAxisEnum
Enumeration of typical directions of the cylinder axis, i.e.
virtual ProjectionParametersCylindric * Clone() const
covariant virtual copy constructor for use in Projection
virtual ProjectionParametersBase & operator=(const ProjectionParametersBase &p)