Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ProjectionParametersZoom.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/ProjectionParametersZoom.hh"
27 
28 
29 using namespace BIAS;
30 using namespace std;
31 
32 
34 ProjectLocal(const Vector3<double>& point, bool IgnoreDistortion) const {
35  // in-plane affine coordinate transformation with KMatrix
36  HomgPoint2D pos;
37  K_.Mult(point, pos);
38  // radial distortion here
39  if (!IgnoreDistortion) Distort(pos);
40  return pos.Homogenize();
41 }
42 
45  bool IgnoreDistortion) const
46 {
47  BIASERR("unfinished\n");
48  BIASABORT;
49  return -1;
50 }
51 
52 
54 UnProjectToImagePlane(const HomgPoint2D& pos, const double& depth,
55  bool IgnoreDistortion) const
56 {
57  Vector3<double> d, p;
58  UnProjectLocal(pos, p, d, IgnoreDistortion);
59  if(Equal(d[2], 0.0))
60  return HomgPoint3D(0,0,0,0);
61  d*=depth/d[2];
62  if(Equal(d.NormL2(), 0.0))
63  return HomgPoint3D(0,0,0,0);
64  HomgPoint3D local(d);
65  return Pose_.LocalToGlobal(local);
66 }
67 
68 
70 UnProjectLocal(const HomgPoint2D& cPos, Vector3<double>& pointOnRay,
71  Vector3<double>& direction, bool IgnoreDistortion) const {
72  HomgPoint2D mpos(cPos); // de-const pos
73  // radial undistortion here
74  if (!IgnoreDistortion) Undistort(mpos);
75  // in-plane affine coordinate transformation with KMatrix
76  invK_.Mult(mpos, direction);
77  direction = direction.GetNormalized();
78  pointOnRay = Vector3<double>(0.0);
79 }
80 
81 
82 
83 int ProjectionParametersZoom::AddZoomStep(double zoom, double focallength,
84  double kc1, double kc2,
85  double kc3, double kc4)
86 {
87  if (knownparams_vect_.size()>0) {
88  if (knownparams_vect_[knownparams_vect_.size()-1].zoom<zoom) {
89  BIASERR("Zoom parameters only in descending order.");
90  return -1;
91  }
92  }
93  CPDiscreteParam dp;
94  dp.zoom = zoom;
95  dp.focallength = focallength;
96  dp.kc1 = kc1;
97  dp.kc2 = kc2;
98  dp.kc3 = kc3;
99  dp.kc4 = kc4;
100  knownparams_vect_.push_back(dp);
101  SetUnzoomed();
102  ComputeK_();
103  return 0;
104 }
105 
106 
108 
109  K_.SetIdentity();
110  K_[0][0] = focallengthZoom_;
111  K_[1][1] = aspectratio_ * focallengthZoom_;
112  K_[0][1] = 0;//skew_;
113  K_[0][2] = principalX_;
114  K_[1][2] = principalY_;
115  invK_ = K_.Invert();
116 
117 }
118 
119 #ifdef BIAS_HAVE_XML2
120 
121 int ProjectionParametersZoom::XMLGetClassName(std::string& TopLevelTag,
122  double& Version) const {
123  TopLevelTag = "ProjectionParametersZoom";
124  Version = 1.0;
125  return 0;
126 }
127 
128 
129 int ProjectionParametersZoom::XMLOut(const xmlNodePtr Node,
130  XMLIO& XMLObject) const {
131  xmlNodePtr theNode;
132  string TopLevelName;
133  double Version;
134  ProjectionParametersBase::XMLGetClassName(TopLevelName, Version);
135  theNode = XMLObject.addChildNode(Node, TopLevelName);
136  XMLObject.addAttribute(theNode, "Version", Version);
137  ProjectionParametersBase::XMLOut(theNode, XMLObject);
138  xmlNodePtr childNode;
139  for (unsigned int i=0; i<knownparams_vect_.size(); i++) {
140  childNode = XMLObject.addChildNode(Node,"ZoomStep");
141  XMLObject.addAttribute(childNode, "Zoom", knownparams_vect_[i].zoom);
142  XMLObject.addAttribute(childNode, "Focallength",
143  knownparams_vect_[i].focallength);
144  XMLObject.addAttribute(childNode, "k1", knownparams_vect_[i].kc1);
145  XMLObject.addAttribute(childNode, "k2", knownparams_vect_[i].kc2);
146  XMLObject.addAttribute(childNode, "p1", knownparams_vect_[i].kc3);
147  XMLObject.addAttribute(childNode, "p2", knownparams_vect_[i].kc4);
148  }
149  return 0;
150 }
151 
152 
153 int ProjectionParametersZoom::XMLIn(const xmlNodePtr Node,
154  XMLIO& XMLObject) {
155  string TopLevelName;
156  double Version;
157  ProjectionParametersBase::XMLGetClassName(TopLevelName, Version);
158 
159  xmlNodePtr childNode;
160  if ((childNode = XMLObject.getChild(Node, TopLevelName))==NULL) {
161  BIASERR("Error in xml, no tag" << TopLevelName);
162  return -1;
163  }
164  if (ProjectionParametersBase::XMLIn(childNode, XMLObject)!=0) return -1;
165  knownparams_vect_.clear();
166  childNode = XMLObject.getFirstChild(Node);
167  while (childNode!=NULL) {
168  string nodename = XMLObject.getNodeName(childNode);
169  if (nodename.compare("ZoomStep")==0) {
170  CPDiscreteParam kpv;
171  kpv.zoom = XMLObject.getAttributeValueDouble(childNode, "Zoom");
172  kpv.focallength =
173  XMLObject.getAttributeValueDouble(childNode, "Focallength");
174  kpv.kc1 = XMLObject.getAttributeValueDouble(childNode, "k1");
175  kpv.kc2 = XMLObject.getAttributeValueDouble(childNode, "k2");
176  kpv.kc3 = XMLObject.getAttributeValueDouble(childNode, "p1");
177  kpv.kc4 = XMLObject.getAttributeValueDouble(childNode, "p2");
178  knownparams_vect_.push_back(kpv);
179  }
180  childNode = XMLObject.getNextChild(childNode);
181  }
182  SetUnzoomed();
183  return 0;
184 }
185 
186 #endif
187 
188 
190  double relnorm){
191  //todo: brown: adequate methode finden (lin. interp. ist
192  //schlechter)
193 
194  kc1Zoom_=relnorm*(knownparams_vect_[i].kc1-knownparams_vect_[i-1].kc1)+
195  knownparams_vect_[i-1].kc1;
196 
197  kc2Zoom_=relnorm*(knownparams_vect_[i].kc2-knownparams_vect_[i-1].kc2)+
198  knownparams_vect_[i-1].kc2;
199 
200  kc3Zoom_=relnorm*(knownparams_vect_[i].kc3-knownparams_vect_[i-1].kc3)+
201  knownparams_vect_[i-1].kc3;
202 
203  kc4Zoom_=relnorm*(knownparams_vect_[i].kc4-knownparams_vect_[i-1].kc4)+
204  knownparams_vect_[i-1].kc4;
205 
206 }
207 
208 
210 
211  double relnorm;
212  double absdist;
213 
214  bool found;
215  unsigned int i;
216  found=false;
217 
218  if (knownparams_vect_[0].zoom<zoom_){ // zoom is higher than the
219  // known values:
220  zoom_=knownparams_vect_[0].zoom; // set to highest available
221  }
222 
223  for (i=0;i<knownparams_vect_.size();i++){
224  if (knownparams_vect_[i].zoom<=zoom_){
225  found=true;
226  break;
227  }
228  }
229 
230  if (!found){ // zoom is lower than the known values
231  focallengthZoom_=knownparams_vect_[i-1].focallength;
232  return knownparams_vect_[i-1].focallength;
233  }
234 
235  if (knownparams_vect_[i].zoom==zoom_){
236  // interpolate distortion parameters
237  InterpolateDistortionFromIndex_(i+1,0);
238  return knownparams_vect_[i].focallength;
239  } else {
240  relnorm=(zoom_ - knownparams_vect_[i].zoom) /
241  (knownparams_vect_[i-1].zoom - knownparams_vect_[i].zoom);
242  relnorm=1.0-relnorm;
243  // interpolate distortion parameters
244  InterpolateDistortionFromIndex_(i,relnorm);
245  absdist=relnorm*(knownparams_vect_[i].focallength-
246  knownparams_vect_[i-1].focallength);
247  return (absdist+knownparams_vect_[i-1].focallength);
248  }
249 }
250 
251 
253 
254  // do nothing in case of ideal lense
255  if (kc1Zoom_==0 && kc2Zoom_==0 && kc3Zoom_==0 && kc4Zoom_==0) return true;
256 
257  // copy of distorted point
258  double distx,disty;
259  double x,y;
260  double twoxy;
261 
262  double rsquared;
263  double raddist;
264  double tandistx, tandisty;
265 
266  point2d.Homogenize();
267 
268  // Points must be Bougouet-normalized
269  // (subtract principal point, then divide by focal length)
270  x = (point2d[0]-principalX_)/focallengthZoom_;
271  y = (point2d[1]-principalY_)/(GetAspectratio()*focallengthZoom_);
272 
273  twoxy = 2 * x*y;
274  rsquared = x*x + y*y;
275 
276  // radial distortion:
277  raddist = 1 + kc1Zoom_*rsquared + kc2Zoom_*rsquared*rsquared;
278  // tangential distortion:
279  tandistx = kc3Zoom_*twoxy + kc4Zoom_ * (rsquared + 2*x*x);
280  tandisty = kc4Zoom_*twoxy + kc3Zoom_ * (rsquared + 2*y*y);
281 
282  // apply distortion:
283  distx = raddist * x + tandistx;
284  disty = raddist * y + tandisty;
285 
286  // invert Bougouet-normalization
287  point2d[0] = distx*focallengthZoom_ + principalX_;
288  point2d[1] = disty*GetAspectratio()*focallengthZoom_ + principalY_;
289  return true;
290 }
291 
292 
294 
295  // do nothing in case of ideal lense
296  if (kc1Zoom_==0 && kc2Zoom_==0 && kc3Zoom_==0 && kc4Zoom_==0) return true;
297 
298 // copy of distorted point
299  double distx,disty;
300  double x,y;
301  double twoxy;
302 
303  double rsquared;
304  double raddist;
305  double tandistx, tandisty;
306 
307  point2d.Homogenize();
308 
309  // Points must be Bougouet-normalized
310  // (subtract principal point, then divide by focal length)
311  x = point2d[0] = (point2d[0]-principalX_)/focallengthZoom_;
312  y = point2d[1] = (point2d[1]-principalY_)/(GetAspectratio()*
313  focallengthZoom_);
314 
315  // 5 iterations are enough
316  for (unsigned int i=0;i<5;i++){
317 
318  twoxy = 2 * x*y;
319  rsquared = x*x + y*y;
320 
321  // radial distortion:
322  raddist = 1 + kc1Zoom_*rsquared + kc2Zoom_*rsquared*rsquared;
323  // tangential distortion:
324  tandistx = kc3Zoom_*twoxy + kc4Zoom_ * (rsquared + 2*x*x);
325  tandisty = kc4Zoom_*twoxy + kc3Zoom_ * (rsquared + 2*y*y);
326 
327  // apply distortion:
328  distx = raddist * x + tandistx;
329  disty = raddist * y + tandisty;
330 
331  // subtract distortion from distorted coordinates
332  x = point2d[0] - (distx-x);
333  y = point2d[1] - (disty-y);
334 
335  }
336 
337  // invert Bougouet-normalization
338  point2d[0] = x*focallengthZoom_ + principalX_;
339  point2d[1] = y*GetAspectratio()*focallengthZoom_ + principalY_;
340  return true;
341 }
342 
343 
345 
346  double relnorm;
347  double absdist;
348 
349  bool found;
350  unsigned int i;
351  found=false;
352 
353  if (knownparams_vect_[0].focallength<focallengthZoom_){
354  focallengthZoom_=knownparams_vect_[0].focallength;
355  }
356 
357  for (i=0;i<knownparams_vect_.size();i++){
358  if (knownparams_vect_[i].focallength<=focallengthZoom_){
359  found=true;
360  break;
361  }
362  }
363  if (!found){
364  return -1;
365  }
366 
367  if (knownparams_vect_[i].focallength==focallengthZoom_){
368  // interpolate distortion parameters
369  InterpolateDistortionFromIndex_(i+1,0);
370  return knownparams_vect_[i].zoom;
371  } else {
372  relnorm=(focallengthZoom_ - knownparams_vect_[i].focallength) /
373  (knownparams_vect_[i-1].focallength - knownparams_vect_[i].focallength);
374  relnorm=1.0-relnorm;
375  // interpolate distortion parameters
376  InterpolateDistortionFromIndex_(i,relnorm);
377  absdist=relnorm*(knownparams_vect_[i].zoom-
378  knownparams_vect_[i-1].zoom);
379  return (absdist+knownparams_vect_[i-1].zoom);
380  }
381 }
virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject)
specialization of XML read function
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
Definition: XMLIO.cpp:156
xmlNodePtr getNextChild()
Get the next child of the parent specified in the last getFirstChild() call, the class remembers the ...
Definition: XMLIO.cpp:466
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
Specialization of XML write function.
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.
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 bool Undistort(BIAS::HomgPoint2D &point2d) const
Using the Matlab camera calibration toolbox parameters for an undistortion of distorted coordinates...
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
Definition: HomgPoint2D.hh:215
virtual HomgPoint2D ProjectLocal(const Vector3< double > &point, bool IgnoreDistortion=false) const
calculates the projection of a point in the camera coordinate system to a pixel in the image plane of...
BIAS::Vector3< T > GetNormalized() const
return a normalized vector of this
Definition: Vector3.cpp:47
virtual int XMLGetClassName(std::string &TopLevelTag, double &Version) const
specialization of XML block name function
virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject)
Specialization of XML read function.
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
void Mult(const T &scalar, Vector3< T > &dest) const
Definition: Vector3.hh:332
void InterpolateDistortionFromIndex_(unsigned int i, double relnorm)
xmlNodePtr getFirstChild(const xmlNodePtr ParentNode)
Get the first child of a given parent, or NULL for no childs.
Definition: XMLIO.cpp:452
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
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_...
double getAttributeValueDouble(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:736
virtual bool Distort(BIAS::HomgPoint2D &point2d) const
Using the Matlab camera calibration toolbox parameters for a distortion of undistorted coordinates...
std::string getNodeName(const xmlNodePtr Node) const
Get the name of a given Node.
Definition: XMLIO.cpp:543
int AddZoomStep(double zoom, double focallength, double kc1, double kc2, double kc3, double kc4)
virtual int XMLGetClassName(std::string &TopLevelTag, double &Version) const
Specialization of XML block name function.
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
specialization of XML write function
void ComputeK_()
computes the cached KMatrix and its inverse call after every parameter change
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
class BIASGeometryBase_EXPORT HomgPoint3D
virtual void UnProjectLocal(const HomgPoint2D &pos, Vector3< double > &pointOnRay, Vector3< double > &direction, bool IgnoreDistortion=false) const
calculates the viewing ray from the camera center (in the camera coordinate system) which belongs to ...