Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ProjectionParametersBufferedRay.cpp
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 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #include "Geometry/ProjectionParametersBufferedRay.hh"
27 #include <Base/Common/CompareFloatingPoint.hh>
28 #include <Geometry/ProjectionParametersFactory.hh>
29 #include <MathAlgo/PolynomialSolve.hh>
30 #include <MathAlgo/Minpack.hh>
31 
32 using namespace BIAS;
33 using namespace std;
34 
38 {
39  if (ppb)
40  ppb_ = ppb->Clone();
41  else
42  ppb_ = NULL;
43  unprojectMappingIgnoreDistortion_ = NULL;
44  unprojectMappingDistortion_ = NULL;
45  mask_ = false;
46  if(!UpdateFromProjection_())
47  {
48  BIASERR("ProjectionParameters are NULL");
49  }
50 }
51 
54 {
55  *this = ppbr;
56  if (ppbr.ppb_)
57  ppb_ = ppbr.ppb_->Clone();
58  else
59  ppb_ = NULL;
60  unprojectMappingIgnoreDistortion_ = NULL;
61  unprojectMappingDistortion_ = NULL;
62  mask_ = ppbr.mask_;
63  if(!UpdateProjection_())
64  {
65  BIASERR("ProjectionParameters are NULL");
66  }
67 }
68 
70 {
71  return ppb_->Distort(point2d);
72 }
73 
74 
76 {
77  return ppb_->Undistort(point2d);
78 }
79 
82 {
83  return ppb_->DoIntrinsicsDiffer(ppb_);
84 }
85 
87 ProjectLocal(const Vector3<double>& point, bool IgnoreDistortion) const
88 {
89  return ppb_->ProjectLocal(point, IgnoreDistortion);
90 }
91 
92 
95  bool IgnoreDistortion) const
96 {
97  return ppb_->ProjectLocal(point, p2d, IgnoreDistortion);
98 }
99 
101 UnProjectToImagePlane(const HomgPoint2D& pos, const double& depth,
102  bool IgnoreDistortion) const
103 {
104  return ppb_->UnProjectToImagePlane(pos, depth, IgnoreDistortion);
105 }
106 
109  Vector3<double>& direction, bool IgnoreDistortion) const
110 {
111 #ifdef BIAS_DEBUG
112  if(pos[0] < 0.0)
113  BIASERR("negative index: "<<pos[0]);
114  if(pos[1] < 0.0)
115  BIASERR("negative index: "<<pos[1]);
116  if((int)(pos[0]+0.5) >= (int)width_)
117  BIASERR("index out of bound: "<<(int)(pos[0]+0.5));
118  if((int)(pos[1]+0.5) >= (int)height_)
119  BIASERR("index out of bound: "<<(int)(pos[1]+0.5));
120 #endif
121  if(IgnoreDistortion)
122  {
123  direction = unprojectMappingIgnoreDistortion_[(int)(pos[0]+0.5)+
124  ((int)(pos[1]+0.5))*width_];
125  }
126  else
127  {
128  direction = unprojectMappingDistortion_[(int)(pos[0]+0.5)+((int)(pos[1]+0.5))*width_];
129  }
130  origin = Vector3<double>(0.0);
131 }
132 
134 UnProjectToPointLocal(const HomgPoint2D& pos, const double& depth,
135  bool IgnoreDistortion) const
136 {
137  Vector3<double> x, p;
138  UnProjectLocal(pos, p, x, IgnoreDistortion);
139  x *= depth;
140  return x;
141 }
142 
143 #ifdef BIAS_HAVE_XML2
144 
146 XMLGetClassName(std::string& TopLevelTag, double& Version) const
147 {
148  TopLevelTag = "ProjectionParametersBufferedRay";
149  Version = 0.1;
150  return 0;
151 }
152 
154 XMLOut(const xmlNodePtr Node, XMLIO& XMLObject) const
155 {
156  xmlNodePtr theNode;
157  string TopLevelName;
158  double Version;
159  ProjectionParametersBase::XMLGetClassName(TopLevelName, Version);
160  theNode = XMLObject.addChildNode(Node, TopLevelName);
161  XMLObject.addAttribute(theNode, "Version", Version);
162  ProjectionParametersBase::XMLOut(theNode, XMLObject);
163 
164  // Add node for wrapped projection parameters
165  xmlNodePtr childNode = XMLObject.addChildNode(Node, "WrappedProjection");
166  if (ppb_) {
167  ppb_->XMLGetClassName(TopLevelName, Version);
168  theNode = XMLObject.addChildNode(childNode, TopLevelName);
169  XMLObject.addAttribute(theNode, "Version", Version);
170  ppb_->XMLOut(theNode, XMLObject);
171  }
172 
173  XMLObject.addAttribute(Node, "Mask", mask_);
174 
175  return 0;
176 }
177 
179 XMLIn(const xmlNodePtr Node, XMLIO& XMLObject)
180 {
181  string TopLevelName;
182  double Version;
183  ProjectionParametersBase::XMLGetClassName(TopLevelName, Version);
184 
185  xmlNodePtr childNode = XMLObject.getChild(Node, TopLevelName);
186  if (!childNode) {
187  BIASERR("Error in XML, tag " << TopLevelName << " not found!");
188  return -1;
189  }
190  if (ProjectionParametersBase::XMLIn(childNode, XMLObject) != 0) return -1;
191 
192  // Read wrapped projection parameters
193  if (ppb_) delete ppb_;
194  childNode = XMLObject.getChild(Node, "WrappedProjection");
195  if (childNode) {
196  childNode = XMLObject.getFirstChild(childNode);
197  if (childNode) {
199  string nodename = XMLObject.getNodeName(childNode);
200  ppb_ = factory.Create(nodename);
201  if (ppb_->XMLIn(childNode, XMLObject) != 0) return -1;
202  }
203  }
204 
205  mask_ = XMLObject.getAttributeValueBool(Node, "Mask");
206 
207  // Update wrapped projection parameters
208  if(!UpdateProjection_())
209  {
210  BIASERR("ProjectionParameters are NULL");
211  }
212 
213  return 0;
214 }
215 
216 #endif //BIAS_HAVE_XML2
217 
218 const bool ProjectionParametersBufferedRay::UpdateProjection_()
219 {
220  if (ppb_ == NULL) return false;
221  ppb_->SetImageSize(width_, height_);
224  if (CValid_ && QValid_) {
225  ppb_->SetQC(GetQ(), GetC());
226  } else if (CValid_) {
227  ppb_->SetQ(GetQ());
228  ppb_->InvalidatePose();
229  ppb_->SetC(GetC());
230  } else if (QValid_) {
231  ppb_->SetC(GetC());
232  ppb_->InvalidatePose();
233  ppb_->SetQ(GetQ());
234  } else {
235  ppb_->SetQC(GetQ(), GetC());
236  ppb_->InvalidatePose();
237  }
238  ppb_->SetCov(GetCov());
239  ppb_->SetIdentifier(identifier_);
240  //ppb_->ustIgnoreDistortion_ = ustIgnoreDistortion_;
241  //ppb_->ustNormalize_ = ustNormalize_;
242  //ppb_->ustTransformIntoImage_ = ustTransformIntoImage_;
243 
244  return UpdateBuffer_();
245 }
246 
247 const bool ProjectionParametersBufferedRay::UpdateFromProjection_()
248 {
249  if (ppb_ == NULL) return false;
250  unsigned int w, h;
251  double px, py;
252  ppb_->GetImageSize(w, h);
253  ppb_->GetPrincipal(px, py);
254  SetImageSize(w, h);
255  SetPrincipal(px, py);
257  SetPose(ppb_->GetPose());
258  if (!ppb_->PoseValid()) InvalidatePose();
259  SetIdentifier(ppb_->GetIdentifier());
260  //ustIgnoreDistortion_ = ppb_->ustIgnoreDistortion_;
261  //ustNormalize_ = ppb_->ustNormalize_;
262  //ustTransformIntoImage_ = ppb_->ustTransformIntoImage_;
263 
264  return UpdateBuffer_();
265 }
266 
267 const bool ProjectionParametersBufferedRay::UpdateBuffer_()
268 {
269  if (ppb_ == NULL) return false;
270  Vector3<double> tmp;
271  const double halfX = width_/2.0, halfY = height_/2.0;
272  const BIAS::Vector3<double> zero(0.0, 0.0, 0.0);
273  double rx, ry, r;
274  if (unprojectMappingIgnoreDistortion_)
275  delete[] unprojectMappingIgnoreDistortion_;
276  if (unprojectMappingDistortion_)
277  delete[] unprojectMappingDistortion_;
278  unprojectMappingIgnoreDistortion_ = new Vector3<double>[width_*height_];
279  unprojectMappingDistortion_ = new Vector3<double>[width_*height_];
280  for (unsigned int y = 0; y < height_; y++)
281  {
282  for (unsigned int x = 0; x < width_; x++)
283  {
284  if(mask_)
285  {
286  rx = (x-halfX)/halfX;
287  ry = (y-halfY)/halfY;
288  r = sqrt(rx*rx+ry*ry);
289  }
290  else
291  {
292  r = 0.5;
293  }
294  if (r <= 1.0)
295  {
296  Vector3<double> p;
297  ppb_->UnProjectLocal(HomgPoint2D(x,y), p, tmp, true);
298  BIASASSERT(fabs(tmp.Length() - 1.0) <= std::numeric_limits<double>::epsilon() ||
299  fabs(tmp.Length()) <= std::numeric_limits<double>::epsilon())
300  unprojectMappingIgnoreDistortion_[x+y*width_] = tmp;
301  ppb_->UnProjectLocal(HomgPoint2D(x,y), p, tmp, false);
302  BIASASSERT(fabs(tmp.Length() - 1.0) <= std::numeric_limits<double>::epsilon() ||
303  fabs(tmp.Length()) <= std::numeric_limits<double>::epsilon())
304  unprojectMappingDistortion_[x+y*width_] = tmp;
305  }
306  else
307  {
308  unprojectMappingIgnoreDistortion_[x+y*width_] = zero;
309  unprojectMappingDistortion_[x+y*width_] = zero;
310  }
311  }
312  }
313  return true;
314 }
virtual BIAS::Vector3< double > GetC() const
Get projection center.
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
Definition: XMLIO.cpp:156
virtual void SetCov(const Matrix< POSE_TYPE > &Cov)
Set pose covariance matrix with respect to C, Q.
This class maps image coords to rays which are buffered for fast lookup.
virtual void SetPrincipal(const double x, const double y)
Set principal point (in pixels relative to top left corner).
virtual HomgPoint2D ProjectLocal(const Vector3< double > &point, bool IgnoreDistortion=false) const =0
calculates the projection of a point in the local camera coordinate system to a pixel in the image pl...
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
virtual int XMLGetClassName(std::string &TopLevelTag, double &Version) const
specialization of XML block name function
double Length() const
returns the Euclidean Length of the Vector
Definition: Vector3.hh:193
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
Specialization of XML write function.
ProjectionParametersBase * Create(const std::string &className)
Creates a projection parameters object by a class name.
virtual int GetPrincipal(double &PrincipalX, double &PrincipalY) const
Get principal point (in pixels relative to top left corner).
virtual void SetIdentifier(std::string name)
Set the identification string.
virtual BIAS::Matrix< POSE_TYPE > GetCov() const
Return pose covariance as 7x7 matrix with respect to C, Q.
xmlNodePtr getChild(const xmlNodePtr ParentNode, const std::string &ChildName)
Get a child of a Parent node by specifying the childs name, NULL is returned if the ParentNode has no...
Definition: XMLIO.cpp:489
virtual void SetImageSize(const unsigned int w, const unsigned int h)
Set image dimensions (in pixels).
virtual ProjectionParametersBase * Clone() const =0
Covariant virtual copy constructor used in BIAS::Projection.
virtual std::string GetIdentifier() const
virtual const bool DoIntrinsicsDiffer(const ProjectionParametersBase *p) const
virtual const bool DoIntrinsicsDiffer(const ProjectionParametersBase *p) const
ProjectionParametersBufferedRay(const ProjectionParametersBase *ppb)
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
specialization of XML write function
bool getAttributeValueBool(const xmlAttrPtr Attribute) const
Get the value of a given Attribute, with type-cast overloads for different attribute types...
Definition: XMLIO.cpp:700
virtual bool Distort(BIAS::HomgPoint2D &point2d) const
Interface defintion for lens distortion function, implemented by derived classes. ...
virtual HomgPoint3D UnProjectToImagePlane(const HomgPoint2D &pos, const double &depth=1.0, bool IgnoreDistortion=false) const
map points from image onto unit diameter image plane in 3D.
virtual bool Distort(BIAS::HomgPoint2D &point2d) const =0
Interface defintion for lens distortion function, implemented by derived classes. ...
virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject)
Specialization of XML read function.
virtual HomgPoint2D ProjectLocal(const Vector3< double > &point, bool IgnoreDistortion=false) const
calculates the projection of a point in the local camera coordinate system to a pixel in the image pl...
virtual void SetPose(const BIAS::Pose pose)
Set pose from pose object.
std::string identifier_
Multifunctional identifier.
virtual void SetQ(const BIAS::Quaternion< double > &Q)
Set orientation from unit quaternion Q.
Wrapper class for reading and writing XML files based on the XML library libxml2. ...
Definition: XMLIO.hh:72
xmlNodePtr addChildNode(const xmlNodePtr ParentNode, const std::string &NewNodeName)
Add a child node to an incoming node with the given name.
Definition: XMLIO.cpp:131
virtual bool PoseValid() const
Check if current pose is valid.
virtual double GetAspectratio() const
Return aspectratio (i.e.
unsigned int height_
height of image in pixels
xmlNodePtr getFirstChild(const xmlNodePtr ParentNode)
Get the first child of a given parent, or NULL for no childs.
Definition: XMLIO.cpp:452
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &origin, Vector3< double > &direction, bool ignoreDistortion=false) const =0
Calculates the view ray, which belongs to the given position on the image plane, in local coordinates...
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
virtual int GetImageSize(unsigned int &Width, unsigned int &Height) const
Obtain image dimensions.
virtual bool Undistort(BIAS::HomgPoint2D &point2d) const
Interface defintion for lens undistortion function, implemented by derived classes.
unsigned int width_
width of image in pixels
std::string getNodeName(const xmlNodePtr Node) const
Get the name of a given Node.
Definition: XMLIO.cpp:543
double principalX_
principal point in pixel coordinates (one for all zoom settings)
double aspectratio_
aspect ratio of the camera CCD
virtual void SetAspectratio(const double AspectRatio)
Set CCD aspect ratio (i.e.
virtual void SetQC(const BIAS::Quaternion< double > &Q, const BIAS::Vector3< double > &C)
Set pose from unit quaternion Q and projection center C.
virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject)
specialization of XML read function
virtual int XMLGetClassName(std::string &TopLevelTag, double &Version) const
Specialization of XML block name function.
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
virtual BIAS::Quaternion< double > GetQ() const
Get orientation as unit quaternion.
virtual const BIAS::Pose & GetPose() const
Return complete pose object.
virtual bool Undistort(BIAS::HomgPoint2D &point2d) const =0
Interface defintion for lens undistortion function, implemented by derived classes.
virtual void SetC(const BIAS::Vector3< double > &C)
Set projection center.
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &origin, Vector3< double > &direction, bool IgnoreDistortion=false) const
Calculates the view ray, which belongs to the given position on the image plane, in local coordinates...
bool QValid_
validity flag for orientation and position
class BIASGeometryBase_EXPORT HomgPoint2D
virtual HomgPoint3D UnProjectToImagePlane(const HomgPoint2D &pos, const double &depth=1.0, bool IgnoreDistortion=false) const =0
map points from image onto unit diameter image plane in 3D.
virtual Vector3< double > UnProjectToPointLocal(const HomgPoint2D &pos, const double &depth, bool IgnoreDistortion=false) const
calculates a 3D point in the local camera coordinate system, which belongs to the image position pos ...
virtual void InvalidatePose()
Invalidate currently set pose.