Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ProjectionParametersPerspectiveDepth.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/ProjectionParametersPerspectiveDepth.hh"
27 #include "MathAlgo/PolynomialSolve.hh"
28 #include <Base/Image/ImageIO.hh>
29 
30 // backward compatibility to gcc < 4.1, all other must have omp.h !
31 #ifdef BIAS_HAVE_OPENMP
32 # if !defined(_OPENMP) && defined(WIN32)
33 # error Please check your OpenMP flags and defines - seem inconsistent.
34 # endif
35 # include <omp.h>
36 #endif
37 
38 
39 using namespace BIAS;
40 using namespace std;
41 
43 ProjectionParametersPerspectiveDepth(const unsigned int width,
44  const unsigned int height)
45  : ProjectionParametersPerspective(width, height)
46 {
47  Init();
48 }
49 
50 
54 {
55  Init();
56 
57  DepthCalibrationModel_ = model;
58 
59  switch(model){
61  DepthCalibrationParameters_.resize(6, 0.0);
62  break;
63  case DEPTH_MODEL_LINEAR:
64  DepthCalibrationParameters_.resize(2, 0.0);
65  break;
66  case DEPTH_MODEL_SPLINE:
67  // 12 control points for spline
70 
71  //set first to minDepth_
72  for(unsigned i=0;i<nrOfSplineParameters_-1;i++){
74  (minDepth_ + double(i)*(maxDepth_-minDepth_)/double(nrOfSplineParameters_-3));
75  }
76  //set last to maxDepth_
77  listSplineKnotPoints_[nrOfSplineParameters_-1]=
78  DepthCalibrationParameters_[nrOfSplineParameters_-1] = maxDepth_;
79  break;
80  case DEPTH_MODEL_NONE:
82  DepthCalibrationParameters_.resize(0,0.0);
83  default:
84  // BIASWARN("Depth error model None set!");
85  return;
86  }
87 }
88 
90 Init(){
91  D_DEPTH_DISTORTION=NewDebugLevel("D_DEPTH_DISTORTION");
92  //AddDebugLevel(D_DEPTH_DISTORTION);
93 
96  bSplinePrepared_ = false;
98  DepthCalibrationParameters_.resize(6, 0.0);
101  minDepth_ = 0.0; // set 0.0 meters as initial minDepth;
102  maxDepth_ = 15000.0; //Set 15 meters as initial maxDepth;
103 }
104 
106 SetDepthCalibrationParameters (const std::vector<double>& params,
107  float minDepth,
108  float maxDepth) {
109  minDepth_ = minDepth;
110  maxDepth_ = maxDepth;
111  unsigned size = 0;
112  if(minDepth == maxDepth)
113  BIASERR("Min and Max Depth are the same! Check your parameters!");
114 
115  switch(DepthCalibrationModel_){
116  case DEPTH_MODEL_POLYNOM:
117  size = 6;
118  if(params.size()!=6){
119  BIASWARNONCE("Polynom parameters have wrong size:"<<params.size()
120  <<" Check your parameters!");
121  }
122  break;
123  case DEPTH_MODEL_LINEAR:
124  size = 2;
125  if(params.size()!=2){
126  BIASWARNONCE("Linear parameters have wrong size:"<<params.size()
127  <<" Check your parameters!");
128  }
129  break;
130  case DEPTH_MODEL_SPLINE:
131  size = 12;
132  // we asume 10 control points! But internally have 12!
133  if(params.size()!=nrOfSplineParameters_){
134  BIASWARNONCE("Spline parameters have wrong size:"<<params.size()
135  <<" Check your parameters!");
136  }
137  break;
138  case DEPTH_MODEL_NONE:
140  size = 0;
141  return;
142  default:
143  //BIASWARN("Depth error model None set!");
144  return;
145  }
146  //set params
148  for(unsigned i=0;i<size;i++){
149  DepthCalibrationParameters_.push_back(params[i]);
150  }
151 
153  listSplineKnotPoints_.clear();
155 
156  //set first to 0
158 
159  for(unsigned i=1;i<nrOfSplineParameters_-1;i++){
160  listSplineKnotPoints_[i]=(minDepth + double(i-1)*(maxDepth-minDepth)/
161  double(nrOfSplineParameters_-3));
162 
163  }
164  //set last knot point to last depth point
165  listSplineKnotPoints_[nrOfSplineParameters_-1]=
166  DepthCalibrationParameters_[nrOfSplineParameters_-1];
167 
168  PrepareSpline_();
169  }
170 }
171 
173 SetDepthCalibrationParametersSpline (const std::vector<double>& knots,
174  const std::vector<double>& controls,
175  float minDepth,
176  float maxDepth) {
178  BIASASSERT(knots.size() == controls.size());
179  BIASASSERT(knots.size() == nrOfSplineParameters_);
180  BIASASSERT(minDepth_ == maxDepth_);
181  minDepth_ = minDepth;
182  maxDepth_ = maxDepth;
183  listSplineKnotPoints_ = knots;
184  DepthCalibrationParameters_ = controls;
185  PrepareSpline_();
186 }
187 
188 
190 SetReflectivityNormalizationParameters(const std::vector<double>& depthValues,
191  const std::vector<double>& minInt,
192  const std::vector<double>& maxInt,
193  const std::vector<double>& radiusValues,
194  const std::vector<double>& radiusIntensities){
195  int ret = 0;
196  std::vector<double> minIntEval;
197  std::vector<double> maxIntEval;
198 
199  depthIntNormValues_.clear();
200  for(unsigned i=0 ; i< depthValues.size(); i++){
201  if(minInt[i]<maxInt[i]){
202  depthIntNormValues_.push_back(depthValues[i]);
203  minIntEval.push_back(minInt[i]);
204  maxIntEval.push_back(maxInt[i]);
205  }
206  }
207  if(depthIntNormValues_.size() > 0){
208  PolynomialSolve PS;
209  ret = PS.FitPolynomial(3, depthIntNormValues_, minIntEval, minNormIntCoeffs_);
210  if(ret < 0) return ret;
211  ret = PS.FitPolynomial(3, depthIntNormValues_, maxIntEval, maxNormIntCoeffs_);
212  if(ret < 0) return ret;
213  /*
214  cout<<"minNormCoeffs:";
215  for(unsigned i=0;i<minNormIntCoeffs_.size();i++) cout<<minNormIntCoeffs_[i]<<"\t";
216  cout<<endl;
217  cout<<"maxNormCoeffs:";
218  for(unsigned i=0;i<maxNormIntCoeffs_.size();i++) cout<<maxNormIntCoeffs_[i]<<"\t";
219  cout<<endl;
220  */
221  }
222  // else
223  // BIASERR("SetReflectivityNormalizationParameters failed, no values");
224 
225  //Determine the valid entries in radius vectors
226  std::vector<double> radiusEval;
227  radiusIntNormValues_.clear();
228  for(unsigned i=0 ; i< radiusValues.size(); i++){
229  if(radiusIntensities[i] != 0.0){
230  radiusIntNormValues_.push_back(radiusValues[i]);
231  radiusEval.push_back(radiusIntensities[i]);
232  }
233  }
234  //fit Polynomial for radius dependent vignetting
235  if(radiusIntNormValues_.size() > 0){
236  PolynomialSolve PS;
237  ret = PS.FitPolynomial(3, radiusIntNormValues_, radiusEval, radiusIntNormCoeffs_);
238  if(ret < 0) return ret;
239  }
240  return ret;
241 }
242 
244 SetReflectivityCalibrationParameters (const std::vector<double>& params){
246 }
247 
250  DepthCalibrationModel_= model;
251  switch(model){
252  case DEPTH_MODEL_POLYNOM:
253  DepthCalibrationParameters_.resize(6, 0.0);
254  break;
255  case DEPTH_MODEL_LINEAR:
256  DepthCalibrationParameters_.resize(2, 0.0);
257  break;
258  case DEPTH_MODEL_SPLINE:
259  // 12 control points for spline
262 
263  //set first to minDepth_
264  for(unsigned i=0;i<nrOfSplineParameters_-1;i++){
266  (minDepth_ + double(i)*(maxDepth_-minDepth_)/double(nrOfSplineParameters_-3));
267  }
268  //set last to maxDepth_
269  listSplineKnotPoints_[nrOfSplineParameters_-1]=
270  DepthCalibrationParameters_[nrOfSplineParameters_-1] = maxDepth_;
271  break;
272  case DEPTH_MODEL_NONE:
274  default:
275  DepthCalibrationParameters_.resize(0, 0.0);
276  break;
277  }
278 }
279 
280 
291  bSplinePrepared_ = true;
292 }
293 
294 
296 DistortDepth (HomgPoint2D const &pos, float &d, bool bIsInCartesianCoords) {
297 
299 
300  BIASDOUT(D_DEPTH_DISTORTION,"DistortDepth, d orig:"<<d)
301  if(!bIsInCartesianCoords)
303  BIASDOUT(D_DEPTH_DISTORTION,"DistortDepth, d cartesian:"<<d)
304 
305 #ifdef BIAS_DEBUG
306  if(BIAS_ISNAN((double)d) || BIAS_ISINF((double)d)){
307  BIASWARN("Error:isnan or isinf failed for "<<d);
308  d=0;
309  }
310 #endif
311 
312  switch(DepthCalibrationModel_){
313  case DEPTH_MODEL_POLYNOM:
314  d = float(DepthCalibrationParameters_[0])
315  + (1.0f+float(DepthCalibrationParameters_[1]))*d
316  + float(DepthCalibrationParameters_[2]*pos[0]/pos[2])
317  + float(DepthCalibrationParameters_[3]*pos[1]/pos[2])
318  + float(DepthCalibrationParameters_[4])*d*d
319  + float(DepthCalibrationParameters_[5])*d*d*d;
320  break;
321  case DEPTH_MODEL_LINEAR:
322  d = float(DepthCalibrationParameters_[0])
323  + (1.0f+float(DepthCalibrationParameters_[1]))*d;
324  break;
325  case DEPTH_MODEL_SPLINE:
326  {
328  double corr=0.0;
329  splineInterpolator_.Spline(corr,(double)d,4); // akima spline
330  d = float(corr);
331  break;
332  }
333  case DEPTH_MODEL_NONE:
335  default:
336  //BIASWARN("Depth error model None set!");
337  break;
338  }
339 
340  BIASDOUT(D_DEPTH_DISTORTION,"DistortDepth, d cartesian distorted:"<<d)
341  if(!bIsInCartesianCoords)
343  BIASDOUT(D_DEPTH_DISTORTION,"DistortDepth, d polar distorted:"<<d)
344 }
345 
346 
348 UnDistortDepth (HomgPoint2D const &pos, float &d,bool bIsInCartesianCoords){
349 
351  if (d == 0.0) return;
352 
353  std::vector<double> poly(4);
354  std::vector<double> sol;
355  PolynomialSolve solver;
356  double dd;
357 
358  if(!bIsInCartesianCoords)
360 
361  switch(DepthCalibrationModel_){
362 
363  case DEPTH_MODEL_POLYNOM:
364  poly[0] = DepthCalibrationParameters_[0]
365  + DepthCalibrationParameters_[2]*pos[0]/pos[2]
366  + DepthCalibrationParameters_[3]*pos[1]/pos[2]
367  - d;
368  poly[1] = (1+DepthCalibrationParameters_[1]);
369  poly[2] = DepthCalibrationParameters_[4];
370  poly[3] = DepthCalibrationParameters_[5];
371  solver.Solve (poly, sol);
372 
373  BIASASSERT(sol.size()>0);
374  dd=sol[0];
375  for (unsigned int i=1; i<sol.size(); i++) {
376  if (fabs(sol[i]-d)<fabs(dd-d))
377  dd = sol[i];
378  }
379  d = float(dd);
380  break;
381  case DEPTH_MODEL_LINEAR:
382  d = (d-float(DepthCalibrationParameters_[0]))/
383  (1.0f+float(DepthCalibrationParameters_[1]));
384  break;
385  case DEPTH_MODEL_SPLINE:
386  {
388  double corr=0.0;
389  //backward spline function
390  splineInterpolatorUndist_.Spline(corr,(double)d,4); // akima spline
391  d = float(corr);
392  break;
393  }
394  case DEPTH_MODEL_NONE:
396  default:
397  // BIASWARN("Depth error model None set!");
398  break;
399  }
400  if(!bIsInCartesianCoords)
402 }
403 
405 UnDistortDepthMapIP(BIAS::Image<float>& depthMap, bool bIsInCartesianCoords)
406 {
407  if(!HasDepthDistortion()) return 0;
408 
409 #ifdef BIAS_DEBUG
410  unsigned int width = depthMap.GetWidth();
411  unsigned int height = depthMap.GetHeight();
412  unsigned int channels = depthMap.GetChannelCount();
413  if(width_ != width || height_ != height || channels != 1)
414  return -1;
415 #endif
416 
417  Image<float> tmpCartDepth;
418  if(!bIsInCartesianCoords){
419  TransformPolarToCartesianCoordinates(depthMap,tmpCartDepth);
420  //ImageIO::Save("cartesian-depth.mip",tmpCartDepth);
421  }
422  else
423  tmpCartDepth = depthMap;
424 
425  float **depthPtr = tmpCartDepth.GetImageDataArray();
426  HomgPoint2D p;
427  p[2] = 1.0;
428  for (unsigned int y=0;y<height_;y++) {
429  for (unsigned int x=0;x<width_;x++) {
430  p[0] = static_cast<float>(x);
431  p[1] = static_cast<float>(y);
432  //give true as last argument because we transformed
433  //the whole image to cartesian coordinates
434  UnDistortDepth(p, depthPtr[y][x],true);
435  }
436  }
437  //ImageIO::Save("cartesian-depth-undist.mip",tmpCartDepth);
438  if(!bIsInCartesianCoords)
439  TransformCartesianToPolarCoordinates(tmpCartDepth,depthMap);
440  else
441  depthMap=tmpCartDepth;
442  return 0;
443 }
444 
446 DistortDepthMapIP(BIAS::Image<float>& depthMap, bool bIsInCartesianCoords)
447 {
448  if(!HasDepthDistortion()) return 0;
449 #ifdef BIAS_DEBUG
450  unsigned int width = depthMap.GetWidth();
451  unsigned int height = depthMap.GetHeight();
452  unsigned int channels = depthMap.GetChannelCount();
453  if(width_ != width || height_ != height || channels != 1)
454  return -1;
455 #endif
456  Image<float> tmpCartDepth;
457  if(!bIsInCartesianCoords){
458  TransformPolarToCartesianCoordinates(depthMap,tmpCartDepth);
459  //ImageIO::Save("cartesian-depth.mip",tmpCartDepth);
460  }
461  else
462  tmpCartDepth = depthMap;
463 
464  float **depthPtr = tmpCartDepth.GetImageDataArray();
465  HomgPoint2D p;
466  p[2] = 1.0;
467  for (unsigned int y=0;y<height_;y++) {
468  for (unsigned int x=0;x<width_;x++) {
469  p[0] = static_cast<float>(x);
470  p[1] = static_cast<float>(y);
471  //give true as last argument because we transformed
472  //the whole image to cartesian coordinates
473  DistortDepth(p, depthPtr[y][x],true);
474  }
475  }
476  //ImageIO::Save("cartesian-depth-dist.mip",tmpCartDepth);
477  if(!bIsInCartesianCoords)
478  TransformCartesianToPolarCoordinates(tmpCartDepth,depthMap);
479  else
480  depthMap=tmpCartDepth;
481  return 0;
482 }
483 //////////////////////////////////////////////////////////////////////////////////////
484 
485 /* @brief Distort Reflectivity value depth at image position pos */
487 DistortReflectivity (HomgPoint2D const &pos,float &depth,
488  float &reflectivity,bool bIsInCartesianCoords){
489 
490  double px=0,py=0; GetPrincipal(px,py);
491  float radius =sqrt(float((pos[0]-px)*(pos[0]-px) +(pos[1]-py)*(pos[1]-py)));
492  if(!bIsInCartesianCoords)
493  depth = TransformPolarToCartesianCoordinates(pos,depth);
494 
495  //normalize Reflectivity
496  double min ,max,radialOffsetOne,radialOffset;
497  PolynomialSolve PS;
498  min = PS.EvaluatePolynomial(depth,minNormIntCoeffs_);
499  max = PS.EvaluatePolynomial(depth,maxNormIntCoeffs_);
500  radialOffsetOne = PS.EvaluatePolynomial(1,radiusIntNormCoeffs_);
501  radialOffset = PS.EvaluatePolynomial(radius,radiusIntNormCoeffs_);
502  min +=radialOffsetOne - radialOffset; //r(1) = r(r)
503  max +=radialOffsetOne - radialOffset;
504  double i_norm = reflectivity-min/(max-min);
505  depth = depth - float(PS.EvaluatePolynomial(i_norm,ReflectivityCalibrationParameters_));
506 
507  if(!bIsInCartesianCoords)
508  depth = TransformCartesianToPolarCoordinates(pos,depth);
509 }
510 
511 /* @brief UnDistort Reflectivity value i at image position pos */
513 UnDistortReflectivity (HomgPoint2D const &pos,float &depth,
514  float &reflectivity,bool bIsInCartesianCoords){
515 
516  double px=0,py=0; GetPrincipal(px,py);
517  float radius =sqrt(float((pos[0]-px)*(pos[0]-px) +(pos[1]-py)*(pos[1]-py)));
518  if(!bIsInCartesianCoords)
519  depth = TransformPolarToCartesianCoordinates(pos,depth);
520 
521  double min ,max,radialOffsetOne,radialOffset;
522  PolynomialSolve PS;
523  min = PS.EvaluatePolynomial(depth,minNormIntCoeffs_);
524  max = PS.EvaluatePolynomial(depth,maxNormIntCoeffs_);
525  radialOffsetOne = PS.EvaluatePolynomial(1,radiusIntNormCoeffs_);
526  radialOffset = PS.EvaluatePolynomial(radius,radiusIntNormCoeffs_);
527  min +=radialOffsetOne - radialOffset; //r(1) = r(r)
528  max +=radialOffsetOne - radialOffset;
529  double i_norm = reflectivity-min/(max-min);
530  depth = depth + float(PS.EvaluatePolynomial(i_norm,ReflectivityCalibrationParameters_));
531 
532  if(!bIsInCartesianCoords)
533  depth = TransformCartesianToPolarCoordinates(pos,depth);
534 }
535 
536 /* @brief Distort Reflectivity image in-place */
539  BIAS::Image<float>& ReflectivityImage,
540  bool bIsInCartesianCoords){
541 
542  Image<float> tmpCartDepth;
543  if(!bIsInCartesianCoords)
544  TransformPolarToCartesianCoordinates(depthMap,tmpCartDepth);
545  else
546  tmpCartDepth = depthMap;
547 
548  int width = (int)tmpCartDepth.GetWidth();
549  int height = (int)tmpCartDepth.GetHeight();
550  float **depthPtr = tmpCartDepth.GetImageDataArray();
551  float **intPtr = ReflectivityImage.GetImageDataArray();
552 
553 // #ifdef BIAS_HAVE_OPENMP
554 // #pragma omp parallel for if(omp_get_num_procs() > 1) shared(depthPtr,intPtr)
555 // #endif
556  for (int y=0;y<height;y++) {
557  for (int x=0;x<width;x++) {
558  HomgPoint2D pos(x,y,1);
559  DistortReflectivity(pos,depthPtr[y][x],intPtr[y][x],true);
560  }
561  }
562  if(!bIsInCartesianCoords)
563  TransformCartesianToPolarCoordinates(tmpCartDepth,depthMap);
564  else
565  depthMap=tmpCartDepth;
566  return 0;
567 }
568 
569 /* @brief Undistort Reflectivity image in-place */
572  BIAS::Image<float>& ReflectivityImage,
573  bool bIsInCartesianCoords){
574 
575  Image<float> tmpCartDepth;
576  if(!bIsInCartesianCoords)
577  TransformPolarToCartesianCoordinates(depthMap,tmpCartDepth);
578  else
579  tmpCartDepth = depthMap;
580  int width = (int)tmpCartDepth.GetWidth();
581  int height = (int)tmpCartDepth.GetHeight();
582  float **depthPtr = tmpCartDepth.GetImageDataArray();
583  float **intPtr = ReflectivityImage.GetImageDataArray();
584 
585 // #ifdef BIAS_HAVE_OPENMP
586 // #pragma omp parallel for if(omp_get_num_procs() > 1) shared(depthPtr,intPtr)
587 // #endif
588  for (int y=0;y<height;y++) {
589  for (int x=0;x<width;x++) {
590  HomgPoint2D pos(x,y,1);
591  UnDistortReflectivity(pos,depthPtr[y][x],intPtr[y][x],true);
592  }
593  }
594  if(!bIsInCartesianCoords)
595  TransformCartesianToPolarCoordinates(tmpCartDepth,depthMap);
596  else
597  depthMap=tmpCartDepth;
598  return 0;
599 }
600 
601 
604 {
605  bool hasNoDepthDistortion = true;
606  for(unsigned int i=0; i<DepthCalibrationParameters_.size(); i++) {
607  hasNoDepthDistortion = (hasNoDepthDistortion && DepthCalibrationParameters_[i] == 0.0 );
608  }
609  return !hasNoDepthDistortion;
610 }
611 
614 {
615  bool hasNoReflectivityDistortion = true;
616  for(unsigned int i=0; i<nrOfReflectivityParameters_; i++) {
617  hasNoReflectivityDistortion=(hasNoReflectivityDistortion &&
619  }
620  if(minNormIntCoeffs_.size() != 4 || maxNormIntCoeffs_.size()!= 4)
621  hasNoReflectivityDistortion = true;
622  return !hasNoReflectivityDistortion;
623 }
624 
627 {
628  for(unsigned int i=0; i<DepthCalibrationParameters_.size(); i++) {
629  DepthCalibrationParameters_[i] = 0.0 ;
630  }
631 
633  listSplineKnotPoints_.clear();
635  for(unsigned i=0;i<nrOfSplineParameters_;i++)
636  listSplineKnotPoints_[i]=0.0;
637  }
638 }
639 
642 {
643  for(unsigned int i=0; i<nrOfReflectivityParameters_; i++) {
645  }
646 }
647 
650 {
651  if(model == DEPTH_MODEL_NONE ||
652  model ==DEPTH_MODEL_UNDEFINED)
653  return 0;
654  if(model == DEPTH_MODEL_LINEAR)
655  return 2;
656  if(model == DEPTH_MODEL_POLYNOM)
657  return 6;
658  if(model == DEPTH_MODEL_SPLINE)
659  return nrOfSplineParameters_-2;
660  else return 0;
661 }
662 
665 {
667 }
668 
669 
672  switch(model){
673  case DEPTH_MODEL_NONE:
674  return string("None");
675  case DEPTH_MODEL_LINEAR:
676  return string("Linear");
677  case DEPTH_MODEL_POLYNOM:
678  return string("Polynom");
679  case DEPTH_MODEL_SPLINE:
680  return string("Spline");
682  return string("Undefined");
683  default:
684  return string("Unknown");
685  }
686 }
687 
688 #ifdef BIAS_HAVE_XML2
689 
691 XMLGetClassName(std::string& TopLevelTag, double& Version) const {
692  TopLevelTag = "ProjectionParametersPerspectiveDepth";
693  Version = 0.1;
694  return 0;
695 }
696 
698 XMLOut(const xmlNodePtr Node, XMLIO& XMLObject) const {
699  ProjectionParametersPerspective::XMLOut (Node, XMLObject);
700  xmlNodePtr childNode;
701  childNode = XMLObject.addChildNode(Node,"DepthCalibration");
702  switch(DepthCalibrationModel_){
703  case DEPTH_MODEL_POLYNOM:
704  XMLObject.addAttribute(childNode,"Model","DEPTH_MODEL_POLYNOM");
705  break;
706  case DEPTH_MODEL_LINEAR:
707  XMLObject.addAttribute(childNode,"Model","DEPTH_MODEL_LINEAR");
708  break;
709  case DEPTH_MODEL_SPLINE:
710  XMLObject.addAttribute(childNode,"Model","DEPTH_MODEL_SPLINE");
711  XMLObject.addAttribute(childNode,"NrSplineParameters",(int)nrOfSplineParameters_);
712  break;
713  case DEPTH_MODEL_NONE:
714  XMLObject.addAttribute(childNode,"Model","DEPTH_MODEL_NONE");
715  break;
717  XMLObject.addAttribute(childNode,"Model","DEPTH_MODEL_UNDEFINED");
718  break;
719  default:
720  break;
721  }
722  for (unsigned int i=0; i<DepthCalibrationParameters_.size(); i++) {
723  std::ostringstream o;
724  o << "d" << i;
725  XMLObject.addAttribute(childNode, o.str(), DepthCalibrationParameters_[i]);
726  }
727 
729  for (unsigned int i=0; i<listSplineKnotPoints_.size(); i++) {
730  std::ostringstream o;
731  o << "k" << i;
732  XMLObject.addAttribute(childNode, o.str(), listSplineKnotPoints_[i]);
733  }
734  }
735 
736  XMLObject.addAttribute(childNode,"MinDepth",minDepth_);
737  XMLObject.addAttribute(childNode,"MaxDepth",maxDepth_);
738 
739  childNode = XMLObject.addChildNode(Node,"ReflectivityCalibration");
740  for (unsigned int i=0; i<nrOfReflectivityParameters_; i++) {
741  std::ostringstream o;
742  o << "i" << i;
743  XMLObject.addAttribute(childNode, o.str(), ReflectivityCalibrationParameters_[i]);
744  }
745  for (unsigned int i=0; i<minNormIntCoeffs_.size(); i++) {
746  std::ostringstream o;
747  o << "cmin" << i;
748  XMLObject.addAttribute(childNode, o.str(), minNormIntCoeffs_[i]);
749  }
750  for (unsigned int i=0; i<maxNormIntCoeffs_.size(); i++) {
751  std::ostringstream o;
752  o << "cmax" << i;
753  XMLObject.addAttribute(childNode, o.str(), maxNormIntCoeffs_[i]);
754  }
755 
756  for (unsigned int i=0; i<radiusIntNormCoeffs_.size(); i++) {
757  std::ostringstream o;
758  o << "crad" << i;
759  XMLObject.addAttribute(childNode, o.str(), radiusIntNormCoeffs_[i]);
760  }
761  return 0;
762 }
763 
765 XMLIn(const xmlNodePtr Node, XMLIO& XMLObject) {
767  xmlNodePtr childNode;
768 
769  if ((childNode = XMLObject.getChild(Node, "DepthCalibration"))!=NULL) {
770  xmlAttrPtr modelAttr = NULL;
771  modelAttr = XMLObject.getAttributeByName(childNode, "Model");
772  if(modelAttr!=NULL)
773  {
774  string model;
775  model = XMLObject.getAttributeValueString(modelAttr);
776  if(model == "DEPTH_MODEL_POLYNOM"){
777  DepthCalibrationParameters_.resize(6, 0.0);
779  }
780  else if(model == "DEPTH_MODEL_LINEAR"){
781  DepthCalibrationParameters_.resize(2, 0.0);
783  }
784  else if(model == "DEPTH_MODEL_SPLINE"){
785  modelAttr = NULL;
786  modelAttr = XMLObject.getAttributeByName(childNode, "NrSplineParameters");
787  if(modelAttr!=NULL){
788  nrOfSplineParameters_ = XMLObject.getAttributeValueInt(modelAttr);
789  }
793  }
794  else if(model == "DEPTH_MODEL_NONE"){
796  }
797  else if(model == "DEPTH_MODEL_UNDEFINED"){
799  }
800  }
801  else
802  DepthCalibrationParameters_.resize(6, 0.0);// standard case Polynom = length 6
803 
804  for (unsigned int i=0; i<DepthCalibrationParameters_.size(); i++) {
805  std::ostringstream o;
806  o << "d" << i;
807  DepthCalibrationParameters_[i] = XMLObject.getAttributeValueDouble(childNode, o.str());
808  }
810  for (unsigned int i=0; i<listSplineKnotPoints_.size(); i++) {
811  std::ostringstream o;
812  o << "k" << i;
813  listSplineKnotPoints_[i] = XMLObject.getAttributeValueDouble(childNode, o.str());
814  }
815  }
816 
817  double min, max;
818  min = XMLObject.getAttributeValueDouble(childNode, "MinDepth");
819  max = XMLObject.getAttributeValueDouble(childNode, "MaxDepth");
820  if(min!=max && min >=0.0 && max > 0.0)
821  {minDepth_ = (float)min; maxDepth_ = (float)max;}
822  }
823  if ((childNode = XMLObject.getChild(Node, "ReflectivityCalibration"))!=NULL) {
825  for (unsigned int i=0; i<nrOfReflectivityParameters_; i++) {
826  std::ostringstream o;
827  o << "i" << i;
828  ReflectivityCalibrationParameters_[i] = XMLObject.getAttributeValueDouble(childNode, o.str());
829  }
830  minNormIntCoeffs_.resize(4);maxNormIntCoeffs_.resize(4),radiusIntNormCoeffs_.resize(4);
831  for (unsigned int i=0; i<4; i++) {
832  std::ostringstream o,o2,o3;
833  o << "cmin" << i;
834  o2<< "cmax" << i;
835  o3<< "crad" << i;
836  minNormIntCoeffs_[i] = XMLObject.getAttributeValueDouble(childNode, o.str());
837  maxNormIntCoeffs_[i] = XMLObject.getAttributeValueDouble(childNode, o2.str());
838  radiusIntNormCoeffs_[i] = XMLObject.getAttributeValueDouble(childNode, o3.str());
839  }
840  }
841 
842  return 0;
843 }
844 
845 
846 #endif // BIAS_HAVE_XML2
static unsigned nrOfSplineParameters_
void Init()
Init function called by constructors.
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
Definition: XMLIO.cpp:156
void InitSpline()
call this for restart at t= first knot point initiates recalculation of all polynom coefficients at f...
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
static std::string GetDepthDistModelString(BIAS_TOF_DEPTH_ERROR_MODEL model)
camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
void UnDistortReflectivity(HomgPoint2D const &pos, float &depth, float &Reflectivity, bool bIsInCartesianCoords=false)
UnDistort Reflectivity value i at image position pos.
virtual int GetPrincipal(double &PrincipalX, double &PrincipalY) const
Get principal point (in pixels relative to top left corner).
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
void SetDepthCalibrationModel(BIAS_TOF_DEPTH_ERROR_MODEL model)
Set the depth calibration model, one of BIAS_TOF_DEPTH_ERROR_MODEL inits the vectors and reserves spa...
int FitPolynomial(const unsigned int degree, const std::vector< double > &x, const std::vector< double > &y, std::vector< double > &coefficients)
given locations x and measurements y=f(x) approximate f by a polynomial of arbitrary degree and retur...
void SetReflectivityDepthDistortionToZero()
Sets depth reflectivity distortion to 0.
static unsigned nrOfReflectivityParameters_
void DistortDepth(HomgPoint2D const &pos, float &d, bool bIsInCartesianCoords=false)
Distort depth value d at image position pos.
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
specialization of XML write function
virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject)
specialization of XML read function
void SetKnotPoints(const std::vector< double > &kPnt)
set the additional knot points, if you want nonuniform interpolation.
int DistortReflectivityDepthIP(BIAS::Image< float > &depthMap, BIAS::Image< float > &ReflectivityImage, bool bIsInCartesianCoords=false)
Distort Reflectivity error in depth map.
void Clear()
resets everything.
void UnDistortDepth(HomgPoint2D const &pos, float &d, bool bIsInCartesianCoords=false)
UnDistort depth value d at image position pos.
unsigned int GetWidth() const
Definition: ImageBase.hh:312
void SetDepthCalibrationParametersSpline(const std::vector< double > &knots, const std::vector< double > &controls, float minDepth=0.0, float maxDepth=15000.0)
Set the depth calibration parameters for B-Spline model.
base class for solving polynomial equations
POLYNOMIALSOLVE_TYPE EvaluatePolynomial(const POLYNOMIALSOLVE_TYPE x, const std::vector< POLYNOMIALSOLVE_TYPE > &coeff) const
numerically robust way to evaluate a polynomial at position x, uses Horner scheme (same principle as ...
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
specialization of XML write function
int UnDistortReflectivityDepthIP(BIAS::Image< float > &depthMap, BIAS::Image< float > &ReflectivityImage, bool bIsInCartesianCoords=false)
Undistort Reflectivity error in depth map.
std::string getAttributeValueString(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:716
int getAttributeValueInt(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:728
static unsigned GetNrOfDepthErrormodelParameters(BIAS_TOF_DEPTH_ERROR_MODEL model)
returns the number of depth error model parameters
Wrapper class for reading and writing XML files based on the XML library libxml2. ...
Definition: XMLIO.hh:72
virtual int XMLGetClassName(std::string &TopLevelTag, double &Version) const
specialization of XML block name function
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
int SetReflectivityNormalizationParameters(const std::vector< double > &depthValues, const std::vector< double > &minInt, const std::vector< double > &maxInt, const std::vector< double > &radiusValues, const std::vector< double > &radiusIntensities)
sets the reflectivity calibration parameters and Fit polynomials to radial and reflectivity normaliza...
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
int Spline(double &res, double t, unsigned int k=3)
these functions do the Spline interpolation which reaches each control point.
unsigned int height_
height of image in pixels
int TransformCartesianToPolarCoordinates(const BIAS::Image< float > &cartesianDepth, BIAS::Image< float > &polarDepth)
transforms an image from cartesian coordinates to polar coordinates
unsigned int GetHeight() const
Definition: ImageBase.hh:319
int DistortDepthMapIP(BIAS::Image< float > &depthMap, bool bIsInCartesianCoords=false)
Distorts the passed depth map in place.
long int NewDebugLevel(const std::string &name)
creates a new debuglevel
Definition: Debug.hh:474
void SetControlPoints(const std::vector< double > &cPnt1)
set the control points, which control the interpolating curve
Definition: Interpolator.hh:87
void SetDepthCalibrationParameters(const std::vector< double > &params, float minDepth=0.0, float maxDepth=15000.0)
Set the depth calibration parameters.
xmlAttrPtr getAttributeByName(const xmlNodePtr Node, const std::string &attribute_name)
search for a specific attribute
Definition: XMLIO.cpp:650
unsigned int width_
width of image in pixels
double getAttributeValueDouble(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:736
void SetReflectivityCalibrationParameters(const std::vector< double > &params)
Set the reflectivity calibration parameters.
int TransformPolarToCartesianCoordinates(const BIAS::Image< float > &polarDepth, BIAS::Image< float > &cartesianDepth)
transforms an image from polar coordinates to cartesian coordinates
int Solve(const std::vector< POLYNOMIALSOLVE_TYPE > &coeff, std::vector< POLYNOMIALSOLVE_TYPE > &sol)
solve polynomial of arbitrary order n coeff[n]x^n+...+coeff[2]x^2+coeff[1]x+coeff[0]=0 coeff[n]!=0...
void DistortReflectivity(HomgPoint2D const &pos, float &depth, float &Reflectivity, bool bIsInCartesianCoords=false)
Distort Reflectivity value at depth at image offset form center radius.
int UnDistortDepthMapIP(BIAS::Image< float > &depthMap, bool bIsInCartesianCoords=false)
Undistorts the passed depth map in place.
ProjectionParametersPerspectiveDepth(const unsigned int width=0, const unsigned int height=0)
constructor with image width and height
static unsigned GetNrOfReflectivityParameters()
returns the number of depth reflectivity error model parameters
bool HasDepthDistortion() const
checks whether depth distortion is present
virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject)
specialization of XML read function
bool HasReflectivityDistortion() const
checks whether depth reflectivity distortion is present
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153