Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ProjectionParametersBase.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 <iostream>
26 #include <sstream>
27 #include "Geometry/ProjectionParametersBase.hh"
28 #include <Geometry/SphericalCoordinates.hh>
29 
30 using namespace std;
31 using namespace BIAS;
32 using namespace std;
33 
34 #define PROJECTION_STREAM_PRECISION 12
35 
36 ProjectionParametersBase::
37 ProjectionParametersBase(const unsigned int width,
38  const unsigned int height)
39 {
40  width_=width;
41  height_=height;
42  principalX_=0;
43  principalY_=0;
44  // set default principal point as image center
45  if (width > 0) principalX_ = 0.5*double(width-1);
46  if (height > 0) principalY_ = 0.5*double(height-1);
47  aspectratio_=1;
48  // init with some value:
49  ustTransformIntoImage_ = false;
50  ustIgnoreDistortion_ = false;
51  ustNormalize_ = false;
52  QValid_ = CValid_ = false;
53  identifier_ = "";
54  videoSourceType_ = "";
55  // use sigma distance for unscented transform sampling
56  // it is not clear whether this is correct, because alpha is not documented
57  // in UnscentedTransform and also not in the reference paper !
58  SetAlpha(1.0);
59 
60  //set values to pose as start
61  // SetC(Vector3<double>(0,0,0));
62  // SetQ(Quaternion<double>(0,0,0,1));
63 
64 }
65 
66 void ProjectionParametersBase::
67 GetFirstBorderPixel(PixelIterator& it)
68 {
69  it.x = 0;
70  it.y = 0;
71 }
72 
73 bool ProjectionParametersBase::
74 GetNextBorderPixel(PixelIterator& it)
75 {
76  if (it.x==0) {
77  if (it.y==0) {
78  // upper left image pixel, move right
79  it.x++;
80  return true;
81  }
82  // on way back up at left image border
83  it.y--;
84  // return false if finished
85  return (it.y>0.0);
86  } else if (it.x<width_-1) {
87  if (it.y==0) {
88  // moving left on upper image boundary
89  it.x++;
90  return true;
91  }
92  // moving right on lower image boundary
93  it.x--;
94  return true;
95  } else {
96  if (it.y<height_-1) {
97  // moving down on right image side
98  it.y++;return true;
99  }
100  // lower right corner
101  it.x--;
102  return true;
103  }
104 }
105 
106 void ProjectionParametersBase::
107 GetFirstEdgePosition(PixelIterator& it)
108 {
109  it.x = -0.5;
110  it.y = -0.5;
111 }
112 
113 bool ProjectionParametersBase::
114 GetNextEdgePosition(PixelIterator& it)
115 {
116  if (it.x==-0.5) {
117  if (it.y==-0.5) {
118  // upper left image pixel, move right
119  it.x++;
120  return true;
121  }
122  // on way back up at left image border
123  it.y--;
124  // return false if finished
125  return (it.y>-0.5);
126  } else if (it.x<width_-0.5) {
127  if (it.y==-0.5) {
128  // moving left on upper image boundary
129  it.x++;
130  return true;
131  }
132  // moving right on lower image boundary
133  it.x--;
134  return true;
135  } else {
136  if (it.y<height_-0.5) {
137  // moving down on right image side
138  it.y++;return true;
139  }
140  // lower right corner
141  it.x--;
142  return true;
143  }
144 }
145 
146 
147 int ProjectionParametersBase::
148 GetSphericalViewingRange(const CoordinateTransform3D& sphericalReferenceFrame,
149  double& minPhi, double& maxPhi, double& centerPhi,
150  double& minTheta, double& maxTheta )
151 {
152 
153  CoordinateTransform3D localSphericalReferenceFrame;
154  localSphericalReferenceFrame.BecomeRelativeTransform(sphericalReferenceFrame,
155  Pose_);
156 
157  if(localSphericalReferenceFrame.GetC().NormL2() > 1e-12) {
158  BIASERR("Spherical frame position and camera position are different!"
159  << endl << localSphericalReferenceFrame.GetC().NormL2());
160  return -1;
161  }
162 
163  SphericalCoordinates euc2Sphere;
164  euc2Sphere.SetAffineBase(localSphericalReferenceFrame);
165 
166  minPhi = M_PI;
167  maxPhi = -3.1;
168  minTheta = M_PI;
169  maxTheta = 0;
170 
171  double phi, theta, rho;
172  HomgPoint2D imgPoint;
173  imgPoint[2] = 1.0;
174  HomgPoint3D ray;
175  PixelIterator it;
176  // GetFirstBorderPixel(it);
177  GetFirstEdgePosition(it);
178  Vector3<double> p, d;
179  do {
180  imgPoint[0] = it.x;
181  imgPoint[1] = it.y;
182 
183  UnProjectLocal(imgPoint, p, d);
184  ray.Set(d);
185  euc2Sphere.GetSphericalCoordinatesFullPhi(ray, rho, phi, theta);
186  if(phi<minPhi) minPhi = phi;
187  if(phi>maxPhi) maxPhi = phi;
188  if(theta<minTheta) minTheta = theta;
189  if(theta>maxTheta) maxTheta = theta;
190  }
191  // while(GetNextBorderPixel(it));
192  while(GetNextEdgePosition(it));
193  //calculate centerPhi:
194  imgPoint[0] = (width_-1)/2;
195  imgPoint[1] = (height_-1)/2;
196  UnProjectLocal(imgPoint, p, d);
197  ray.Set(d);
198  euc2Sphere.GetSphericalCoordinatesFullPhi(ray, rho, centerPhi, theta);
199 
200 
201  //determine whether theta=0 or theta = M_PI do
202  //project into the images in order to find minimal/maximal
203  // theta angles:
204  HomgPoint3D minRay, maxRay;
205  euc2Sphere.GetCartesianRayFromFullPhi(0, 0, minRay);
206  euc2Sphere.GetCartesianRayFromFullPhi(0, M_PI, maxRay);
207  HomgPoint2D tmpImgPoint;
208  bool minimumIsIn = DoesPointProjectIntoImageLocal(minRay.GetEuclidean(),
209  tmpImgPoint);
210  bool maximumIsIn = DoesPointProjectIntoImageLocal(maxRay.GetEuclidean(),
211  tmpImgPoint);
212  if(maximumIsIn) {
213  maxTheta = M_PI;
214  }
215  if(minimumIsIn) {
216  minTheta = 0;
217  }
218 
219  return 0;
220 }
221 
222 bool ProjectionParametersBase::
223 DoesPointProjectIntoImage(const HomgPoint3D& X,
224  HomgPoint2D& x,
225  bool IgnoreDistortion) const
226 {
227  HomgPoint3D tempX = GetPose().GlobalToLocal(X);
228  BIAS::Vector3<double> localX;
229  tempX.GetEuclidean(localX);
230  return DoesPointProjectIntoImageLocal(localX, x, IgnoreDistortion);
231 }
232 
233 const bool ProjectionParametersBase::
234 DoIntrinsicsDiffer(const ProjectionParametersBase* p) const
235 {
236 /*
237  cout << "principalX_ : " << principalX_ << " <-> " << p->principalX_ << endl;
238  cout << "principalY_ : " << principalY_ << " <-> " << p->principalY_ << endl;
239  cout << "width_ : " << width_ << " <-> " << p->width_ << endl;
240  cout << "height_ : " << height_ << " <-> " << p->height_ << endl;
241  cout << "aspectratio_ : " << aspectratio_ << " <-> " << p->aspectratio_ << endl;
242 */
243  if(principalX_ != p->principalX_)
244  return true;
245  if(principalY_ != p->principalY_)
246  return true;
247  if(width_ != p->width_)
248  return true;
249  if(height_ != p->height_)
250  return true;
251  if(aspectratio_ != p->aspectratio_)
252  return true;
253  return false;
254 }
255 
256 const bool ProjectionParametersBase::
257 DoExtrinsicsDiffer(const ProjectionParametersBase* p) const
258 {
259 /*
260  cout << "CValid_ : " << CValid_ << " <-> " << p->CValid_ << endl;
261  cout << "QValid_ : " << QValid_ << " <-> " << p->QValid_ << endl;
262  cout << "C : " << GetC() << " <-> " << p->GetC()
263  << " (diff = " << (GetC()-p->GetC()).NormL2() << ")" << endl;
264  cout << "R : " << GetR() << " <-> " << p->GetR()
265  << " (diff = " << (GetR()-p->GetR()).NormL2() << ")" << endl;
266  cout << "Q : " << GetQ() << " <-> " << p->GetQ()
267  << " (diff = " << (GetQ()-p->GetQ()).NormL2() << ")" << endl;
268 */
269  if ((p->CValid_ != CValid_) || (p->QValid_ != QValid_))
270  return true;
271  if (QValid_ && !BIAS::Equal((GetR()-p->GetR()).NormL2(), 0.0, 1e-9))
272  // GetR() != p->GetR())
273  return true;
274  if (CValid_ && !BIAS::Equal((GetC()-p->GetC()).NormL2(), 0.0, 1e-9))
275  // GetC() != p->GetC())
276  return true;
277  return false;
278 }
279 
280 
281 RMatrix ProjectionParametersBase::
282 GetR() const
283 {
284  //if(!QValid_) BIASWARN("Projection is invalid!");
285  RMatrix R;
286  // unconst, because RMatrix::SetFromQ() in not const enough
287  Quaternion<double> qtmp = GetQ();
288  R.SetFromQuaternion(qtmp);
289  return R;
290 }
291 
292 
293 #ifdef BIAS_HAVE_XML2
294 
295 int ProjectionParametersBase::
296 XMLGetClassName(std::string& TopLevelTag,
297  double& Version) const {
298  TopLevelTag = "ProjectionParametersBase";
299  Version = 0.2;
300  return 0;
301 }
302 
303 int ProjectionParametersBase::
304 XMLOut(const xmlNodePtr Node, XMLIO& XMLObject) const {
305 
306  xmlNodePtr childNode;
307  childNode = XMLObject.addChildNode(Node, "Identifier");
308  string identutf8;
309  XMLIO::IsoLatin1ToUtf8( GetIdentifier(),identutf8);
310  XMLObject.addAttribute(childNode, "val", identutf8);
311 
312  childNode = XMLObject.addChildNode(Node, "VideoSourceType");
313  XMLObject.addAttribute(childNode, "val", GetVideoSourceType());
314 
315  childNode = XMLObject.addChildNode(Node, "ImageSize");
316  XMLObject.addAttribute(childNode, "width", (int)width_);
317  XMLObject.addAttribute(childNode, "height", (int)height_);
318 
319  childNode = XMLObject.addChildNode(Node, "PrincipalPoint");
320  XMLObject.addAttribute(childNode, "x", principalX_);
321  XMLObject.addAttribute(childNode, "y", principalY_);
322 
323  childNode = XMLObject.addChildNode(Node, "AspectRatio");
324  XMLObject.addAttribute(childNode, "val", aspectratio_);
325 
326  // R
327  // Quaternion<double> Q(0.0, 0.0, 0.0, 1.0);
328  // if (PoseValid()){
329  // Q = GetQ();
330  // }
331  if (QValid_) {
332  Quaternion<double> Q = GetQ();
333  stringstream streamR;
334  childNode = XMLObject.addChildNode(Node,"Rotation");
335  streamR << std::setprecision(PROJECTION_STREAM_PRECISION);
336  for (unsigned int i = 0; i < 4; i++) {
337  streamR << (double) Q.GetData()[i] <<" ";
338  }
339  XMLObject.addContent(childNode, streamR.str());
340  }
341 
342  // C
343  // Vector3<double> C(0.0, 0.0, 0.0);
344  // if (PoseValid()){
345  // C = GetC();
346  // }
347  if (CValid_){
348  Vector3<double> C = GetC();
349  childNode = XMLObject.addChildNode(Node,"Center");
350  XMLObject.addAttribute(childNode, "x", C[0]);
351  XMLObject.addAttribute(childNode, "y", C[1]);
352  XMLObject.addAttribute(childNode, "z", C[2]);
353  }
354  return 0;
355 }
356 
357 int ProjectionParametersBase::
358 XMLIn(const xmlNodePtr Node, XMLIO& XMLObject) {
359 
360  xmlNodePtr childNode;
361  if ((childNode = XMLObject.getChild(Node, "Identifier"))!=NULL) {
362  string identutf8;
363  identutf8 = XMLObject.getAttributeValueString(childNode, "val");
364  XMLIO::Utf8ToIsoLatin1(identutf8,identifier_);
365  }
366 
367  if ((childNode = XMLObject.getChild(Node, "VideoSourceType"))!=NULL) {
368  videoSourceType_ = XMLObject.getAttributeValueString(childNode, "val");
369  }
370 
371  if ((childNode = XMLObject.getChild(Node, "ImageSize"))!=NULL) {
372  width_ = XMLObject.getAttributeValueInt(childNode, "width");
373  height_ = XMLObject.getAttributeValueInt(childNode, "height");
374  }
375  if ((childNode = XMLObject.getChild(Node, "PrincipalPoint"))!=NULL) {
376  principalX_ = XMLObject.getAttributeValueDouble(childNode, "x");
377  principalY_ = XMLObject.getAttributeValueDouble(childNode, "y");
378  }
379  if ((childNode = XMLObject.getChild(Node, "CellSize"))!=NULL) {
380  double cellSizeX, cellSizeY;
381  cellSizeX = XMLObject.getAttributeValueDouble(childNode, "x");
382  cellSizeY = XMLObject.getAttributeValueDouble(childNode, "y");
383  aspectratio_ = cellSizeX / cellSizeY;
384  }
385  if ((childNode = XMLObject.getChild(Node, "AspectRatio"))!=NULL) {
386  aspectratio_ = XMLObject.getAttributeValueDouble(childNode, "val");
387  }
388 
390  // R
391  if ((childNode = XMLObject.getChild(Node, "Rotation"))!=NULL) {
392  // get data fields
393  stringstream ssRotation(XMLObject.getNodeContentString(childNode));
394  unsigned int CurrentData = 0;
395  while (ssRotation.good() && CurrentData<4) {
396  ssRotation >> (Q.GetData()[CurrentData++]);
397  }
398  if (CurrentData<4) {
399  // reached end of stream before expected end of data
400  BIASERR("error in xml structure, rotation matrix incomplete.");
401  return -1;
402  }
403  SetQ(Q);
404  }
405  else
406  QValid_ = false;
407 
408  // C
409  Vector3<double> C;
410  if ((childNode = XMLObject.getChild(Node, "Center"))!=NULL) {
411  C[0] = XMLObject.getAttributeValueDouble(childNode, "x");
412  C[1] = XMLObject.getAttributeValueDouble(childNode, "y");
413  C[2] = XMLObject.getAttributeValueDouble(childNode, "z");
414  SetC(C);
415  }
416  else
417  CValid_ = false;
418  return 0;
419 }
420 #endif
421 
422 double ProjectionParametersBase::
423 ViewDifference(const ProjectionParametersBase*) const {
424  // there should be an implmentation in each derived class
425  BIASERR("ViewDifference not implemented in derived class");
426  BIASABORT;
427  // visual studio needs this
428  return 0.0;
429 }
430 
431 Vector3<double> ProjectionParametersBase::
432 UnProjectToPointLocal(const HomgPoint2D& pos,
433  const double& depth, bool IgnoreDistortion) const {
434  Vector3<double> x, p;
435  UnProjectLocal(pos, p, x, IgnoreDistortion);
436  x *= depth;
437 #ifdef BIAS_DEBUG
438  if (fabs(x.NormL2()-depth)>1e-10) {
439  BIASERR("Unprojection failed:" << x << " Position:"<< pos
440  <<" Norm:" << setw(10) << double(x.NormL2()));
441  // BIASABORT;
442  }
443 #endif
444  return x;
445 }
446 
447 HomgPoint3D ProjectionParametersBase::
448 UnProjectToPoint(const HomgPoint2D& pos,
449  double depth,
450  bool IgnoreDistortion) const
451 {
452  // cout<<"[ProjectionParametersBase] UnprojectToPoint pos:"<<pos<<endl;
453  Vector3<double> point;
454  GetR().Mult(UnProjectToPointLocal(pos, depth, IgnoreDistortion), point);
455  point.AddIP(GetC());
456  return HomgPoint3D(point);
457 }
458 
459 HomgPoint3D ProjectionParametersBase::
460 UnProjectToPoint(const HomgPoint2D& pos,
461  const double depth,
462  const ProjectionParametersBase &proj,
463  bool IgnoreDistortion) const
464 {
465  Vector3<double> point;
466  GetR().Mult(proj.UnProjectToPointLocal(pos, depth, IgnoreDistortion), point);
467  point.AddIP(GetC());
468  return HomgPoint3D(point);
469 }
470 
471 int ProjectionParametersBase::
472 Transform_(const Vector<double>& src, Vector<double>& dst) const {
473  BIASASSERT(src.size()==3);BIASASSERT(dst.size()==3);
474  HomgPoint2D xsrc(src[0], src[1], src[2]), xdst, p;
475  if (ustTransformIntoImage_) {
476  xdst = ProjectLocal(xsrc, ustIgnoreDistortion_);
477  } else {
478  UnProjectLocal(xsrc, p, xdst, ustIgnoreDistortion_);
479  }
480  if (xdst.NormL2()<1e-10) {
481  // point does not transform, failed !
482  dst[0] = dst[1] = dst[2] = 0; // FIXME TODO JW
483  return -1;
484  }
485  // we do a homogenize here, for the spherical case the covariance
486  // may be interesting on the normalized point.
487  // However, for < 160 degrees, homogenize should be no problem also for
488  // spherical cameras.
489  if (ustNormalize_) {
490  xdst.Normalize();
491  } else {
492  xdst.Homogenize();
493  }
494  dst[0] = xdst[0];
495  dst[1] = xdst[1];
496  dst[2] = xdst[2];
497  return 0;
498 }
499 
500 
501 Matrix3x3<double> ProjectionParametersBase::
502 UnProjectCovLocal(const HomgPoint2D& pos, const Matrix3x3<double>& cov2D,
503  bool IgnoreDistortion, bool Normalize)
504 {
505  // set transformation parameters using class members
506  ustIgnoreDistortion_ = IgnoreDistortion;
507  ustTransformIntoImage_ = false;
508  ustNormalize_ = Normalize;
509  // convert into general data structs
510  Matrix<double> resCov(3,3,MatrixZero);
511  Vector<double> srcPoint(3);
512  Vector<double> resPoint(3);
513  srcPoint[0] = pos[0];
514  srcPoint[1] = pos[1];
515  srcPoint[2] = pos[2];
516  // use unscented transform to approximate covariance
517  Transform(srcPoint, (Matrix<double>)cov2D, resPoint, resCov);
518  //cout << "Original cov = " << cov2D << " around " << pos << endl
519  // << "Transformed to " << resCov << " around " << resPoint << endl;
520  return (Matrix3x3<double>)resCov;
521 }
522 
523 
524 ProjectionParametersBase::~ProjectionParametersBase(){
525 #ifdef BIAS_DEBUG
526  // mark this object as invalid
527  width_ = 999999;
528  height_ = 999999;
529  principalX_ = 999999;
530  principalY_ = 999999;
531  aspectratio_ = 999999;
532 #endif
533 }
534 
535 
536 KMatrix ProjectionParametersBase::
537 GetFakeKMatrix(int resolution, const double& maxangle)
538  const {
539  double dum;
540  return GetFakeKMatrix(dum, resolution);
541 }
542 
543 KMatrix ProjectionParametersBase::
544 GetFakeKMatrix(double& imgsize, int resolution, const double& ang) const {
545  imgsize = 0;
546 
547 
548  Vector3<double> ray1, ray2;
549  HomgPoint2D imgCoord1, imgCoord2;
550  switch (resolution) {
551  case 1:
552  // measure 1 deg angle in camera center
553  ray1.Set(sin(ang-M_PI/180.0),0.0,cos(ang-M_PI/180.0));
554  ray2.Set(sin(ang),0.0,cos(ang));
555  imgCoord1 = ProjectLocal(ray1);
556  imgCoord2 = ProjectLocal(ray2);
557  imgsize=(imgCoord2[0]-imgCoord1[0])*
558  tan(ang)/tan(M_PI/180.0);
559  break;
560  case 2:
561  // measure 1 deg angle near max angle
562  ray1.Set(sin(ang-M_PI/180.0),0.0,cos(ang-M_PI/180.0));
563  ray2.Set(sin(ang),0.0,cos(ang));
564  imgCoord1 = ProjectLocal(ray1);
565  imgCoord2 = ProjectLocal(ray2);
566  imgsize=(imgCoord2[0]-imgCoord1[0])*
567  tan(ang)/(tan(ang)-tan(ang-M_PI/180.0));
568  break;
569  default:
570  ray1.Set(sin(ang),0.0,cos(ang));
571  imgCoord1 = ProjectLocal(ray1);
572  imgsize = imgCoord1[0]-principalX_;
573  }
574  KMatrix K;
575  K.SetIdentity();
576  K[0][0] = imgsize/tan(ang);
577  K[1][1] = imgsize/tan(ang);
578  K[0][2] = imgsize;
579  K[1][2] = imgsize;
580  imgsize *= 2;
581  return K;
582 }
583 
584 
585 void ProjectionParametersBase::
586 Rescale(double ratio, const double offset)
587 {
588  double widthTemp = (double)width_/ratio;
589  double heightTemp = (double)height_/ratio;
590 
591  /*
592  cout << "PPB::Rescale( ratio=" << setprecision(10) << ratio << ", offset=" << offset << "): "
593  << "width_ x height_ = (" << width_ << " x " << height_ << "), "
594  << "widthTemp x heightTemp = (" << widthTemp << " x " << heightTemp << ")\n";
595  */
596  width_ = (int)rint(widthTemp); //was floor... which had the undesired sideeffect
597  //that 639.999999999 became 639 pixels instead
598  //of 640
599  height_ = (int)rint(heightTemp);
600  //cout << "new width_ x height_ = (" << width_ << " x " << height_ << ")\n";
601 
602  if( (!BIAS::Equal(widthTemp, (double)width_)) ||
603  (!BIAS::Equal(heightTemp, (double)height_))) {
604  // BIASERR("image size has integer type."<<width_<<"x"<<height_
605  // <<" Passed rescale factor "<< ratio <<" does not conform!\n");
606  }
607  principalX_ = (principalX_ - offset)/ratio;
608  principalY_ = (principalY_ - offset)/ratio;
609 
610 }
611 
612 
613 
614 void ProjectionParametersBase::
615 Rescale(unsigned int width, unsigned int height)
616 {
617 
618  unsigned int oldWidth = width_;
619  unsigned int oldHeight = height_;
620 
621  width_ = width;
622  height_= height;
623 
624  principalX_ = principalX_ / ((double)oldWidth/(double)width_);
625  principalY_ = principalY_ / ((double)oldHeight/(double)height_);
626 }
627 
628 
629 #define JACOBIAN_EPSILON 0.5
630 
631 int ProjectionParametersBase::
632 GetUnProjectionJacobian(const HomgPoint2D& x,
633  Matrix2x2<double>& Jac,
634  const bool homogenized) const {
635  BIASASSERT(x.IsHomogenized());
636  BIASASSERT(homogenized);// normalized not yet implemented
637  // numeric approximation in base class, make better in derived classes
638 
639  // compute rays for left/right/top/bottom pixels
640  Vector3<double> L = UnProjectToPointLocal(HomgPoint2D(x[0]-JACOBIAN_EPSILON,
641  x[1]), 1.0);
642  if (L.NormL2()<0.5) return -1;
643  Vector3<double> R = UnProjectToPointLocal(HomgPoint2D(x[0]+JACOBIAN_EPSILON,
644  x[1]), 1.0);
645 
646  if (R.NormL2()<0.5) return -1;
647 
648 
649  Vector3<double> T = UnProjectToPointLocal(HomgPoint2D(x[0],
650  x[1]-JACOBIAN_EPSILON),
651  1.0);
652  if (T.NormL2()<0.5) return -1;
653  Vector3<double> B = UnProjectToPointLocal(HomgPoint2D(x[0],
654  x[1]+JACOBIAN_EPSILON),
655  1.0);
656 
657  if (B.NormL2()<0.5) return -1;
658 
659  //cout<<"Left is "<<L<<endl;
660  //cout<<"Righ is "<<R<<endl;
661  //cout<<"Top is "<<T<<endl;
662  //cout<<"Bottom is "<<B<<endl;
663 
664  // check if caller wants tangent plane instead of w=1 plane
665  if (!homogenized) {
666  // parallel projection into tangent plane, "rotate camera"
667  Vector3<double> C = UnProjectToPointLocal(x, 1.0);
668  if (C.NormL2()<0.5) return -1;
669  //cout<<"feature ray C is "<<C<<endl;
670  // here we are faced with the problem of selecting a good x- and y-axis
671  // on the tangent plane
672  RMatrix Rot(MatrixIdentity);
673  // use shortest way on the sphere: rotate around orthogonal axis
675  if (axis.NormL2()>1e-7) {
676  axis.Normalize();
677  Rot.Set(axis, acos(C[2]));
678  L = Rot * L;
679  R = Rot * R;
680  T = Rot * T;
681  B = Rot * B;
682  }
683  //cout<<"new L is "<<L<<endl;
684  //cout<<"new R is "<<R<<endl;
685  //cout<<"new T is "<<T<<endl;
686  //cout<<"new B is "<<B<<endl;
687  //cout<<"Rot is "<<Rot<<endl;
688  //cout<<"Rot*C="<<Rot*C<<endl;
689  BIASASSERT((Rot*C-Vector3<double>(0,0,1)).NormL2()<1e-7);
690  } else {
691  // homogenize
692  L/=L[2];
693  R/=R[2];
694  T/=T[2];
695  B/=B[2];
696  }
697 
698  // R-L: if we make one step in x direction of the image,
699  // what step will we make in the space plane? f(R)-f(L)
700  // set into first row of Jac
701  Jac[0][0] = (R[0]-L[0]); // /2.0*JACOBIAN_EPSILON==1
702  Jac[1][0] = (R[1]-L[1]); // /2.0*JACOBIAN_EPSILON==1
703  // same with vertical step
704  Jac[0][1] = (B[0]-T[0]); // /2.0*JACOBIAN_EPSILON==1
705  Jac[1][1] = (B[1]-T[1]); // /2.0*JACOBIAN_EPSILON==1
706 
707  return 0;
708 }
709 
710 bool ProjectionParametersBase::
711 IsLeftOf(const ProjectionParametersBase& ppb) const
712 {
713  const Vector3<double> baseline = ppb.GetC() - GetC();
714  Matrix3x3<double> rMatrixInv;
715  GetR().GetInverse(rMatrixInv);
716  const Vector3<double> transformedBaseline = rMatrixInv * baseline;
717 
718  return transformedBaseline[0] >= 0.0;
719 }
720 
721 void ProjectionParametersBase::
722 SetVideoSourceType(const std::string &name)
723 {
724  videoSourceType_ = name;
725 }
virtual BIAS::Vector3< double > GetC() const
Get projection center.
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
Definition: XMLIO.cpp:156
void BecomeRelativeTransform(const CoordinateTransform3D &newLocal, const CoordinateTransform3D &newGlobal)
Changes this coordinate transformation so that parameter newLocal becomes the local coordinate frame ...
void GetEuclidean(Vector3< HOMGPOINT3D_TYPE > &dest) const
calculate affine coordinates of this and write them to dest affine coordinates are projective coordin...
Definition: HomgPoint3D.hh:336
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this-&gt;data_
Definition: Vector3.hh:532
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
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
const Vector3< double > & GetC() const
Set origin of local coordinate system in global coordinates.
void Set(const HOMGPOINT3D_TYPE &x, const HOMGPOINT3D_TYPE &y, const HOMGPOINT3D_TYPE &z)
set elementwise with given 3 euclidean scalar values.
Definition: HomgPoint3D.hh:321
int SetFromQuaternion(const Quaternion< ROTATION_MATRIX_TYPE > &q)
Set rotation matrix from a quaternion.
void GetCartesianRayFromFullPhi(const double &phi, const double &theta, HomgPoint3D &ray) const
Calculates the Euclidean ray belonging to the passed angles in the world coordinate frame...
void SetAffineBase(const CoordinateTransform3D &newAffineBase)
Sets the &quot;local&quot; coordinate frame of the spherical coordinates.
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
void addContent(const xmlNodePtr Node, const std::string &Content)
Add content to a node.
Definition: XMLIO.cpp:254
void Set(const Vector3< ROTATION_MATRIX_TYPE > &w, const ROTATION_MATRIX_TYPE phi)
Set from rotation axis w and angle phi (in rad)
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
void AddIP(const T &scalar)
Addition (in place) of an scalar.
Definition: Vector3.hh:310
int GetInverse(Matrix3x3< T > &inv) const
Matrix inversion: inverts this and stores resulty in argument inv.
Definition: Matrix3x3.cpp:373
void Mult(const T &scalar, Vector3< T > &dest) const
Definition: Vector3.hh:332
unsigned int height_
height of image in pixels
virtual BIAS::RMatrix GetR() const
Get orientation as rotation matrix R.
virtual Vector3< double > UnProjectToPointLocal(const HomgPoint2D &pos, const double &depth, bool IgnoreDistortion=false) const
calculates a 3D point in the local camera coordinate system, which belongs to the image position pos ...
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
Can be used to run along the image border.
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...
unsigned int width_
width of image in pixels
double x
If using BorderPixel methods these are the coordinates of the pixel.
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn&#39;t change the...
Definition: Vector4.hh:177
double getAttributeValueDouble(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:736
void GetSphericalCoordinatesFullPhi(const HomgPoint3D &point, double &rho, double &phi, double &theta) const
Method calculates spherical coordinates, hereby phi will lie in the range (-M_PI, M_PI] while theta l...
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
double principalX_
principal point in pixel coordinates (one for all zoom settings)
double aspectratio_
aspect ratio of the camera CCD
Transforms 3d points between two different coodinate systems, e.g.
Camera parameters which define the mapping between rays in the camera coordinate system and pixels in...
Transformation between affine and spherical coordinates.
bool IsHomogenized() const
Definition: HomgPoint2D.hh:202
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
std::string getNodeContentString(const xmlNodePtr Node) const
Get the content of a given Node.
Definition: XMLIO.cpp:554
bool QValid_
validity flag for orientation and position
Subscript size() const
Definition: vec.h:262
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429