Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ProjectionParametersIO.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 #include "Geometry/ProjectionParametersIO.hh"
26 #include <string>
27 #include <Base/Image/ImageAttributes.hh>
28 #include <MathAlgo/Interpolator.hh>
29 #include <fstream>
30 #include <Geometry/RMatrix.hh>
31 #include <Base/Common/FileHandling.hh>
32 
33 
34 using namespace BIAS;
35 using namespace std;
36 
37 
39 
40  cd.CamModel_ = "";
41  cd.CamID_ = 1;
42  cd.LensModel_ = "";
43  cd.LensIsSpherical_ = false;
44  cd.zoomCamera_ =false;
45 
46  cd.width_=cd.height_=0;
47  cd.principalX_ = cd.principalY_ =0;
48  cd.cellSizeX_ = cd.cellSizeY_ = 1;
49  cd.focallengthDef_ = 0;
50  cd.kc1Def_ = cd.kc2Def_ = cd.kc3Def_ = cd.kc4Def_ = 0;
51  cd.knownparams_vect_.clear();
52  cd.IlluCorrX_.clear();
53  cd.IlluCorrY_.clear();
54  cd.AngleCorrX_.clear();
55  cd.AngleCorrY_.clear();
56  cd.acCoeff0_ = cd.acCoeff1_ = cd.acCoeff2_ = cd.acCoeff3_ = cd.acCoeff4_ = 0;
57  cd.MaxCamAngle_ = 0;
58  cd.radius_ = 0;
59 
61  cd.PoseInRigYaw_=0;
62  cd.PoseInRigPitch_=0;
63  cd.PoseInRigRoll_=0;
64 
65 }
67 
69  sd.PoseInRigYaw_=0;
70  sd.PoseInRigPitch_=0;
71  sd.PoseInRigRoll_=0;
72 
73 }
74 
75 int ProjectionParametersIO::ReadFromBBC(const std::string& filename,
76  CameraData& cd,
77  const double& addppx,
78  const double& addppy,
79  const bool silent) {
80  std::ifstream ifs(filename.c_str());
81  return ReadFromBBCStream(ifs, cd, addppx, addppy, silent);
82 }
83 
84 int ProjectionParametersIO::ReadFromEXIF(const std::string& filename,
85  CameraData& cd) {
86 
87  Initialize(cd);
88 
89  ImageAttributes exifdata;
90  exifdata.InitExifTags();
91  int result = exifdata.Read(filename);
92  if (result!=0) return result;
93 
94 
95  string make, model;
96  exifdata.GetHardwareName(make, model);
97  cd.CamModel_ = make + "___"+model;
98 
99  cd.CamID_ = 0;
100  cd.LensModel_ = "unknown";
101  cd.LensIsSpherical_ = false;
102 
103  result = exifdata.GetPixelSizeXMeter(cd.cellSizeX_);
104  if (result<0) return result;
105  result = exifdata.GetPixelSizeYMeter(cd.cellSizeY_);
106  if (result<0) return result;
107 
108  int width=0, height=0;
109  result = exifdata.GetImageDimensions(width, height);
110  if (result<0) return result;
111  cd.width_ = width;
112  cd.height_ = height;
113 
114  cd.aspectratio_ = cd.cellSizeX_ / cd.cellSizeY_;
115 
116  result = exifdata.GetPrincipalPoint(cd.principalX_, cd.principalY_);
117  if (result<0) return result;
118 
119  result = exifdata.GetFocalLengthXPixel(cd.focallengthDef_);
120  if (result<0) return result;
121 
122  cd.zoomCamera_ = false;
123  cd.knownparams_vect_.clear();
124 
125  return 0;
126 }
127 
128 
130  CameraData& cd,
131  const double& addppx,
132  const double& addppy,
133  const bool silent) {
134  Vector3<double> BBCC(0.0), BBCA(0.0), BBCUp(0.0);
135  unsigned int BBCWidth=0, BBCHeight=0;
136  // Pixelsize and FocalLength are in [m] (meter)
137  double BBCPxSizeX=0, BBCPxSizeY=0, BBCCxShift=0,
138  BBCCyShift=0,BBCFocalLength=0,BBCk3=0,BBCk5=0,BBCCircleRadius=0;
139  bool isSpherical = false;
140  string key;
141  int BBCIdent = -1;
142  istringstream iss;
143  char linebuf[201];
144  while (ifs.getline(linebuf,200)) {
145 // cout <<"read line: "<<linebuf<<endl;
146  iss.clear();
147  iss.str(linebuf);
148  iss >> key;
149  if (key == "Ident") iss >> BBCIdent;
150  else if (key == "CVec") iss >> BBCC[0]>> BBCC[1]>> BBCC[2];
151  else if (key == "AVec") iss >> BBCA[0]>> BBCA[1]>> BBCA[2];
152  else if (key == "UpVec") iss >> BBCUp[0]>> BBCUp[1]>> BBCUp[2];
153  else if (key == "Width") iss >> BBCWidth;
154  else if (key == "Height") iss >> BBCHeight;
155  else if (key == "PixelSizeX") iss >> BBCPxSizeX;
156  else if (key == "PixelSizeY") iss >> BBCPxSizeY;
157  else if (key == "CenterPointShiftX") iss >> BBCCxShift;
158  else if (key == "CenterPointShiftY") iss >> BBCCyShift;
159  else if (key == "FocalLength") iss >> BBCFocalLength;
160  else if (key == "RadDistK3") iss >> BBCk3;
161  else if (key == "RadDistK5") iss >> BBCk5;
162  else if (key == "CircleRadius") iss >> BBCCircleRadius;
163  else if (key.find("o_SphericalCamera")!=string::npos) isSpherical = true;
164  if (key == "}") break; // end of entry
165  }
166 
167 #ifdef BIAS_DEBUG
168  if (true){//!silent){
169  if (isSpherical)
170  cout<<"BBC parameters are spherical"<<endl;
171  else
172  cout<<"BBC parameters are perspective"<<endl;
173  cout <<"BBC CVec: "<<BBCC<<endl;
174  cout <<"BBC AVec: "<<BBCA<<" with norm="<< BBCA.NormL2()<<endl;
175  cout <<"BBC UpVec: "<<BBCUp<<" with norm="<< BBCUp.NormL2()<<endl;
176  cout <<"BBC Width: "<<BBCWidth<<endl;
177  cout <<"BBC Height: "<<BBCHeight<<endl;
178  cout <<"BBC PixelSizeX: "<<BBCPxSizeX<<endl;
179  cout <<"BBC PixelSizeY: "<<BBCPxSizeY<<endl;
180  cout <<"BBC CenterPointShiftX: "<<BBCCxShift<<endl;
181  cout <<"BBC CenterPointShiftY: "<<BBCCyShift<<endl;
182  cout <<"BBC FocalLength: "<<BBCFocalLength<<endl;
183  cout <<"BBC Radials "<<BBCk3<<" "<<BBCk5<<endl;
184  cout <<"CircleRadius"<< BBCCircleRadius<<endl;
185  }
186 #endif
187 
189 
190  K.SetIdentity();
191  K[0][0] = BBCFocalLength / BBCPxSizeX; // fx
192  K[1][1] = BBCFocalLength / BBCPxSizeY; // fy
193 
194  // compute principle point, addppx and addppy are useful in case
195  // the centerpointshift is determined separately
196  K[0][2] = double(BBCWidth-1)/2.0 + (BBCCxShift+addppx) / BBCPxSizeX;
197  K[1][2] = double(BBCHeight-1)/2.0 + (BBCCyShift+addppy) / BBCPxSizeY;
198 
199  Vector3<double> V,C,A,H;
200  V = -1.0 * BBCUp;
201 
202  C[0] = BBCC[0];
203  C[1] = BBCC[1];
204  C[2] = BBCC[2];
205 
206  A[0] = BBCA[0];
207  A[1] = BBCA[1];
208  A[2] = BBCA[2];
209 
210 
211  H = V.CrossProduct(A);
212 
213  RMatrix R;
214  for (unsigned int i=0;i<3;i++){
215  R[i][0] = H[i];
216  R[i][1] = V[i];
217  R[i][2] = A[i];
218  }
219  R.EnforceConstraints();
220  Initialize(cd);
221 
222  stringstream ss;
223  ss<<"FreeD_Camera_ID"<<BBCIdent;
224  cd.CamModel_ = ss.str();
225 
226 
227  cd.width_ = BBCWidth;
228  cd.height_ = BBCHeight;
229  if ( cd.width_==0 || cd.height_==0) {
230  if (!silent) {
231  BIASERR("Sensor-data incomplete. Camera ID=" << cd.CamID_
232  << ", Image Width= " << cd.width_
233  << ", Image Height= " << cd.height_);
234  }
235  return -1;
236  }
237 
238  // in meter:
239  cd.cellSizeX_ = BBCPxSizeX;
240  cd.cellSizeY_ = BBCPxSizeY;
242 
243  cd.principalX_ = K[0][2];
244  cd.principalY_ = K[1][2];
245 
246  cd.LensIsSpherical_ = isSpherical;
247 
248  if (isSpherical) {
249  BIASASSERT(BBCPxSizeX == BBCPxSizeY);
250  BIASASSERT(K[0][0]>0.0);
251  // radius in pixels
252  cd.radius_ = floor(BBCCircleRadius / BBCPxSizeX);
253  cd.MaxCamAngle_ = asin(double(cd.radius_) / K[0][0]) / BBCk3;
254  cd.AngleCorrX_.push_back(0.0);
255  cd.AngleCorrY_.push_back(0.0);
256  for (unsigned int r=1; r<=cd.radius_; r++) {
257  double idealTheta = cd.MaxCamAngle_ * double(r) / double(cd.radius_);
258  double realTheta = asin(double(r) / K[0][0]) / BBCk3;
259  cout<<"ideal theta = "<< idealTheta<<" real="<<realTheta <<endl;
260 
261  cd.AngleCorrX_.push_back(idealTheta);
262  cd.AngleCorrY_.push_back(realTheta);
263  }
264  K.SetIdentity();
265  cd.focallengthDef_ = 1.0;
266  cd.kc1Def_ = 0;
267  cd.kc2Def_ = 0;
268  cd.kc3Def_ = 0;
269  cd.kc4Def_ = 0;
270  } else {
271  cd.focallengthDef_ = K[0][0];
272 
273  // BBC measures radial distortion coefficients in meters at the chip
274  // We compute coefficients also in space but on the w=1 plane (or in the
275  // image with focallengthx=focallengthy=1pixel in pixels).
276  // We have to convert the coefficients k3 = k3bbc * BBCFocalLength^2
277  // and similar k5:
278 
279  cd.kc1Def_ = -1.0 * BBCk3 * BBCFocalLength * BBCFocalLength;
280  cd.kc2Def_ = -1.0 * BBCk5 * BBCFocalLength * BBCFocalLength *
281  BBCFocalLength * BBCFocalLength;
282  // tangential
283  cd.kc3Def_ = 0;
284  cd.kc4Def_ = 0;
285  }
286 
287  cd.zoomCamera_ = false;
288  cd.LensModel_ = "UnknownLens";
289 
290 
291 
292  cd.PoseInRigCenter_ = C;
293  // fill angles in the same order Projection::InitFromCameraData uses them:
295  cd.PoseInRigYaw_,
296  cd.PoseInRigRoll_);
297 
298  return 0;
299 }
300 
301 
303  const int w, const int h,
304  CameraData& cd) {
305  Initialize(cd);
306 
307  cd.width_ = w;
308  cd.height_ = h;
309  cd.CamModel_ = "fromkmatrix";
310 
311  // you can set any value here but not zero !
312  cd.CamID_ = 42;
313  cd.LensModel_ = "unknown";
314  cd.LensIsSpherical_ = false;
315 
316  cd.cellSizeX_ = 1;
317  cd.cellSizeY_ = K[0][0] / K[1][1];
318  cd.principalX_ = K[0][2];
319  cd.principalY_ = K[1][2];
320 
321  cd.focallengthDef_ = K[0][0];
322 
324 
325  cd.knownparams_vect_.clear();
326  return 0;
327 
328 }
329 
330 
331 #ifdef BIAS_HAVE_XML2
332 
333 int ProjectionParametersIO::WriteRigData(const std::string &filename,
334  const std::vector<CameraData>& vcd,
335  const std::vector<SensorData>& vsd) {
336 
337  XMLIO myXML;
338  xmlNodePtr rootNode, childNode1, childNode2, childNode3;
339  rootNode = myXML.create("rig");
340  myXML.addAttribute(rootNode, "version", std::string("1.0") );
341  for (unsigned int i=0; i<vcd.size(); i++) {
342  childNode1 = myXML.addChildNode(rootNode, "cameraDescription");
343  AddCameraDataToRig(myXML, childNode1, vcd[i]);
344  childNode2 = myXML.addChildNode(childNode1, "poseInRig");
345  myXML.addComment(childNode2, "Pitch, Yaw and Roll are the Rotation_ angles of the camera around the rigs X, Y and Z Axes relative to the rig Rotation_. The Rotation_s are applied in the order XYZ or PYR with fixed axes.");
346  childNode3 = myXML.addChildNode(childNode2, "x");
347  myXML.addContent(childNode3, vcd[i].PoseInRigCenter_[0]);
348  childNode3 = myXML.addChildNode(childNode2, "y");
349  myXML.addContent(childNode3, vcd[i].PoseInRigCenter_[1]);
350  childNode3 = myXML.addChildNode(childNode2, "z");
351  myXML.addContent(childNode3, vcd[i].PoseInRigCenter_[2]);
352  myXML.addComment(childNode2,"Rotation_ direction: from rig reference system to camera frame.");
353  childNode3 = myXML.addChildNode(childNode2, "yaw");
354  myXML.addContent(childNode3, vcd[i].PoseInRigYaw_);
355  childNode3 = myXML.addChildNode(childNode2, "pitch");
356  myXML.addContent(childNode3, vcd[i].PoseInRigPitch_);
357  childNode3 = myXML.addChildNode(childNode2, "roll");
358  myXML.addContent(childNode3, vcd[i].PoseInRigRoll_);
359  }
360 
361  for (unsigned int i=0; i<vsd.size(); i++) {
362  childNode1 = myXML.addChildNode(rootNode, "sensorDescription");
363  childNode2 = myXML.addChildNode(childNode1, "poseInRig");
364  childNode3 = myXML.addChildNode(childNode2, "x");
365  myXML.addContent(childNode3, vsd[i].PoseInRigCenter_[0]);
366  childNode3 = myXML.addChildNode(childNode2, "y");
367  myXML.addContent(childNode3, vsd[i].PoseInRigCenter_[1]);
368  childNode3 = myXML.addChildNode(childNode2, "z");
369  myXML.addContent(childNode3, vsd[i].PoseInRigCenter_[2]);
370  myXML.addComment(childNode2,"Rotation_ direction: from rig reference system to sensor frame.");
371 
372  childNode3 = myXML.addChildNode(childNode2, "pitch");
373  myXML.addContent(childNode3, vsd[i].PoseInRigPitch_);
374  childNode3 = myXML.addChildNode(childNode2, "yaw");
375  myXML.addContent(childNode3, vsd[i].PoseInRigYaw_);
376  childNode3 = myXML.addChildNode(childNode2, "roll");
377  myXML.addContent(childNode3, vsd[i].PoseInRigRoll_);
378  }
379  myXML.write(filename);
380  return 0;
381 }
382 
383 
384 int ProjectionParametersIO::ReadRigData(const std::string &filename,
385  std::vector<CameraData>& vcd,
386  const bool silent) {
387  std::vector<SensorData> vsd;
388  int ret = ReadRigData(filename,vcd,vsd);
389  if (vsd.size()>0) {
390  if (!silent) {
391  BIASERR("The data file contained sensor data, use ReadRigData"
392  << "with vector<SensorData> to get it.");
393  }
394  }
395  return ret;
396 }
397 
398 
399 int ProjectionParametersIO::ReadRigData(const std::string &filename,
400  std::vector<CameraData>& vcd,
401  std::vector<SensorData>& vsd,
402  const bool silent) {
403  vcd.clear();
404  vsd.clear();
405 
406  // TODO: check BIAS_HAVE_XML2 ! JW
407  XMLIO myXML;
408  xmlNodePtr rootNode, childNode1, childNode2;
409 
410  rootNode = myXML.read(filename);
411  if (rootNode==NULL) {
412  if (!silent) {
413  BIASERR("Rig-Parameter-File not found or parse error: " << filename <<" cwd="<< FileHandling::GetCwd() );
414  }
415  return -1;
416  }
417 
418  if (myXML.getNodeName(rootNode)!="rig" &&
419  myXML.getNodeName(rootNode)!="Rig") {
420  if (myXML.getNodeName(rootNode)!="camera" &&
421  myXML.getNodeName(rootNode)!="Camera") {
422  if (!silent) {
423  BIASERR("Root node has to be \"rig\" or \"camera\"");
424  }
425  return -1;
426  } else {
427  //Root Node is "camera"
428  vcd.resize(1);
429  return ReadCameraData(filename, vcd[0]);
430  }
431  } else {
432  // Root node is "Rig"
433  double vers=0;
434  vers = myXML.getAttributeValueDouble(rootNode, "version");
435  if (vers==0) {
436  vers = myXML.getAttributeValueDouble(rootNode, "Version");
437  }
438  if (vers!=RIG_PARAMETER_CURRENT_XML_VERSION) {
439  BIASWARN("Rig-Parameter File Version (" << vers << ")is Deprecated, "
440  << "current version is " << RIG_PARAMETER_CURRENT_XML_VERSION);
441  if (vers==0.8) {
442  ReadRigDataV0_8(filename, vcd);
443  return 0;
444  } else {
445  return -1;
446  }
447  }
448 
449  childNode1 = myXML.getFirstChild(rootNode);
450  if (childNode1 == NULL) {
451  if (!silent) {
452  BIASERR("No CameraDescriptions in Rig, empty Rig???");
453  }
454  return -1;
455  }
456 
457  int CamCount=0;
458  int SensCount=0;
459  CameraData cd;
460  SensorData sd;
461  do {
462  if (myXML.getNodeName(childNode1)=="cameraDescription") {
463  Initialize(cd);
464  childNode2 = myXML.getChild(childNode1, "camera");
465  if (childNode2 == NULL) {
466  if (!silent) {
467  BIASERR("\"CameraDescription\" without a \"Camera\" is not possible.");
468  }
469  return -1;
470  } else {
471  if (ReadCameraData(myXML, childNode2, cd)<0) return -1;
472  }
473  childNode2 = myXML.getChild(childNode1, "poseInRig");
474  if (childNode2 == NULL) {
475  if (!silent) {
476  BIASERR("\"cameraDescription\" without a \"poseInRig\" is not possible.");
477  }
478  return -1;
479  } else {
480  cd.PoseInRigCenter_[0] =
481  myXML.getNodeContentDouble(myXML.getChild(childNode2, "x"));
482  cd.PoseInRigCenter_[1] =
483  myXML.getNodeContentDouble(myXML.getChild(childNode2, "y"));
484  cd.PoseInRigCenter_[2] =
485  myXML.getNodeContentDouble(myXML.getChild(childNode2, "z"));
486  cd.PoseInRigYaw_ =
487  myXML.getNodeContentDouble(myXML.getChild(childNode2,"yaw"));
488  cd.PoseInRigPitch_ =
489  myXML.getNodeContentDouble(myXML.getChild(childNode2,"pitch"));
490  cd.PoseInRigRoll_ =
491  myXML.getNodeContentDouble(myXML.getChild(childNode2,"roll"));
492  }
493  vcd.push_back(cd);
494  CamCount++;
495  }
496 
497  if (myXML.getNodeName(childNode1)=="sensorDescription") {
498  InitializeSensor(sd);
499  childNode2 = myXML.getChild(childNode1, "poseInRig");
500  if (childNode2 == NULL) {
501  if (!silent) {
502  BIASERR("\"sensorDescription\" without a \"poseInRig\" is not possible.");
503  }
504  return -1;
505  } else {
506  sd.PoseInRigCenter_[0] =
507  myXML.getNodeContentDouble(myXML.getChild(childNode2, "x"));
508  sd.PoseInRigCenter_[1] =
509  myXML.getNodeContentDouble(myXML.getChild(childNode2, "y"));
510  sd.PoseInRigCenter_[2] =
511  myXML.getNodeContentDouble(myXML.getChild(childNode2, "z"));
512  sd.PoseInRigYaw_ =
513  myXML.getNodeContentDouble(myXML.getChild(childNode2,"yaw"));
514  sd.PoseInRigPitch_ =
515  myXML.getNodeContentDouble(myXML.getChild(childNode2,"pitch"));
516  sd.PoseInRigRoll_ =
517  myXML.getNodeContentDouble(myXML.getChild(childNode2,"roll"));
518  }
519  vcd.push_back(cd);
520  SensCount++;
521  }
522  childNode1 = myXML.getNextChild(childNode1);
523  } while (childNode1!=NULL);
524  }
525 
526  if (vcd.size()==0) return -1;
527 
528  return 0;
529 }
530 
531 
532 int ProjectionParametersIO::ReadRigDataV0_8(const std::string &filename,
533  std::vector<CameraData>& vcd,
534  const bool silent) {
535 
536  XMLIO myXML;
537  xmlNodePtr rootNode, childNode1, childNode2;
538 
539  rootNode = myXML.read(filename);
540  if (rootNode==NULL) {
541  if (!silent) {
542  BIASERR("Rig-Parameter-File not found or parse error: " << filename);
543  }
544  return -1;
545  }
546 
547  // Root node is "Rig"
548  childNode1 = myXML.getFirstChild(rootNode);
549  if (childNode1 == NULL) {
550  if (!silent) {
551  BIASERR("No CameraDescriptions in Rig, empty Rig???");
552  }
553  return -1;
554  }
555 
556  int CamCount=0;
557  CameraData cd;
558  do {
559  if (myXML.getNodeName(childNode1)=="CameraDescription") {
560  Initialize(cd);
561  childNode2 = myXML.getChild(childNode1, "Camera");
562  if (childNode2 == NULL) {
563  if (!silent) {
564  BIASERR("\"CameraDescription\" without a \"Camera\" is not possible.");
565  }
566  return -1;
567  } else {
568  if (ReadCameraData(myXML, childNode2, cd)<0) return -1;
569  }
570  childNode2 = myXML.getChild(childNode1, "PoseInRig");
571  if (childNode2 == NULL) {
572  if (!silent) {
573  BIASERR("\"CameraDescription\" without a \"PoseInRig\" is not possible.");
574  }
575  return -1;
576  } else {
577  cd.PoseInRigCenter_[0] =
578  myXML.getAttributeValueDouble(childNode2, "X");
579  cd.PoseInRigCenter_[1] =
580  myXML.getAttributeValueDouble(childNode2, "Y");
581  cd.PoseInRigCenter_[2] =
582  myXML.getAttributeValueDouble(childNode2, "Z");
583  cd.PoseInRigYaw_ =
584  myXML.getAttributeValueDouble(childNode2,"Yaw");
585  cd.PoseInRigPitch_ =
586  myXML.getAttributeValueDouble(childNode2,"Pitch");
587  cd.PoseInRigRoll_ =
588  myXML.getAttributeValueDouble(childNode2,"Roll");
589  }
590  vcd.push_back(cd);
591  CamCount++;
592  }
593  childNode1 = myXML.getNextChild(childNode1);
594  } while (childNode1!=NULL);
595 
596  if (vcd.size()==0) return -1;
597 
598  return 0;
599 }
600 
601 
602 int ProjectionParametersIO::WriteCameraData(const std::string& Filename,
603  const CameraData& cd) {
604 
605  XMLIO myXML;
606  xmlNodePtr rootNode;
607  rootNode = myXML.create("camera");
608  myXML.addAttribute(rootNode, "version",
609  CAMERA_PARAMETER_CURRENT_XML_VERSION);
610  AddCameraDataToNode(myXML, rootNode, cd);
611  myXML.write(Filename);
612  return 0;
613 
614 }
615 
616 
618  xmlNodePtr &cameraDataNode,
619  const CameraData &cd) {
620 
621  xmlNodePtr childNode;
622  childNode = myXML.addChildNode(cameraDataNode, "camera");
623  myXML.addAttribute(childNode, "version",
624  std::string("2.0") );
625  AddCameraDataToNode(myXML, childNode, cd);
626  return 0;
627 
628 }
629 
630 
632  xmlNodePtr &rootNode,
633  const CameraData &cd) {
634 
635  unsigned int i;
636  xmlNodePtr childNode2, childNode3, childNode4;
637  myXML.addComment(rootNode, "\"Model\" is an arbitrary camera name.\n \"SerialID\" is i.e. the camera firewire-bus ID.\n \"ImageWidth\" and \"ImageHeight\" are in pixel.\n \"CellSizeX\" is the size of one CCD-cell in meter.\n \"AspectRatio\" is CellsizeX/CellSizeY (same as FocalLengthY/FocalLengthX).");
638  childNode2 = myXML.addChildNode(rootNode, "Sensor");
639  myXML.addAttribute(childNode2, "Model", cd.CamModel_ );
640  myXML.addAttribute(childNode2, "SerialID", cd.CamID_);
641  myXML.addAttribute(childNode2, "ImageWidth", (int) cd.width_);
642  myXML.addAttribute(childNode2, "ImageHeight", (int) cd.height_);
643  myXML.addAttribute(childNode2, "CellSizeX", cd.cellSizeX_);
644  myXML.addAttribute(childNode2, "AspectRatio", cd.aspectratio_);
645  myXML.addComment(rootNode, "\"Model\" is an arbitrary name.\n \"Type\" can be either \"Spherical\" or \"Perspective\"");
646  childNode2 = myXML.addChildNode(rootNode, "Lens");
647  myXML.addAttribute(childNode2, "Model", cd.LensModel_ );
648  string LensType="";
649  if (cd.LensIsSpherical_) {
650  LensType="Spherical";
651  } else {
652  LensType="Perspective";
653  }
654  myXML.addAttribute(childNode2, "Type", LensType);
655  if (cd.LensIsSpherical_) {
656  childNode3 = myXML.addChildNode(childNode2, "AngleCalib");
657  myXML.addComment(childNode3, "Measurement points of angle calibration curve.\n \"AngRay\" is the angle of the viewing ray, \"AngDeformed\" is the Angle deformed by the camera.\n The maximium \"AngRay\" is the cameras FoV.");
658  for (i=0; i<cd.AngleCorrX_.size(); i++) {
659  childNode4 = myXML.addChildNode(childNode3, "MeasPt");
660  myXML.addAttribute(childNode4, "AngRay", cd.AngleCorrX_[i]);
661  myXML.addAttribute(childNode4, "AngDeformed", cd.AngleCorrY_[i]);
662  }
663  if (cd.acCoeff0_!=0 || cd.acCoeff1_!=0 || cd.acCoeff2_!=0 ||
664  cd.acCoeff3_!=0 || cd.acCoeff4_!=0) {
665  childNode3 = myXML.addChildNode(childNode2, "AngleCalibPoly");
666  myXML.addComment(childNode3, "Polynome coefficients (polynomial degree 4 CN*x^N) from matlab calibration toolbox, see: http://asl.epfl.ch/~scaramuz/research/Davide_Scaramuzza_files/Research/OcamCalib_Tutorial.htm");
667  myXML.addAttribute(childNode3, "MaxCamAngle", cd.MaxCamAngle_);
668  myXML.addAttribute(childNode3, "C0", cd.acCoeff0_);
669  myXML.addAttribute(childNode3, "C1", cd.acCoeff1_);
670  myXML.addAttribute(childNode3, "C2", cd.acCoeff2_);
671  myXML.addAttribute(childNode3, "C3", cd.acCoeff3_);
672  myXML.addAttribute(childNode3, "C4", cd.acCoeff4_);
673  }
674  } else {
675  childNode3 = myXML.addChildNode(childNode2, "PerspectiveCalib");
676  myXML.addComment(childNode3, "\"FocalLength\" is FocalLengthX in meters, if you want to give it in pixel set \"CellSizeX\"=1.\n\"k1\" and \"k2\" are radial distortion; \"p1\", \"p2\" are tangential distortion.\n Camera calibration constants coming from the matlab toolbox 'http://www.vision.caltech.edu/bouguetj/calib_doc/'.\n Distortion is calculated as x'=x*(1+k1*r^2+k2*r^4)+2*p1*x*y+p2*(r^2+2*x^2) and y'=y*(1+k1*r^2+k2*r^4)+2*p1*(r^2+2*y^2)+2*p2*x*y with r^2=(x^2+y^2).");
677  if (cd.focallengthDef_!=0) {
678  childNode4 = myXML.addChildNode(childNode3, "Default");
679  //convert to mm
680  double fl = cd.focallengthDef_ * cd.cellSizeX_;
681  myXML.addAttribute(childNode4, "FocalLength", fl);
682  myXML.addAttribute(childNode4, "k1", cd.kc1Def_);
683  myXML.addAttribute(childNode4, "k2", cd.kc2Def_);
684  myXML.addAttribute(childNode4, "p1", cd.kc3Def_);
685  myXML.addAttribute(childNode4, "p2", cd.kc4Def_);
686  }
687  for (i=0; i<cd.knownparams_vect_.size(); i++) {
688  childNode4 = myXML.addChildNode(childNode3, "ZoomStep");
689  myXML.addAttribute(childNode4, "Zoom", cd.knownparams_vect_[i].zoom);
690  //convert to mm
691  double fl = cd.knownparams_vect_[i].focallength * cd.cellSizeX_;
692  myXML.addAttribute(childNode4, "FocalLength", fl);
693  // myXML.addComment(childNode2,"Focal length in meter, if you want to use the pixel value set pixelSpacing to 1.");
694  myXML.addAttribute(childNode4, "k1", cd.knownparams_vect_[i].kc1);
695  myXML.addAttribute(childNode4, "k2", cd.knownparams_vect_[i].kc2);
696  myXML.addAttribute(childNode4, "p1", cd.knownparams_vect_[i].kc3);
697  myXML.addAttribute(childNode4, "p2", cd.knownparams_vect_[i].kc4);
698  }
699  }
700  childNode3 = myXML.addChildNode(childNode2, "VignetteCalib");
701  if (cd.LensIsSpherical_) {
702  myXML.addComment(childNode3, "The measurements for vignette calibration relate the angle of the viewing ray to an absorbtion factor for the corresponding image pixels.");
703  for (i=0; i<cd.IlluCorrX_.size(); i++) {
704  childNode4 = myXML.addChildNode(childNode3, "MeasPt");
705  myXML.addAttribute(childNode4, "AngRay", cd.IlluCorrX_[i]);
706  myXML.addAttribute(childNode4, "Fac", cd.IlluCorrY_[i]);
707  }
708  } else {
709  myXML.addComment(childNode3, "The measurements for vignette calibration relate the distance of a pixel from the image principal point to an absorbtion factor for the corresponding image pixels.");
710  for (i=0; i<cd.IlluCorrX_.size(); i++) {
711  childNode4 = myXML.addChildNode(childNode3, "MeasPt");
712  myXML.addAttribute(childNode4, "Dist", cd.IlluCorrX_[i]);
713  myXML.addAttribute(childNode4, "Fac", cd.IlluCorrY_[i]);
714  }
715  }
716 
717  myXML.addComment(rootNode, "The \"PrincipalPoint\" is given as a fraction of \"ImageWidth\"/\"ImageHeight\" with (0.5,0.5) is the image center.");
718  childNode2 = myXML.addChildNode(rootNode, "PrincipalPoint");
719  myXML.addAttribute(childNode2, "X", cd.principalX_/cd.width_);
720  myXML.addAttribute(childNode2, "Y", cd.principalY_/cd.height_);
721  if (cd.LensIsSpherical_) {
722  myXML.addComment(childNode2, "The \"SphereRadius\" is given as a fraction of \"ImageWidth\".");
723  myXML.addAttribute(childNode2, "SphereRadius", cd.radius_/cd.width_);
724  }
725 
726  return 0;
727 }
728 
729 
730 int ProjectionParametersIO::ReadCameraData(const std::string& Filename,
731  CameraData& cd,
732  const bool silent) {
733 
734  XMLIO myXML;
735  xmlNodePtr rootNode;
736  rootNode = myXML.read(Filename);
737  if (rootNode==NULL) {
738  if (!silent) {
739  BIASERR("Camera-Parameter-File not found or parse error: " << Filename);
740  }
741  return -1;
742  }
743 
744  if (myXML.getNodeName(rootNode)!="camera" &&
745  myXML.getNodeName(rootNode)!="Camera") {
746  if (!silent) {
747  BIASERR("Root node has to be \"camera\"");
748  }
749  return -1;
750  }
751  ReadCameraData (myXML, rootNode, cd);
752 
753  return 0;
754 }
755 
756 
758  xmlNodePtr &cameraNode,
759  CameraData& cd,
760  const bool silent) {
761 
762  Initialize(cd);
763 
764  double vers = 0;
765 
766  vers = myXML.getAttributeValueDouble(cameraNode, "Version");
767  if (vers==0) {
768  vers = myXML.getAttributeValueDouble(cameraNode, "version");
769  }
770  if (vers!=CAMERA_PARAMETER_CURRENT_XML_VERSION) {
771  BIASWARN("Camera-Parameter Version (" << vers << ") is Deprecated, "
772  << "current version is " << CAMERA_PARAMETER_CURRENT_XML_VERSION);
773  if (vers==0.8) {
774  ReadCameraDataV0_8(myXML, cameraNode, cd);
775  return 0;
776  } else {
777  if (vers==1.0) {
778  ReadCameraDataV1_0(myXML, cameraNode, cd);
779  return 0;
780  } else {
781  return -1;
782  }
783  }
784  }
785 
786  xmlNodePtr childNode2, childNode3, childNode4;
787 
788  childNode2 = myXML.getChild(cameraNode, "Sensor");
789  if (childNode2!=NULL) {
790  cd.CamModel_ = myXML.getAttributeValueString(childNode2, "Model");
791  cd.CamID_ = myXML.getAttributeValueInt(childNode2, "SerialID");
792  cd.width_ = myXML.getAttributeValueInt(childNode2, "ImageWidth");
793  cd.height_ = myXML.getAttributeValueInt(childNode2, "ImageHeight");
794  if (cd.CamModel_=="" || cd.CamID_==0 || cd.width_==0 || cd.height_==0) {
795  if (!silent) {
796  BIASERR("Sensor-data incomplete. Camera Model=" << cd.CamModel_
797  << ", Camera Serial=" << cd.CamID_
798  << ", Image Width=" << cd.width_
799  << ", Image Height" << cd.height_);
800  }
801  return -1;
802  }
803  cd.cellSizeX_ = myXML.getAttributeValueDouble(childNode2, "CellSizeX");
804  cd.aspectratio_ = myXML.getAttributeValueDouble(childNode2, "AspectRatio");
805  if (cd.cellSizeX_==0 || cd.aspectratio_==0) {
806  cd.aspectratio_=1;
807  cd.cellSizeX_=1;
808  cd.cellSizeY_=1;
809  } else {
810  cd.cellSizeY_ = cd.cellSizeX_ / cd.aspectratio_;
811  }
812  } else {
813  if (!silent) {
814  BIASERR("Node \"Sensor\" missing.");
815  }
816  return -1;
817  }
818 
819  childNode2 = myXML.getChild(cameraNode, "Lens");
820  if (childNode2==NULL) {
821  if (!silent) {
822  BIASERR("Node \"Lens\" missing.");
823  }
824  return -1;
825  }
826 
827  cd.LensModel_ = myXML.getAttributeValueString(childNode2, "Model");
828  string LensType = myXML.getAttributeValueString(childNode2, "Type");
829 
830  if (LensType!="Spherical" && LensType!="Perspective") {
831  if (!silent) {
832  BIASERR("Unknown Lens-Type, has to be \"Spherical\" or \"Perspective\".");
833  }
834  return -1;
835  }
836  if (LensType=="Spherical") {
837  cd.LensIsSpherical_ = true;
838  cd.zoomCamera_=false;
839  childNode3 = myXML.getChild(childNode2, "AngleCalib");
840  if (childNode3!=NULL) {
841  childNode4 = myXML.getFirstChild(childNode3);
842  if (childNode4 == NULL) {
843  if (!silent) {
844  BIASERR("No angle calibration measurement points.");
845  }
846  return -1;
847  } else {
848  do {
849  if (myXML.getNodeName(childNode4)=="MeasPt") {
850  // TODO: Write these into SphereParameters class
851  double x,y;
852  x = myXML.getAttributeValueDouble(childNode4, "AngRay");
853  y = myXML.getAttributeValueDouble(childNode4, "AngDeformed");
854  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
855  }
856  childNode4 = myXML.getNextChild();
857  cout<<".";
858  } while (childNode4!=NULL);
859  }
860  }
861  childNode3 = myXML.getChild(childNode2, "AngleCalibPoly");
862  if (childNode3==NULL && cd.AngleCorrX_.size()==0) {
863  if (!silent) {
864  BIASERR("One on the nodes \"AngleCalib\" or \"AngleCalibPoly\"" <<
865  "is necessary.");
866  }
867  return -1;
868  } else {
869  cd.MaxCamAngle_ =
870  myXML.getAttributeValueDouble(childNode3, "MaxCamAngle");
871  cd.acCoeff0_ = myXML.getAttributeValueDouble(childNode3, "C0");
872  cd.acCoeff1_ = myXML.getAttributeValueDouble(childNode3, "C1");
873  cd.acCoeff2_ = myXML.getAttributeValueDouble(childNode3, "C2");
874  cd.acCoeff3_ = myXML.getAttributeValueDouble(childNode3, "C3");
875  cd.acCoeff4_ = myXML.getAttributeValueDouble(childNode3, "C4");
876  if (cd.AngleCorrX_.size()==0) {
877  InitAngleCorrFromPoly_(cd);
878  }
879  }
880  }
881  if (LensType=="Perspective") {
882  cd.LensIsSpherical_ = false;
883  cd.zoomCamera_=false;
884  childNode3 = myXML.getChild(childNode2, "PerspectiveCalib");
885  if (childNode3 != NULL) {
886  childNode4 = myXML.getFirstChild(childNode3);
887  if (childNode4 != NULL) {
888  do {
889  if (myXML.getNodeName(childNode4)=="Default") {
890  cd.focallengthDef_ =
891  myXML.getAttributeValueDouble(childNode4, "FocalLength");
892  //convert to Pixel
893  if (cd.cellSizeX_!=1) {
895  }
896  cd.kc1Def_ = myXML.getAttributeValueDouble(childNode4, "k1");
897  cd.kc2Def_ = myXML.getAttributeValueDouble(childNode4, "k2");
898  cd.kc3Def_ = myXML.getAttributeValueDouble(childNode4, "p1");
899  cd.kc4Def_ = myXML.getAttributeValueDouble(childNode4, "p2");
900  }
901  if (myXML.getNodeName(childNode4)=="ZoomStep") {
902  CPDiscreteParam dp;
903  dp.zoom=myXML.getAttributeValueDouble(childNode4, "Zoom");
904  dp.focallength=myXML.getAttributeValueDouble(childNode4,
905  "FocalLength");
906  //convert to Pixel
907  if (cd.cellSizeX_!=1) {
908  dp.focallength = dp.focallength / cd.cellSizeX_;
909  }
910  dp.kc1=myXML.getAttributeValueDouble(childNode4, "k1");
911  dp.kc2=myXML.getAttributeValueDouble(childNode4, "k2");
912  dp.kc3=myXML.getAttributeValueDouble(childNode4, "p1");
913  dp.kc4=myXML.getAttributeValueDouble(childNode4, "p2");
914  cd.knownparams_vect_.push_back(dp);
915  cd.zoomCamera_=true;
916  }
917  childNode4 = myXML.getNextChild();
918  } while (childNode4!=NULL);
919  if (cd.knownparams_vect_.size()>0 &&
920  cd.focallengthDef_==0) {
921  cd.focallengthDef_ = cd.knownparams_vect_[0].focallength;
922  cd.kc1Def_ = cd.knownparams_vect_[0].kc1;
923  cd.kc2Def_ = cd.knownparams_vect_[0].kc2;
924  cd.kc3Def_ = cd.knownparams_vect_[0].kc3;
925  cd.kc4Def_ = cd.knownparams_vect_[0].kc4;
926  }
927  }
928  }
929  }
930 
931  childNode3 = myXML.getChild(childNode2, "VignetteCalib");
932  if (childNode3 != NULL) {
933  childNode4 = myXML.getFirstChild(childNode3);
934  if (childNode4 != NULL) {
935  do {
936  if (myXML.getNodeName(childNode4)=="MeasPt") {
937  // TODO: Write these into SphereParameters & cameradata class
938  double x,y;
939  if (cd.LensIsSpherical_) {
940  x = myXML.getAttributeValueDouble(childNode4, "AngRay");
941  } else {
942  x = myXML.getAttributeValueDouble(childNode4, "Dist");
943  }
944  y = myXML.getAttributeValueDouble(childNode4, "Fac");
945  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
946  }
947  childNode4 = myXML.getNextChild();
948  } while (childNode4!=NULL);
949  }
950  }
951 
952  childNode2 = myXML.getChild(cameraNode, "PrincipalPoint");
953  if (childNode2 != NULL) {
954  cd.principalX_ = myXML.getAttributeValueDouble(childNode2, "X");
955  cd.principalX_ = cd.width_ * cd.principalX_;
956  cd.principalY_ = myXML.getAttributeValueDouble(childNode2, "Y");
957  cd.principalY_ = cd.height_ * cd.principalY_;
958  if (cd.LensIsSpherical_) {
959  if (cd.radius_ > 0) {
960  // it would be more intuitive to pass the radius than the maxcamangle
961  // this would require to change some of the read logic
962  // maybe an improvement for version 3.0 ;-)
963 
964  if (myXML.getAttributeByName(childNode2,"SphereRadius")!=NULL) {
965  BIASWARN(endl<<endl<<endl<<"The SphereRadius field in your camera"
966  <<" parameter file is redundant and must be consistent with"
967  <<" the maximum cam angle. Your value of SphereRadius "
968  <<" will be ignored and computed"<<endl<<endl<<endl);
969  } else {
970  // fine: user erased SphereRadius entry vom camera paramter file
971  }
972  } else {
973  cd.radius_ = myXML.getAttributeValueDouble(childNode2, "SphereRadius");
974  cd.radius_ = cd.width_ * cd.radius_;
975  }
976  }
977  } else {
978  cd.principalX_ = cd.width_/2.0;
979  cd.principalY_ = cd.height_/2.0;
980  if (cd.LensIsSpherical_) {
981  cd.radius_ = cd.height_/2.0;
982  }
983  }
984 
985  return 0;
986 
987 }
988 
989 
991  xmlNodePtr &cameraNode,
992  CameraData& cd,
993  const bool silent) {
994 
995  Initialize(cd);
996 
997  cd.CamModel_ = myXML.getAttributeValueString(cameraNode, "name");
998 
999  xmlNodePtr childNode2, childNode3, childNode4, childNode5, childNode6;
1000 
1001  childNode2 = myXML.getChild(cameraNode, "id");
1002  cd.CamID_ = myXML.getNodeContentInt(childNode2);
1003  if ( cd.CamID_==0 ) {
1004  if (!silent) {
1005  BIASERR("Sensor-data incomplete. Camera ID must not be 0:" << cd.CamID_);
1006  }
1007  return -1;
1008  }
1009 
1010  childNode2 = myXML.getChild(cameraNode, "sensor");
1011  if (childNode2!=NULL) {
1012  childNode3 = myXML.getChild(childNode2, "numberOfPixels");
1013  childNode4 = myXML.getChild(childNode3, "x");
1014  cd.width_ = myXML.getNodeContentInt(childNode4);
1015  childNode4 = myXML.getChild(childNode3, "y");
1016  cd.height_ = myXML.getNodeContentInt(childNode4);
1017  if ( cd.width_==0 || cd.height_==0) {
1018  if (!silent) {
1019  BIASERR("Sensor-data incomplete. Camera ID=" << cd.CamID_
1020  << ", Image Width= " << cd.width_
1021  << ", Image Height= " << cd.height_);
1022  }
1023  return -1;
1024  }
1025 
1026  childNode3 = myXML.getChild(childNode2, "pixelSpacing");
1027  childNode4 = myXML.getChild(childNode3, "x");
1028  cd.cellSizeX_ = myXML.getNodeContentDouble(childNode4);
1029  childNode4 = myXML.getChild(childNode3, "y");
1030  cd.cellSizeY_ = myXML.getNodeContentDouble(childNode4);
1031  if (cd.cellSizeX_==0 || cd.cellSizeY_==0) {
1032  cd.cellSizeX_=1;
1033  cd.cellSizeY_=1;
1034  }
1035  cd.aspectratio_ = cd.cellSizeX_/cd.cellSizeY_;
1036  childNode3 = myXML.getChild(childNode2, "principalPoint");
1037  if (childNode3 != NULL) {
1038  childNode4 = myXML.getChild(childNode3, "x");
1039  cd.principalX_ = myXML.getNodeContentDouble(childNode4);
1040  childNode4 = myXML.getChild(childNode3, "y");
1041  cd.principalY_ = myXML.getNodeContentDouble(childNode4);
1042  //convert to Pixel
1043  cd.principalX_ = cd.width_/2.0 + cd.principalX_/cd.cellSizeX_;
1044  cd.principalY_ = cd.height_/2.0 + cd.principalY_/cd.cellSizeY_;
1045  } else {
1046  cd.principalX_ = cd.width_/2.0;
1047  cd.principalY_ = cd.height_/2.0;
1048  }
1049 
1050  } else {
1051  if (!silent) {
1052  BIASERR("Node \"sensor\" missing.");
1053  }
1054  return -1;
1055  }
1056 
1057  childNode2 = myXML.getChild(cameraNode, "lens");
1058  if (childNode2!=NULL) {
1059  cd.LensIsSpherical_=false;
1060  cd.zoomCamera_=false;
1061  } else {
1062  childNode2 = myXML.getChild(cameraNode, "zoomLens");
1063  if (childNode2!=NULL) {
1064  cd.LensIsSpherical_=false;
1065  cd.zoomCamera_=true;
1066  } else {
1067  childNode2 = myXML.getChild(cameraNode, "sphericalLens");
1068  if (childNode2!=NULL) {
1069  cd.LensIsSpherical_=true;
1070  cd.zoomCamera_=false;
1071  } else {
1072  if (!silent) {
1073  BIASERR("Camera has no lens-, zoomLens- or sphericalLens-Tag");
1074  }
1075  return -1;
1076  }
1077  }
1078  }
1079 
1080  cd.LensModel_ = myXML.getAttributeValueString(childNode2, "name");
1081 
1082  if (cd.LensIsSpherical_) {
1083 
1084  childNode3 = myXML.getChild(childNode2, "angleCalibration");
1085  if (childNode3==NULL) {
1086  if (!silent) {
1087  BIASERR("Node \"angleCalibration\" missing.");
1088  }
1089  return -1;
1090  }
1091  childNode4 = myXML.getFirstChild(childNode3);
1092  if (childNode4 == NULL) {
1093  if (!silent) {
1094  BIASERR("No angle calibration measurement points.");
1095  }
1096  return -1;
1097  } else {
1098  do {
1099  if (myXML.getNodeName(childNode4)=="measPoint") {
1100  double x,y;
1101  childNode5 = myXML.getChild(childNode4, "angleRay");
1102  x = myXML.getNodeContentDouble(childNode5);
1103  childNode5 = myXML.getChild(childNode4, "angleDeformed");
1104  y = myXML.getNodeContentDouble(childNode5);
1105  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1106  }
1107  childNode4 = myXML.getNextChild(childNode4);
1108  } while (childNode4!=NULL);
1109  }
1110 
1111  childNode3 = myXML.getChild(childNode2, "vignetteCalibration");
1112  if (childNode3 != NULL) {
1113  childNode4 = myXML.getFirstChild(childNode3);
1114  if (childNode4 != NULL) {
1115  do {
1116  if (myXML.getNodeName(childNode4)=="measPoint") {
1117  double x,y;
1118  childNode5 = myXML.getChild(childNode4, "angleRay");
1119  x = myXML.getNodeContentDouble(childNode5);
1120  childNode5 = myXML.getChild(childNode4, "factor");
1121  y = myXML.getNodeContentDouble(childNode5);
1122  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1123  }
1124  childNode4 = myXML.getNextChild(childNode4);
1125  } while (childNode4!=NULL);
1126  }
1127  }
1128 
1129  childNode3 = myXML.getChild(childNode2, "sphereRadius");
1130  cd.radius_ = myXML.getNodeContentDouble(childNode3);
1131  if (childNode3==NULL) {
1132  if (!silent) {
1133  BIASERR("Sphere radius missing!");
1134  }
1135  return -1;
1136  }
1137 
1138  } else { // if (!LensIsSpherical_)
1139  if (!cd.zoomCamera_) {
1140  childNode3 = myXML.getChild(childNode2, "focalLength");
1141  cd.focallengthDef_ = myXML.getNodeContentDouble(childNode3);
1142  //convert to Pixel
1144  childNode3 = myXML.getChild(childNode2, "distortion");
1145  childNode4 = myXML.getChild(childNode3, "radial");
1146  childNode5 = myXML.getChild(childNode4, "k1");
1147  cd.kc1Def_ = myXML.getNodeContentDouble(childNode5);
1148  childNode5 = myXML.getChild(childNode4, "k2");
1149  cd.kc2Def_ = myXML.getNodeContentDouble(childNode5);
1150  childNode4 = myXML.getChild(childNode3, "tangential");
1151  childNode5 = myXML.getChild(childNode4, "p1");
1152  cd.kc3Def_ = myXML.getNodeContentDouble(childNode5);
1153  childNode5 = myXML.getChild(childNode4, "p2");
1154  cd.kc4Def_ = myXML.getNodeContentDouble(childNode5);
1155  } else { // if (zoomCamera)
1156  childNode3 = myXML.getFirstChild(childNode2);
1157  if (childNode3 != NULL) {
1158  do {
1159  if (myXML.getNodeName(childNode3)=="zoomStep") {
1160  CPDiscreteParam dp;
1161  childNode4 = myXML.getChild(childNode3, "zoom");
1162  dp.zoom = myXML.getNodeContentDouble(childNode4);
1163  childNode4=myXML.getChild(childNode3, "focalLength");
1164  dp.focallength = myXML.getNodeContentDouble(childNode4);
1165  //convert to Pixel
1166  dp.focallength = dp.focallength/cd.cellSizeX_;
1167  childNode4=myXML.getChild(childNode3, "distortion");
1168  childNode5=myXML.getChild(childNode4, "radial");
1169  childNode6=myXML.getChild(childNode5, "k1");
1170  dp.kc1 = myXML.getNodeContentDouble(childNode6);
1171  childNode6=myXML.getChild(childNode5, "k2");
1172  dp.kc2 = myXML.getNodeContentDouble(childNode6);
1173  childNode5=myXML.getChild(childNode4, "tangential");
1174  childNode6=myXML.getChild(childNode5, "p1");
1175  dp.kc3 = myXML.getNodeContentDouble(childNode6);
1176  childNode6=myXML.getChild(childNode5, "p2");
1177  dp.kc4 = myXML.getNodeContentDouble(childNode6);
1178  cd.knownparams_vect_.push_back(dp);
1179  }
1180  if (myXML.getNodeName(childNode3)=="defaultZoom") {
1181  if (!silent) {
1182  BIASERR("defaultZoom is deprecated and has no effect, use different param-file version");
1183  }
1184  }
1185  childNode3 = myXML.getNextChild(childNode3);
1186  } while (childNode3!=NULL);
1187  if (cd.knownparams_vect_.size()>0) {
1188  cd.focallengthDef_ = cd.knownparams_vect_[0].focallength;
1189  cd.kc1Def_ = cd.knownparams_vect_[0].kc1;
1190  cd.kc2Def_ = cd.knownparams_vect_[0].kc2;
1191  cd.kc3Def_ = cd.knownparams_vect_[0].kc3;
1192  cd.kc4Def_ = cd.knownparams_vect_[0].kc4;
1193  }
1194  }
1195  }
1196  }
1197 
1198  return 0;
1199 }
1200 
1201 
1203  xmlNodePtr &cameraNode,
1204  CameraData& cd,
1205  const bool silent) {
1206 
1207  Initialize(cd);
1208 
1209  xmlNodePtr childNode2, childNode3, childNode4;
1210 
1211  childNode2 = myXML.getChild(cameraNode, "Sensor");
1212  if (childNode2!=NULL) {
1213  cd.CamModel_ = myXML.getAttributeValueString(childNode2, "Model");
1214  cd.CamID_ = myXML.getAttributeValueInt(childNode2, "SerialID");
1215  cd.width_ = myXML.getAttributeValueInt(childNode2, "ImageWidth");
1216  cd.height_ = myXML.getAttributeValueInt(childNode2, "ImageHeight");
1217  if (cd.CamModel_=="" || cd.CamID_==0 || cd.width_==0 || cd.height_==0) {
1218  if (!silent) {
1219  BIASERR("Sensor-data incomplete. Camera Model=" << cd.CamModel_
1220  << ", Camera Serial=" << cd.CamID_
1221  << ", Image Width=" << cd.width_
1222  << ", Image Height" << cd.height_);
1223  }
1224  return -1;
1225  }
1226  cd.cellSizeX_ = myXML.getAttributeValueDouble(childNode2, "CellSizeInMicrX");
1227  cd.cellSizeY_ = myXML.getAttributeValueDouble(childNode2, "CellSizeInMicrY");
1228  if (cd.cellSizeX_>100 ||cd.cellSizeY_>100) {
1229  cd.cellSizeX_ /= 1000.0;
1230  cd.cellSizeY_ /= 1000.0;
1231  } else {
1232  cd.cellSizeX_ /= 1000000.0;
1233  cd.cellSizeY_ /= 1000000.0;
1234  }
1235  if (cd.cellSizeX_==0 || cd.cellSizeY_==0) {
1236  cd.aspectratio_=1;
1237  cd.cellSizeX_=1;
1238  cd.cellSizeY_=1;
1239  } else {
1240  cd.aspectratio_ = cd.cellSizeX_/cd.cellSizeY_;
1241  }
1242  } else {
1243  if (!silent) {
1244  BIASERR("Node \"Sensor\" missing.");
1245  }
1246  return -1;
1247  }
1248 
1249  childNode2 = myXML.getChild(cameraNode, "Lens");
1250  if (childNode2==NULL) {
1251  if (!silent) {
1252  BIASERR("Node \"Lens\" missing.");
1253  }
1254  return -1;
1255  }
1256 
1257  cd.LensModel_ = myXML.getAttributeValueString(childNode2, "Model");
1258  string LensType = myXML.getAttributeValueString(childNode2, "Type");
1259 
1260  if (LensType!="Spherical" && LensType!="Perspective") {
1261  if (!silent) {
1262  BIASERR("Unknown Lens-Type, has to be \"Spherical\" or \"Perspective\".");
1263  }
1264  return -1;
1265  }
1266  if (LensType=="Spherical") {
1267  cd.LensIsSpherical_ = true;
1268  cd.zoomCamera_=false;
1269  childNode3 = myXML.getChild(childNode2, "AngleCalib");
1270  if (childNode3==NULL) {
1271  if (!silent) {
1272  BIASERR("Node \"AngleCalib\" missing.");
1273  }
1274  return -1;
1275  }
1276  childNode4 = myXML.getFirstChild(childNode3);
1277  if (childNode4 == NULL) {
1278  if (!silent) {
1279  BIASERR("No angle calibration measurement points.");
1280  }
1281  return -1;
1282  } else {
1283  do {
1284  if (myXML.getNodeName(childNode4)=="MeasPt") {
1285  // TODO: Write these into SphereParameters class
1286  double x,y;
1287  x = myXML.getAttributeValueDouble(childNode4, "AngRay");
1288  y = myXML.getAttributeValueDouble(childNode4, "AngDeformed");
1289  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1290  }
1291  childNode4 = myXML.getNextChild();
1292  } while (childNode4!=NULL);
1293  }
1294  }
1295  if (LensType=="Perspective") {
1296  cd.LensIsSpherical_ = false;
1297  cd.zoomCamera_=false;
1298  childNode3 = myXML.getChild(childNode2, "PerspectiveCalib");
1299  if (childNode3 != NULL) {
1300  childNode4 = myXML.getFirstChild(childNode3);
1301  if (childNode4 != NULL) {
1302  do {
1303  if (myXML.getNodeName(childNode4)=="Default") {
1304  cd.focallengthDef_ =
1305  myXML.getAttributeValueDouble(childNode4, "FocalLengthInMM");
1306  //convert to Pixel
1307  if (cd.cellSizeX_!=1) {
1308  cd.focallengthDef_ = cd.focallengthDef_/1000.0/cd.cellSizeX_;
1309  }
1310  cd.kc1Def_ = myXML.getAttributeValueDouble(childNode4, "KC1");
1311  cd.kc2Def_ = myXML.getAttributeValueDouble(childNode4, "KC2");
1312  cd.kc3Def_ = myXML.getAttributeValueDouble(childNode4, "KC3");
1313  cd.kc4Def_ = myXML.getAttributeValueDouble(childNode4, "KC4");
1314  }
1315  if (myXML.getNodeName(childNode4)=="ZoomStep") {
1316  CPDiscreteParam dp;
1317  dp.zoom=myXML.getAttributeValueDouble(childNode4, "Zoom");
1318  dp.focallength=myXML.getAttributeValueDouble(childNode4,
1319  "FocalLengthInMM");
1320  //convert to Pixel
1321  if (cd.cellSizeX_!=1) {
1322  dp.focallength = dp.focallength/1000.0 / cd.cellSizeX_;
1323  }
1324  dp.kc1=myXML.getAttributeValueDouble(childNode4, "KC1");
1325  dp.kc2=myXML.getAttributeValueDouble(childNode4, "KC2");
1326  dp.kc3=myXML.getAttributeValueDouble(childNode4, "KC3");
1327  dp.kc4=myXML.getAttributeValueDouble(childNode4, "KC4");
1328  cd.knownparams_vect_.push_back(dp);
1329  cd.zoomCamera_=true;
1330  }
1331  childNode4 = myXML.getNextChild();
1332  } while (childNode4!=NULL);
1333  if (cd.knownparams_vect_.size()>0 &&
1334  cd.focallengthDef_==0) {
1335  cd.focallengthDef_ = cd.knownparams_vect_[0].focallength;
1336  cd.kc1Def_ = cd.knownparams_vect_[0].kc1;
1337  cd.kc2Def_ = cd.knownparams_vect_[0].kc2;
1338  cd.kc3Def_ = cd.knownparams_vect_[0].kc3;
1339  cd.kc4Def_ = cd.knownparams_vect_[0].kc4;
1340  }
1341  }
1342  }
1343  }
1344 
1345  childNode3 = myXML.getChild(childNode2, "VignetteCalib");
1346  if (childNode3 != NULL) {
1347  childNode4 = myXML.getFirstChild(childNode3);
1348  if (childNode4 != NULL) {
1349  do {
1350  if (myXML.getNodeName(childNode4)=="MeasPt") {
1351  // TODO: Write these into SphereParameters & cameradata class
1352  double x,y;
1353  if (cd.LensIsSpherical_) {
1354  x = myXML.getAttributeValueDouble(childNode4, "AngRay");
1355  } else {
1356  x = myXML.getAttributeValueDouble(childNode4, "Dist");
1357  }
1358  y = myXML.getAttributeValueDouble(childNode4, "Fac");
1359  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1360  }
1361  childNode4 = myXML.getNextChild();
1362  } while (childNode4!=NULL);
1363  }
1364  }
1365 
1366  childNode2 = myXML.getChild(cameraNode, "PrincipalPoint");
1367  if (childNode2 != NULL) {
1368  cd.principalX_ = myXML.getAttributeValueDouble(childNode2, "X");
1369  cd.principalY_ = myXML.getAttributeValueDouble(childNode2, "Y");
1370  if (cd.LensIsSpherical_) {
1371  cd.radius_ = myXML.getAttributeValueDouble(childNode2, "SphereRadius");
1372  }
1373  } else {
1374  cd.principalX_ = cd.width_/2.0;
1375  cd.principalY_ = cd.height_/2.0;
1376  if (cd.LensIsSpherical_) {
1377  cd.radius_ = cd.height_/2.0;
1378  }
1379  }
1380 
1381  return 0;
1382 }
1383 #endif
1384 
1385 
1387 {
1388  double pix_def, ang_def, ang_pix_der, ang_opt;
1389  int steps=14;
1390 
1391  // calculate distortion function
1392  vector<double> vx, vy;
1393  double maxradius = 0;
1394  for (unsigned int x=0; x<cd.width_/2; x++) {
1395  //ang_pix = atan2(0:floor(nx/2),-polyval([ss(end:-1:1)],[0:floor(nx/2)]));
1396  vx.push_back(x);
1397  double pol = cd.acCoeff0_ + (cd.acCoeff1_ + (cd.acCoeff2_ +
1398  (cd.acCoeff3_ + cd.acCoeff4_ * x)*x)*x)*x;
1399  double y = atan2(x,-pol);
1400  vy.push_back(y);
1401  if (x>maxradius && y<cd.MaxCamAngle_) maxradius = x;
1402  }
1403  if (cd.radius_<=0.0) {
1404  cout<<"maxradius determined as "<<maxradius<<endl;
1405  cd.radius_ = maxradius;
1406  }
1407  // numerically deriving distortion function in 0
1408  ang_pix_der = vy[1]-vy[0];
1409  Interpolator ip_inv;
1410  double dum;
1411  ip_inv.SetKnotPoints(vy);
1412  ip_inv.SetControlPoints(vx);
1413 
1414  ip_inv.InitSpline();
1415  ip_inv.Spline(dum, 0);
1416 
1417  cd.AngleCorrX_.clear();
1418  cd.AngleCorrY_.clear();
1419 
1420  for (double i=0; i-1e-10<=cd.MaxCamAngle_; i+=cd.MaxCamAngle_/steps) {
1421  ang_opt = i;
1422 
1423  ip_inv.Spline(pix_def,ang_opt);
1424  ang_def = pix_def*ang_pix_der;
1425  cd.AngleCorrX_.push_back(ang_opt);
1426  cd.AngleCorrY_.push_back(ang_def);
1427  }
1428  return 0;
1429 }
1430 
1431 
1433 
1434  Initialize(cd);
1435 
1436  CPDiscreteParam dp;
1437  cd.CamModel_ = "SONY EVI-D31";
1438  cd.CamID_ = 147094;
1439  cd.LensModel_ = "LENS_SONY_EVID31_BUILTIN";
1440  cd.LensIsSpherical_ = false;
1441 
1442  cd.cellSizeX_=1;
1443  cd.cellSizeY_=1;
1444 
1445  cd.width_=768;
1446  cd.height_=576;
1447 
1448  cd.aspectratio_=1;
1449 
1450  cd.principalX_=384;
1451  cd.principalY_=288;
1452 
1453 // exposureTime_ = 0.08;
1454 // iris_ = 1;
1455 // reciprocalFocus_ = 1.234;
1456 
1457  cd.knownparams_vect_.clear();
1458 
1459  // must be in descending order regarding the zoom!
1460 
1461  dp.zoom=47;
1462  dp.focallength=910.781402852481733;
1463  dp.kc1=-0.268280770809586;
1464  dp.kc2=0.487451704517498;
1465  dp.kc3=-0.000762042258562;
1466  dp.kc4=-0.001130194838780;
1467  cd.knownparams_vect_.push_back(dp);
1468 
1469  dp.zoom=45;
1470  dp.focallength=942.276371802197332;
1471  dp.kc1=-0.222325918868402;
1472  dp.kc2=0.303803084817878;
1473  dp.kc3=-0.000220828107747;
1474  dp.kc4=-0.002379174938453;
1475  cd.knownparams_vect_.push_back(dp);
1476 
1477  dp.zoom=43;
1478  dp.focallength=989.223042668483913;
1479  dp.kc1=-0.230499856719837;
1480  dp.kc2=0.632569092436950;
1481  dp.kc3=0.000645301367934;
1482  dp.kc4=-0.002245120579513;
1483  cd.knownparams_vect_.push_back(dp);
1484 
1485  dp.zoom=41;
1486  dp.focallength=1046.743156411611380;
1487  dp.kc1=-0.175147739150835;
1488  dp.kc2=0.399855896767651;
1489  dp.kc3=0.001819727735452;
1490  dp.kc4=-0.004642715440390;
1491  cd.knownparams_vect_.push_back(dp);
1492 
1493  dp.zoom=39;
1494  dp.focallength=1113.877613258150632;
1495  dp.kc1=-0.199908717507440;
1496  dp.kc2=0.735328948045900;
1497  dp.kc3=0.001857139856879;
1498  dp.kc4=-0.001726332328807;
1499  cd.knownparams_vect_.push_back(dp);
1500 
1501  dp.zoom=37;
1502  dp.focallength=1195.129672009601336;
1503  dp.kc1=-0.194029932886528;
1504  dp.kc2=1.052137931539009;
1505  dp.kc3=0.002556010034664;
1506  dp.kc4=-0.002664280436511;
1507  cd.knownparams_vect_.push_back(dp);
1508 
1509  dp.zoom=35;
1510  dp.focallength=1284.915674699713918;
1511  dp.kc1=-0.222381373429422;
1512  dp.kc2=1.627430874083972;
1513  dp.kc3=0.001072744905158;
1514  dp.kc4=-0.001628105221342;
1515  cd.knownparams_vect_.push_back(dp);
1516 
1517  dp.zoom=33;
1518  dp.focallength=1381.682287410254276;
1519  dp.kc1=-0.221923278642680;
1520  dp.kc2=1.734685282276320;
1521  dp.kc3=0.002486050695331;
1522  dp.kc4=-0.001291711925732;
1523  cd.knownparams_vect_.push_back(dp);
1524 
1525  dp.zoom=31;
1526  dp.focallength=1493.437763776483052;
1527  dp.kc1=-0.224447467694984;
1528  dp.kc2=1.863840161034580;
1529  dp.kc3=0.003709677616807;
1530  dp.kc4=-0.001150445035362;
1531  cd.knownparams_vect_.push_back(dp);
1532 
1533  dp.zoom=29;
1534  dp.focallength=1616.993704040472039;
1535  dp.kc1=-0.202923793671622;
1536  dp.kc2=1.473981778670278;
1537  dp.kc3=0.003684677768293;
1538  dp.kc4=-0.002550288087126;
1539  cd.knownparams_vect_.push_back(dp);
1540 
1541  dp.zoom=27;
1542  dp.focallength=1757.081611652665060;
1543  dp.kc1=-0.217240281709651;
1544  dp.kc2=2.140024501420107;
1545  dp.kc3=0.001114854630183;
1546  dp.kc4=-0.001295578479362;
1547  cd.knownparams_vect_.push_back(dp);
1548 
1549  dp.zoom=25;
1550  dp.focallength=1902.05452;
1551  dp.kc1=-0.23863;
1552  dp.kc2=1.61900;
1553  dp.kc3=0.00195;
1554  dp.kc4=-0.00185;
1555  cd.knownparams_vect_.push_back(dp);
1556 
1557  dp.zoom=23;
1558  dp.focallength=2074.378333106370974;
1559  dp.kc1=-0.255567875389573;
1560  dp.kc2=1.732924024277849;
1561  dp.kc3=0.001245946585972;
1562  dp.kc4=-0.000594821663798;
1563  cd.knownparams_vect_.push_back(dp);
1564 
1565  dp.zoom=21;
1566  dp.focallength=2282.63949;
1567  dp.kc1=-0.26368;
1568  dp.kc2=0.44519;
1569  dp.kc3=0.00174;
1570  dp.kc4=-0.00076;
1571  cd.knownparams_vect_.push_back(dp);
1572 
1573  dp.zoom=19;
1574  dp.focallength=2519.628084135987592;
1575  dp.kc1=-0.332071279316112;
1576  dp.kc2=0.944781789471998;
1577  dp.kc3=0.000746973436601;
1578  dp.kc4=-0.001772703465946;
1579  cd.knownparams_vect_.push_back(dp);
1580 
1581  dp.zoom=17;
1582  dp.focallength=2824.507670379169667;
1583  dp.kc1=-0.404343435901478;
1584  dp.kc2=0.453162060457514;
1585  dp.kc3=-0.000861720421368;
1586  dp.kc4=-0.001149130726447;
1587  cd.knownparams_vect_.push_back(dp);
1588 
1589  dp.zoom=15;
1590  dp.focallength=3226.589266051306367;
1591  dp.kc1=-0.594320179301222;
1592  dp.kc2=12.959736505367889;
1593  dp.kc3=-0.001868658432064;
1594  dp.kc4=-0.000676806079268;
1595  cd.knownparams_vect_.push_back(dp);
1596 
1597  dp.zoom=13;
1598  dp.focallength=3788.529115119004928;
1599  dp.kc1=-0.823072669196453;
1600  dp.kc2=27.510513372014003;
1601  dp.kc3=-0.006928032867432;
1602  dp.kc4=0.002134868203333;
1603  cd.knownparams_vect_.push_back(dp);
1604 
1605  dp.zoom=11;
1606  dp.focallength=4592.039263971351829;
1607  dp.kc1=-1.121702159939672;
1608  dp.kc2=36.994236469912934;
1609  dp.kc3=-0.014620822228192;
1610  dp.kc4=0.004860766468908;
1611  cd.knownparams_vect_.push_back(dp);
1612 
1613  dp.zoom=9;
1614  dp.focallength=5834.063334730769384;
1615  dp.kc1=-1.473018481165970;
1616  dp.kc2=41.598117903225528;
1617  dp.kc3=-0.028692464501407;
1618  dp.kc4=0.007739406251353;
1619  cd.knownparams_vect_.push_back(dp);
1620 
1621  dp.zoom=7;
1622  dp.focallength=5877.390940425404551;
1623  dp.kc1=-1.786184809649660;
1624  dp.kc2=109.639598242766894;
1625  dp.kc3=-0.011555140535335;
1626  dp.kc4=-0.002211119391028;
1627  cd.knownparams_vect_.push_back(dp);
1628 
1629  // this is a safety-buffer
1630  dp.zoom=1000;
1631  cd.knownparams_vect_.push_back(dp);
1632 
1633 }
1634 
1635 
1637 
1638  Initialize(cd);
1639 
1640  cd.AngleCorrX_.clear();
1641  cd.AngleCorrY_.clear();
1642  cd.IlluCorrX_.clear();
1643  cd.IlluCorrY_.clear();
1644 
1645  cd.CamModel_ = "Fisheye Camera";
1646  cd.CamID_ = 0440;
1647  cd.LensModel_ = "OMNITECH_ORIFL_190_3";
1648  cd.LensIsSpherical_ = true;
1649 
1650  cd.width_=640;
1651  cd.height_=480;
1652 
1653  cd.principalX_ = 364;
1654  cd.principalY_ = 245;
1655 
1656  cd.aspectratio_=1;
1657 
1658  cd.knownparams_vect_.clear();
1659 
1660  cd.cellSizeX_=1;
1661  cd.cellSizeY_=1;
1662 
1663  double x,y;
1664  x=0.000; y=1.000*x;
1665  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1666  x=0.138; y=1.000*x;
1667  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1668  x=0.424; y=0.993*x;
1669  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1670  x=0.757; y=0.974*x;
1671  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1672  x=1.045; y=0.941*x;
1673  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1674  x=1.342; y=0.899*x;
1675  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1676  x=1.436; y=0.881*x;
1677  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1678  x=1.652; y=0.828*x;
1679  cd.AngleCorrX_.push_back(x); cd.AngleCorrY_.push_back(y);
1680 
1681  // Vignette correction x=angle, y=darkening factor
1682  x=0.005; y=1.000;
1683  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1684  x=0.092; y=1.000;
1685  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1686  x=0.179; y=1.000;
1687  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1688  x=0.266; y=1.003;
1689  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1690  x=0.354; y=1.003;
1691  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1692  x=0.439; y=1.003;
1693  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1694  x=0.527; y=1.003;
1695  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1696  x=0.615; y=1.005;
1697  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1698  x=0.701; y=1.005;
1699  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1700  x=0.788; y=1.005;
1701  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1702  x=0.875; y=1.005;
1703  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1704  x=0.962; y=1.003;
1705  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1706  x=1.049; y=0.998;
1707  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1708  x=1.135; y=0.993;
1709  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1710  x=1.223; y=0.983;
1711  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1712  x=1.310; y=0.966;
1713  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1714  x=1.398; y=0.941;
1715  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1716  x=1.485; y=0.897;
1717  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1718  x=1.572; y=0.828;
1719  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1720  x=1.660; y=0.716;
1721  cd.IlluCorrX_.push_back(x); cd.IlluCorrY_.push_back(y);
1722 
1723  // TODO: Implement Max Angle
1724  //double MaxCamAngle = 1.6581; // 95 deg
1725 
1726  cd.radius_ = 226;
1727 }
1728 
1729 
1730 void ProjectionParametersIO::SetData_DummyRig(std::vector<CameraData>& vcd) {
1731 
1732  CameraData cd;
1733  Initialize(cd);
1734  SetData_EVID31_147094(cd);
1735  cd.PoseInRigYaw_=0;
1736  cd.PoseInRigPitch_=0;
1737  cd.PoseInRigRoll_=0;
1739  vcd.push_back(cd);
1740 
1741  Initialize(cd);
1742  SetData_OMNITECH_ORIFL_190_3(cd);
1743  cd.PoseInRigYaw_=.1;
1744  cd.PoseInRigPitch_=.2;
1745  cd.PoseInRigRoll_=-.15;
1746  cd.PoseInRigCenter_[0]=123.45;
1747  cd.PoseInRigCenter_[1]=321.54;
1748  cd.PoseInRigCenter_[2]=666.67;
1749  vcd.push_back(cd);
1750 
1751 }
1752 
1753 
1754 std::ostream& operator<<(std::ostream& os,
1755  std::vector<BIAS::CameraData>& vcd) {
1756 
1757  os << "vector<CameraData>: " << endl;
1758  for (unsigned int i=0; i<vcd.size(); i++) {
1759  os << " ----------- Camera " << i << "-----------" << endl;
1760  os << vcd[i];
1761  os << endl;
1762  }
1763 
1764  return os;
1765 }
1766 
1767 
1768 std::ostream& operator<<(std::ostream& os,
1769  std::vector<BIAS::SensorData>& vsd) {
1770 
1771  os << "vector<SensorData>: " << endl;
1772  for (unsigned int i=0; i<vsd.size(); i++) {
1773  os << " ----------- Sensor " << i << "-----------" << endl;
1774  os << vsd[i];
1775  os << endl;
1776  }
1777 
1778  return os;
1779 }
1780 
1781 
1782 std::ostream& operator<<(std::ostream& os,
1783  BIAS::CameraData& cd) {
1784 
1785  os << "CamModel_ = " << cd.CamModel_ << endl;
1786  os << "CamID_ = " << cd.CamID_ << endl;
1787  os << "LensModel_ = " << cd.LensModel_ << endl;
1788  os << "LensIsSpherical_ = " << cd.LensIsSpherical_ << endl;
1789  os << "zoomCamera_ = " << cd.zoomCamera_ << endl;
1790  os << "width_ = " << cd.width_ << endl;
1791  os << "height_ = " << cd.height_ << endl;
1792  for (int i=0; i<(int)cd.knownparams_vect_.size();i++) {
1793  os << "knownparams_vect_[" << i << "] = " << endl;
1794  CPDiscreteParam dp;
1795  dp=cd.knownparams_vect_[i];
1796  os << " zoom = " << dp.zoom << endl;
1797  os << " focallength = " << dp.focallength << endl;
1798  os << " kc1 = " << dp.kc1;
1799  os << ", kc2 = " << dp.kc2;
1800  os << ", kc3 = " << dp.kc3;
1801  os << ", kc4 = " << dp.kc4;
1802  };
1803  os << "MaxCamAngle_ = " << cd.MaxCamAngle_ << endl;
1804  os << " acCoeff0_ = " << cd.acCoeff0_;
1805  os << ", acCoeff1_ = " << cd.acCoeff1_;
1806  os << ", acCoeff2_ = " << cd.acCoeff2_;
1807  os << ", acCoeff3_ = " << cd.acCoeff3_;
1808  os << ", acCoeff4_ = " << cd.acCoeff4_;
1809  os << endl;
1810  os << "AngleCorrX_ = " ;
1811  for (int i=0; i<(int) cd.AngleCorrX_.size();i++) {
1812  os << cd.AngleCorrX_[i] << ", ";
1813  }
1814  os << endl;
1815  os << "AngleCorrY_ = ";
1816  for (int i=0; i<(int) cd.AngleCorrY_.size();i++) {
1817  os << cd.AngleCorrY_[i] << ", ";
1818  }
1819  os << endl;
1820  os << "IlluCorrX_ = ";
1821  for (int i=0; i<(int) cd.IlluCorrX_.size();i++) {
1822  os << cd.IlluCorrX_[i] << ", ";
1823  }
1824  os << endl;
1825  os << "IlluCorrY_ = ";
1826  for (int i=0; i<(int) cd.IlluCorrY_.size();i++) {
1827  os << cd.IlluCorrY_[i] << ", ";
1828  }
1829  os << endl;
1830 
1831  os << "aspectratio_ = " << cd.aspectratio_ << endl;
1832  os << "cellSizeX_ = " << cd.cellSizeX_ << endl;
1833  os << "cellSizeY_ = " << cd.cellSizeY_ << endl;
1834  os << "principalX_ = " << cd.principalX_ << endl;
1835  os << "principalY_ = " << cd.principalY_ << endl;
1836  os << "focallengthDef_ = " << cd.focallengthDef_ << endl;
1837  os << "kc1Def_ = " << cd.kc1Def_ << endl;
1838  os << "kc2Def_ = " << cd.kc2Def_ << endl;
1839  os << "kc3Def_ = " << cd.kc3Def_ << endl;
1840  os << "kc4Def_ = " << cd.kc4Def_ << endl;
1841  os << "PoseInRigCenter_ = " << cd.PoseInRigCenter_ << endl;
1842  os << "PoseInRigYaw_ = " << cd.PoseInRigYaw_ << endl;
1843  os << "PoseInRigPitch_ = " << cd.PoseInRigPitch_ << endl;
1844  os << "PoseInRigRoll_ = " << cd.PoseInRigRoll_ << endl;
1845 
1846  return os;
1847 }
1848 
1849 
1850 std::ostream& operator<<(std::ostream& os,
1851  BIAS::SensorData& sd) {
1852 
1853  os << "PoseInRigCenter_ = " << sd.PoseInRigCenter_ << endl;
1854  os << "PoseInRigYaw_ = " << sd.PoseInRigYaw_ << endl;
1855  os << "PoseInRigPitch_ = " << sd.PoseInRigPitch_ << endl;
1856  os << "PoseInRigRoll_ = " << sd.PoseInRigRoll_ << endl;
1857 
1858  return os;
1859 }
virtual void EnforceConstraints()
Enforce orthonormality constraints and right-handed rotation with SVD.
Definition: RMatrix.cpp:49
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
Definition: XMLIO.cpp:156
static void SetData_DummyRig(std::vector< CameraData > &vcd)
void InitSpline()
call this for restart at t= first knot point initiates recalculation of all polynom coefficients at f...
xmlNodePtr getNextChild()
Get the next child of the parent specified in the last getFirstChild() call, the class remembers the ...
Definition: XMLIO.cpp:466
int write(const std::string &Filename, bool AutoAddCompressionSuffix=true) const
Write the whole tree that was constructed in memory to disk.
Definition: XMLIO.cpp:379
static int ReadCameraData(const std::string &Filename, CameraData &cd, const bool silent=false)
Read a camera data parameter file and store the data in (*this)
xmlNodePtr read(const std::string &Filename)
Read and parse an XML file from disk, DtD validation is not yet implemented.
Definition: XMLIO.cpp:416
void addComment(const xmlNodePtr Node, const std::string &Comment)
Add comment to a node.
Definition: XMLIO.cpp:309
static int WriteCameraData(const std::string &Filename, const CameraData &cd)
Write all data to a camera data parameter file )
int GetPixelSizeXMeter(double &p)
compute pixel size in meter
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
xmlNodePtr create(const std::string &RootNodeName)
Create the base of a new XML-Tree in memory, already with a one and only root node.
Definition: XMLIO.cpp:88
void SetZero()
set all values to 0
Definition: Vector3.hh:559
int GetPrincipalPoint(double &x, double &y)
look up principal point
static int ReadRigDataV0_8(const std::string &filename, std::vector< CameraData > &vcd, const bool silent=false)
Reading old file versions.
static int ReadRigData(const std::string &filename, std::vector< CameraData > &vcd, const bool silent=false)
Read a rig parameter file and store the data in (*this) the Camera-, Center-, RMatrix-, and KMatrix-Vectors are reset from the file.
std::vector< double > IlluCorrY_
void SetKnotPoints(const std::vector< double > &kPnt)
set the additional knot points, if you want nonuniform interpolation.
std::vector< double > IlluCorrX_
static void InitializeSensor(SensorData &sd)
default zero initialization for a single sensor
static int SetFromKMatrix(const BIAS::KMatrix &K, const int w, const int h, CameraData &cd)
pass K and image dims to construct a simple parameter file
static int ReadFromBBCStream(std::ifstream &infile, CameraData &cd, const double &addppx=0.0, const double &addppy=0.0, const bool silent=false)
read bbc&#39;s freeD date from an open stream
static int WriteRigData(const std::string &filename, const std::vector< CameraData > &vcd, const std::vector< SensorData > &vsd=std::vector< SensorData >(0, SensorData()))
Write all data camera data and camera positions in the rig to a rig parameter file in XML-notation...
static std::string GetCwd()
Return current working directory as string.
static void SetData_EVID31_147094(CameraData &cd)
std::vector< double > AngleCorrX_
3D rotation matrix
Definition: RMatrix.hh:49
std::string getAttributeValueString(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:716
int getAttributeValueInt(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:728
this class interpolates a function y=f(t) between given control points (the y-values) ...
Definition: Interpolator.hh:71
BIAS::Vector3< double > PoseInRigCenter_
void addContent(const xmlNodePtr Node, const std::string &Content)
Add content to a node.
Definition: XMLIO.cpp:254
double getNodeContentDouble(const xmlNodePtr Node) const
Definition: XMLIO.cpp:613
int GetPixelSizeYMeter(double &p)
compute pixel size in meter
void CrossProduct(const Vector3< T > &argvec, Vector3< T > &destvec) const
cross product of two vectors destvec = this x argvec
Definition: Vector3.hh:594
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
static int ReadFromEXIF(const std::string &filename, CameraData &cd)
read jpeg EXIF header and set camera parameter
int GetHardwareName(std::string &Make, std::string &Model)
look up camera make and model
static int InitAngleCorrFromPoly_(CameraData &cd)
transform polynome coefficients from matlab toolbox (see: http://asl.epfl.ch/~scaramuz/research/David...
int Spline(double &res, double t, unsigned int k=3)
these functions do the Spline interpolation which reaches each control point.
std::vector< CPDiscreteParam > knownparams_vect_
xmlNodePtr getFirstChild(const xmlNodePtr ParentNode)
Get the first child of a given parent, or NULL for no childs.
Definition: XMLIO.cpp:452
void SetControlPoints(const std::vector< double > &cPnt1)
set the control points, which control the interpolating curve
Definition: Interpolator.hh:87
int Read(const std::string &filename)
main entry routine to read all EXIF tags from the header of image file.
std::ostream & operator<<(std::ostream &os, const Array2D< T > &arg)
Definition: Array2D.hh:260
int GetFocalLengthXPixel(double &fp)
compute focallength in pixels
BIAS::Vector3< double > PoseInRigCenter_
xmlAttrPtr getAttributeByName(const xmlNodePtr Node, const std::string &attribute_name)
search for a specific attribute
Definition: XMLIO.cpp:650
double getAttributeValueDouble(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:736
static int AddCameraDataToRig(XMLIO &myXML, xmlNodePtr &cameraDataNode, const CameraData &cd)
Add a camera sub-tree-structure to an allready created XML-tree and write the data from (*this) into ...
contains all atribute info and values of e.g. a file.
int GetRotationAnglesXYZ(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order XYZ.
static int ReadCameraDataV1_0(XMLIO &myXML, xmlNodePtr &cameraNode, CameraData &cd, const bool silent=false)
void InitExifTags()
initialize me vector with all known EXIF tags
std::string getNodeName(const xmlNodePtr Node) const
Get the name of a given Node.
Definition: XMLIO.cpp:543
std::vector< double > AngleCorrY_
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
int getNodeContentInt(const xmlNodePtr Node) const
Definition: XMLIO.cpp:579
int GetImageDimensions(int &width, int &height)
get width and height of image
static void Initialize(CameraData &cd)
default zero initialization for a single camera
static int ReadCameraDataV0_8(XMLIO &myXML, xmlNodePtr &cameraNode, CameraData &cd, const bool silent=false)
static int ReadFromBBC(const std::string &filename, CameraData &cd, const double &addppx=0.0, const double &addppy=0.0, const bool silent=false)
read bbc&#39;s freeD date from a file
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
static void SetData_OMNITECH_ORIFL_190_3(CameraData &cd)
static int AddCameraDataToNode(XMLIO &myXML, xmlNodePtr &rootNode, const CameraData &cd)
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429