Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
PMatrix.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 <Base/Common/BIASpragma.hh>
26 
27 #include "PMatrix.hh"
28 
29 #include <Base/Common/CompareFloatingPoint.hh>
30 #include <Base/Geometry/AffineTransf.hh>
31 #include <MathAlgo/Lapack.hh>
32 #include <fstream>
33 #include <sstream>
34 #include <MathAlgo/SVD.hh>
35 
36 using namespace BIAS;
37 using namespace std;
38 
39 
40 // precision for output using streams, counted in decimal digits
41 #define STREAM_PRECISION 12
42 
43 namespace BIAS {
44 
46  if (Svd_ != NULL) delete Svd_;
47 #ifdef BIAS_DEBUG
48  Svd_ = NULL;
49 #endif
50 }
51 
52 PMatrix::PMatrix(const std::string & s)
53 : PMatrixBase(s)
54 {
55  Svd_ = NULL;
57 }
58 
59 
60 PMatrix &
61 PMatrix::newsize(int rows, int cols)
62 {
63  BIASERR("The size of a P-Matrix has to be 3x4. newsize can't create a "
64  <<rows<<" x "<< cols << " P-matrix. aborting.");
65  exit(-1);
66  //return *this;
67 }
68 
70  : PMatrixBase(Amat)
71 {
72  if ((Amat.num_rows()==3) && (Amat.num_cols()==4)) {
73  Svd_=NULL;
75  IsMetric_ = false;
76  } else {
77  BIASERR(" wrong size in constructor! Amat is a "<<Amat.num_rows()
78  <<" x "<<Amat.num_cols()<<" matrix but must be 3x4."
79  <<std::endl );
80  BIASASSERT((Amat.num_rows()==3) && (Amat.num_cols()==4));
81  };
82 }
83 
85 {
86  if (&mat != this){
88  if (Svd_!=NULL) { delete Svd_; Svd_=NULL; }
89  if (mat.Svd_!=NULL) Svd_ = new SVD(*(mat.Svd_));
90  C_=mat.C_;
91  A_=mat.A_;
92  H0_=mat.H0_;
93  V0_=mat.V0_;
94  R_=mat.R_;
95  K_=mat.K_;
97  Hinf_=mat.Hinf_;
98 #ifdef BIAS_DEBUG
101 #endif
103  IsMetric_ = mat.IsMetric_;
104  }
105  return *this;
106 }
107 
108 /** \todo 5 different Back-Project-Funktions, "Please cleanup"
109  (evers 2004-11-29)
110 */
111 
112 
114  if (Svd_ == NULL) {
115  MakeSVD_();
116  } else {
117 #ifdef BIAS_DEBUG
118  CheckSVD_();
119 #endif
120  }
121 
122  Matrix<double> V(Svd_->GetV()); // 3x4 matrix
123  Matrix<double> SinvUT(4,3);
124  SinvUT.SetZero();
125  Matrix<double> U(Svd_->GetU()); // 4x4 matrix
126  Vector3<double> S(Svd_->GetS());
127  for (int i=0;i<U.num_rows();i++)
128  for (int j=0;j<U.num_cols();j++) {
129  SinvUT[i][j] = 1.0/S[i] * U[j][i];
130  }
131  Pinv = V * SinvUT;
132 
133  return 0;
134 }
135 
136 
138  MakeSVD_();
139  Vector<double> Nullvec(Svd_->GetNullvector());
140  if (fabs(Nullvec[3]) > DBL_EPSILON) {
141  // homogenize vector
142  C.Set(Nullvec[0]/Nullvec[3], Nullvec[1]/Nullvec[3], Nullvec[2]/Nullvec[3],
143  1.0);
144  } else {
145  // return "as is"
146  C.Set(Nullvec[0],Nullvec[1],Nullvec[2],Nullvec[3]);
147  }
148  return 0;
149 }
150 
152  if (!IsDecomposed_) {
153  if (Decompose_()!=0) return -1;
154  } else {
155  // flag says: "matrix is decomposed!"
156 #ifdef BIAS_DEBUG
158 #endif
159  }
160  Hinf = Hinf_;
161  return 0;
162 }
163 
164 
166 {
167  if (!IsDecomposed_) {
168  if (Decompose_()!=0)
169  return -1;
170  } else {
171  // flag says: "matrix is decomposed!"
172 #ifdef BIAS_DEBUG
174 #endif
175  }
176 
177  C=C_;
178  return 0;
179 }
180 
181 // JW
184  GetC(C);
185  return C;
186 }
187 
189 {
190  if (!IsDecomposed_) {
191  if (Decompose_()!=0)
192  return -1;
193  } else {
194  // flag says: "matrix is decomposed!"
195 #ifdef BIAS_DEBUG
197 #endif
198  }
199 
200  C.Set(C_[0], C_[1], C_[2]);
201  return 0;
202 }
203 
205 {
206  if (!IsDecomposed_) {
207  if ( Decompose_() != 0)
208  return -1;
209  } else {
210  // flag says: "matrix is decomposed!"
211 #ifdef BIAS_DEBUG
213 #endif
214  }
215 
216  R=R_;
217  return 0;
218 }
219 
221 {
222  if (!IsDecomposed_) {
223  if (Decompose_() != 0)
224  return -1;
225  } else {
226  // flag says: "matrix is decomposed!"
227 #ifdef BIAS_DEBUG
229 #endif
230  }
231  K=K_;
232  return 0;
233 }
234 
235 /// This is not the cam.# standard CAHV, but the unit vector H0
236 // (jw, 11/2002) (because image size is unknown)
238 {
239  if (!IsDecomposed_) {
240  if(Decompose_()!=0)
241  return -1;
242  } else {
243 
244  // flag says: "matrix is decomposed!"
245 
246 #ifdef BIAS_DEBUG
248 #endif
249  }
250 
251  H=H0_;
252  return 0;
253 }
254 
255 // JW
258  if (0!=GetH(h)) BIASERR("could not access H.");
259  return h;
260 }
261 
262 /// This is not the cam.# standard CAHV, but the unit vector H0
263 //(jw, 11/2002) (because image size is unknown)
265 {
266  if (!IsDecomposed_) {
267  if (Decompose_()!=0)
268  return -1;
269  } else {
270  // flag says: "matrix is decomposed!"
271 
272 #ifdef BIAS_DEBUG
274 #endif
275  }
276  V=V0_;
277  return 0;
278 }
279 
280 // JW
283  if (0!=GetV(v)) BIASERR("could not access V.");
284  return v;
285 }
286 
288 {
289  if (!IsDecomposed_) {
290  if (Decompose_() != 0)
291  return -1;
292  } else {
293  // flag says: "matrix is decomposed!"
294 
295 #ifdef BIAS_DEBUG
297 #endif
298  }
299  A=A_;
300  return 0;
301 }
302 
303 // JW
306  if (0!=GetA(a)) BIASERR("could not access A.");
307  return a;
308 }
309 
311  Matrix<double>& VT) {
312  MakeSVD_();
313  U = Svd_->GetU();
314  S = Svd_->GetS();
315  VT = Svd_->GetVT();
316 }
317 
319  int decomposeresult = 0;
320  // see diploma thesis gonzales p. 94 (docu; JW 11/2002)
321  double rho = 0.0;
322  PMatrix Ptmp;
323  Ptmp= *this;
324  Matrix3x3<double> matA;
325  Vector<double> vecB(3);
326 
327  // sum(P_[2][i]^2) must be 1
328  for (int i=0; i<3; i++)
329  rho += (*this)[2][i] * (*this)[2][i];
330  rho = sqrt(rho);
331  // norm temporary P
332  if (rho==0) { // JW 05/2003
333  BIASERR("degenerate case detected in decomposition. P="<<(*this)<<endl);
334  BIASABORT;
335  } else {
336  Ptmp /= rho;
337  };
338 
339  // take only left part of P (as K*R')
340  // P = [ matA | -vecB] (docu; JW 11/2002)
341  // M^T = P[0..2][0..2]
342  for (int i=0; i<3; i++) {
343  for (int j=0; j<3; j++)
344  matA[i][j] = Ptmp[i][j];
345 
346  vecB[i] = -Ptmp[i][3];
347  }
348 
349  // solve linear equations using LU factorization
350  // solve for C: "matA * C = vecB" (docu; JW 11/2002)
351  // Vector<double> tmpC=Lapack_LU_linear_solve(matA, vecB);
352 
353  int hres = matA.GetInverse(Hinf_);
354  if (hres!=0) {
355  BIASERR("error unable to compute Hinf_.");
356  Hinf_.SetZero();
357  decomposeresult = -1;
358  // pick the smallest base vector from the nullspace and assume center
359  HomgPoint3D HC;
360  this->GetNullVector(HC);
361  HC.GetEuclidean(C_);
362  } else {
363  // even here it seems to me more accurate and numerically stable to compute
364  // the center via the nullvector svd, especially when we dont exactly
365  // have (-K R^T C) as the last column of P
366  // However, we keep it the old way since it seemed to work. (koeser)
367  //C_ = Hinf_ * vecB;
368  Hinf_.Mult(vecB, C_);
369  }
370 
371  // take rows of Ptmp in: zeile 1...3 = z1..z3
372  Vector3<double> z1, z2, z3, tmp;
373  K_.SetZero();
374  K_[2][2] = 1.0;
375 
376  // for all cols: fill rows z:
377  for (int col=0; col<3; col++) {
378  z1[col] = Ptmp[0][col]; // 1st row
379  z2[col] = Ptmp[1][col]; // 2nd row
380  // R = (H V A) , KR^T = Ptmp -> A = z3
381  R_[col][2] = Ptmp[2][col];
382  // 3rd row, is unit length 1 because or previous normalization by
383  // rho (docu: JW 11/2002)
384  A_[col] = Ptmp[2][col]; // 3rd row
385  }
386 
387  // cy = z2^T * z3 (=optical center hx docu; is OK because A is orthogonal
388  // to V (see diploma thesis Gonzalez, pp. 94 JW 11/2002)
389  K_[1][2] = z2.ScalarProduct(A_);
390  // cx = z1^T * z3 (=optical center hx docu; JW 11/2002)
391  K_[0][2] = z1.ScalarProduct(A_);
392 
393  // fy = || z2^T - cy * z3^T ||
394  V0_ = (z2 - (A_ * K_[1][2]) );
395  K_[1][1] = V0_.NormL2();
396 
397  // V = 1/fy (z2^T - cx * z3^T)
398  V0_ /= K_[1][1];
399 
400  // kk: how can we assume skew=0, compute R exploiting that
401  // and then compute the skew ???
402  //
403  // skew: S= H * V.NORM
404  K_[0][1]=z1.ScalarProduct(V0_);
405 
406  // H = 1/fx (z1^T - cy * z3^T)
407  // fx = || z1^T - cx * z3^T ||
408  H0_ = (z1 - V0_*K_[0][1]-(A_ * K_[0][2]) );
409  K_[0][0] = H0_.NormL2();
410 
411  H0_ /= K_[0][0];
412 
413  // docu: Here h, v are 'still' unity vectors, so fill them into R
414  // (docu; JW 11/2002)
415  for (int i=0; i<3; i++) {
416  R_[i][0] = H0_[i];
417  R_[i][1] = V0_[i];
418  }
419 
420 #ifdef BIAS_DEBUG
421 
422  Vector3<double> sum(0.0, 0.0, 0.0), col1, col2, col3;
423  for (int i=0; i<3; i++){
424  sum[i] += R_[i][0] * R_[i][0] + R_[i][1] * R_[i][1] + R_[i][2] * R_[i][2];
425  col1[i] = R_[i][0];
426  col2[i] = R_[i][1];
427  col3[i] = R_[i][2];
428  }
429  if ( fabs(col1.ScalarProduct(col2))>1e-10 ||
430  fabs(col3.ScalarProduct(col2))>1e-10 ||
431  fabs(col1.ScalarProduct(col3))>1e-10 ){
432  BIASERR("warning, numerical instability in PMatrix::Decompose_(): "
433  << "R_ is nor orthogonal (not a rotation matrix), scalar "
434  << "products are: " << col1.ScalarProduct(col2) << "," <<
435  col3.ScalarProduct(col2) << "," << col1.ScalarProduct(col3));
436  }
437  if ( fabs(sum[0]-1.0)>1e-10 || fabs(sum[1]-1.0)>1e-10 ||
438  fabs(sum[2]-1.0)>1e-10 ){
439  BIASERR("warning, numerical instability in PMatrix::Decompose_(): "
440  << "R_ is not a orthonormal (not a rotation matrix) "
441  << "Vector lengthes are"<<sum[0] << "," << sum[1] << ","
442  << sum[2]);
443  }
444 
445 
446  // make backup of pmatrix fields for debug purposes
447  PConsistencyBackup_ = (*this);
448 #endif
449  IsDecomposed_ = true;
450  return decomposeresult;
451 }
452 
453 void PMatrix::
454 BackprojectByZDepth(const double& x,
455  const double& y,
456  const double& z_depth,
457  HomgPoint3D& res)
458 {
459  HomgPoint3D C;
460  GetC(C);
461 
462  HomgPoint2D p(x*z_depth, y*z_depth, z_depth);
463  p = GetK().Invert()*p;
464  p = GetR()*p;
465  res.Set(p[0]+C[0], p[1]+C[1], p[2]+C[2], C[3]);
466 }
467 
468 void PMatrix::BackprojectWorldCoo(const HomgPoint2D& point, double depth,
469  HomgPoint3D& res)
470 {
471  Vector3<double> ray;
472  HomgPoint3D C, hray;
473  if (GetC(C)!=0){
474  BIASERR("error getting C");
475  //BIASASSERT(false);
476  BIASABORT;
477  }
478  ray = GetNormRayWorldCoo(point);
479  hray.Set(depth*ray[0], depth*ray[1], depth*ray[2], 0.0);
480  res = C+hray;
481 }
482 
484  Matrix<double> Pinv;
485  GetPseudoInverse(Pinv);
486 
487  HomgPoint3D newPoint(Pinv * x);
488  newPoint.Homogenize();
489 
490  //// check if direction is the same as camera orientation
491  Vector3<double> viewray, center;
492  GetC(center);
493  viewray[0] = newPoint[0] - center[0];
494  viewray[1] = newPoint[1] - center[1];
495  viewray[2] = newPoint[2] - center[2];
496  // scalar product viewray with camera orientation
497  double dS = viewray[0] * (*this)[2][0] + viewray[1] * (*this)[2][1] +
498  viewray[2] * (*this)[2][2];
499  if (dS<0) {
500  // backprojected point is behind camera
501  newPoint[0] = center[0] - viewray[0];
502  newPoint[1] = center[1] - viewray[1];
503  newPoint[2] = center[2] - viewray[2];
504  }
505 
506  newPoint[3]=1; // there is the case that w=0, though other values are valid
507 
508  return newPoint;
509 }
510 
511 
512 
514 {
515  if (!IsDecomposed_) {
516  Decompose_();
517  } else {
518  // flag says: "matrix is decomposed!"
519 #ifdef BIAS_DEBUG
521 #endif
522  }
523  plane[0] = A_[0];
524  plane[1] = A_[1];
525  plane[2] = A_[2];
526  Vector3<double> PlaneVec(0.0, 0.0, 1.0);
527  Vector3<double> WorldPlaneVec;
528  R_.Mult(PlaneVec, WorldPlaneVec);
529  WorldPlaneVec += C_;
530  plane[3] = WorldPlaneVec.NormL2();
531 }
532 
534  HomgPlane3D plane;
535  GetImagePlane(plane);
536  return plane;
537 }
538 
540  HomgLine2D& intersection)
541 {
542  // this is just the way, to do: fast
543  // NormalVector = P.GetA()
544  // Transform Normal Vector to CameraCoo of this PMatrix
545  // R = GetR();
546  // NewA = R.TRanspose() * NormalVector
547  // intersection[0] = NewA[0];
548  // intersection[1] = NewA[1];
549  // intersection[2] = NewA[2] + NewA[3];
550 
551  int res = 0;
552  HomgPlane3D Plane = P.GetImagePlane();
553  HomgPlane3D TransformedPlane;
554  AffineTransf at;
556  if (GetR(R) !=0)
557  return -1;
558 // cerr << "Plane: " << Plane << endl;
559 // cerr << "R: " << R << endl;
560  R.TransposeIP();
561 // cerr << "R': " << R << endl;
562  at.SetAsRotationMatrix(R);
563 // cerr << "at: " << at << endl;
564  at.Mult(Plane, TransformedPlane);
565 // cerr << "TransfPlane: " << TransformedPlane << endl;
566 
567  double dot;
568  TransformedPlane.ScalarProduct(HomgPlane3D(0.0, 0.0, 1.0, 0.0), dot);
569  if ((dot < PMATRIX_EPSILON) && (dot > -PMATRIX_EPSILON)) {
570  res = -1;
571  } else {
572  intersection[0] = TransformedPlane[0];
573  intersection[1] = TransformedPlane[1];
574  intersection[2] = TransformedPlane[2] + TransformedPlane[3];
575  }
576 
577  return res;
578 }
579 
580 
582  const Matrix3x3<double>& R,
583  const Vector3<double>& C)
584 {
585  IsMetric_ = true;
586  R_ = R;
587  C_ = C;
588  K_ = K;
589  for (register int i=0; i<3; i++){
590  H0_[i] = R_[i][0];
591  V0_[i] = R_[i][1];
592  A_[i] = R_[i][2];
593  }
594  PMatrixBase::Compose(K, R, C);
595  for (unsigned int j=0; j<3; j++) {
596  for (unsigned int i=0; i<3; i++) {
597  Hinf_[i][j] = (*this)[i][j];
598  }
599  }
600  int res = Hinf_.InvertIP();
601  if (res!=0) {
602  BIASERR("error computing Hinf_.");
603  cout << "K: "<<K<<endl<<"R: "<<R<<endl<<"C: "<<C<<endl;BIASABORT; }
604 
605 #ifdef BIAS_DEBUG
606  // save the PMatrix fields
607  PConsistencyBackup_ = (*this);
608 #endif
609  IsDecomposed_=true;
610 
611  if (Svd_ != NULL) {
612  delete Svd_;
613  Svd_ = NULL;
614  }
615 }
616 
618  const Matrix3x3<double>& R,
619  const HomgPoint3D& C)
620 {
621  Vector3<PMATRIX_TYPE> cnew;
622  if (!C.IsAtInfinity()){
623  cnew.Set(C[0]/C[3], C[1]/C[3], C[2]/C[3]);
624  PMatrix::Compose(K, R, cnew);
625  for (unsigned int j=0; j<3; j++) {
626  for (unsigned int i=0; i<3; i++) {
627  Hinf_[i][j] = (*this)[i][j];
628  }
629  }
630  int hres = Hinf_.InvertIP();
631  if (hres!=0) BIASERR("error: unable to compute Hinf_.");
632 #ifdef BIAS_DEBUG
633  // save the PMatrix fileds
634  PConsistencyBackup_ = (*this);
635 #endif
636  IsDecomposed_ = true;
637  } else {
638  BIASERR("cannot compose camera at infinity");
639  }
640 }
641 
642 void PMatrix::
644  const Vector<double>& parametrization,
645  enum E_ParametrizationType param_type)
646 {
647  Vector3<double> C;
648  C.Set(parametrization[0], parametrization[1], parametrization[2]);
649  RMatrixBase R = Parametrization2R_(parametrization, param_type);
650 
651  // compute and set Hinf_, ....
652  Compose(K, R, C);
653 }
654 
657 {
658  Vector3<double> result = GetRayWorldCoo(point);
659  //cerr << "point: "<<point<<"\tresult: " << result <<endl;
660  return result / result.NormL2();
661 }
662 
663 
666 {
667  KMatrix Kinv;
668  Vector3<double> result;
669 
670  if (!IsDecomposed_){
671  Decompose_();
672 
673 //#ifdef BIAS_DEBUG
674 // BIASWARN("DBG decomposing P (for call in "__FILE__<<" : "<<__LINE__<<")" );
675 //#endif
676 
677  } else {
678  // flag says: "matrix is decomposed!"
679 #ifdef BIAS_DEBUG
681 #endif
682  }
683 
684  Kinv = K_.Invert();
685 
686  Kinv.Mult(point, result);
687 
688  return R_ * result;
689 }
690 
691 
692 
693 // JW 11/2002
694 int PMatrix::WriteCAHV_10(int cols, int rows, ostream & os)
695 {
696  if (cols<0 || cols>10000 || rows<0 || rows>10000 ) {
697  // Error: impossible image size (in pixel) given
698  BIASERR( " image cols x rows = "<<cols<<" x "<< rows
699  <<" is to small or to big!");
700  };
701 
702  Vector3<double> A0; // unit vector, direction of optical axis
703  Vector3<double> H0; // unit vector, spans horizontal pixel-axis
704  Vector3<double> V0; // unit vector, spans vertical pixe-axixs
705  //(iff there is skew then H0,V0 are NOT orthogonal!)
706 
707  Vector3<double> H; // Cunningham CAHV 1.0 format H vector
708  Vector3<double> V; // Cunningham CAHV 1.0 format V vector
709 
710  // direction of the optical axis:
711  // get the 3rd row of KR' which is P[2][0..2] and divide it by
712  // its norm to get a unit vector.
713  A0[0] = (*this)[2][0];
714  A0[1] = (*this)[2][1];
715  A0[2] = (*this)[2][2];
716  double Alength = sqrt ( A0.ScalarProduct(A0) ); // norm of A
717  A0 /= Alength; // normalize A to unit vector
718 
719  H0[0] = (*this)[0][0]; // get 1st row of KR' which is P[0][0..2]
720  H0[1] = (*this)[0][1];
721  H0[2] = (*this)[0][2];
722  H0 /= Alength; // scale H (A should be unit vector)
723 
724  V0[0] = (*this)[1][0]; // get the 2nd row of KR' which is P[1][0..2]
725  V0[1] = (*this)[1][1];
726  V0[2] = (*this)[1][2];
727  V0 /= Alength; // scale V (A should be unit vector)
728 
729  Vector3<double> TTh;
730  Vector3<double> TTv;
731  TTh = A0 * ((cols-1)/2.0);
732  TTv = A0 * ((rows-1)/2.0);
733  H = H0 - TTh;
734  V = V0 - TTv;
735 
736 
737  // get intrinsic parameters:
738  double imgCenterX = cols/2.0; // center of the image (not cols-1, see
739  // RK code (and example)
740  double imgCenterY = rows/2.0;
741  KMatrix K;
742  if (GetK(K) != 0)
743  return -1;
744  double opticalCenterX = K[0][2]; // optical center in pixel (cx=hx)
745  double opticalCenterY = K[1][2]; // (cy=hy)
746  double bxh = opticalCenterX - imgCenterX; // length (in pixel) from image
747  // center to optical center
748  double byh = opticalCenterY - imgCenterY;
749  double fx = K[0][0]; // focal length
750  double fy = K[1][1];
751  double skew = K[0][1]; // are the x/y axes skewed (=not orthogonal)
752  double sx = 1.0;
753  double sy = (fx/fy)*sx; // ratio of pixel size sx/sy
754 
755  // write CAHV decomposed P to file in special 'Cunningham CAHV 1.0 format:
756  Vector3<double> C;
757  if (GetC(C) !=0)
758  return -1;
759  os<<setprecision(12);
760  os <<";CAHV 1.0" << endl;
761  os <<";Generated by PMatrix::WriteCAHV_10 (JW 2002)" << endl;
762  os <<"; Cx Cy Cz"<<endl;
763  os <<C[0]<<" "<<C[1]<<" "<<C[2]<<endl;
764  os <<"; Ax Ay Az"<<endl;
765  os <<A0[0]<<" "<<A0[1]<<" "<<A0[2]<<endl;
766  os <<"; Hx Hy Hz"<<endl;
767  os <<H[0]<<" "<<H[1]<<" "<<H[2]<<endl;
768  os <<"; Vx Vy Vz"<<endl;
769  os <<V[0]<<" "<<V[1]<<" "<<V[2]<<endl;
770 
771  os <<"; Radialdistortion rd "<<endl;
772  os <<"0.0"<<endl; // fix to zero because it's not used by following programs
773  os <<"; Pixelsize sx (fixed) sy (ratio)"<<endl;
774  os <<sx<<" "<<sy<<endl;
775  os <<"; Image-size: colums rows"<<endl;
776  os <<cols<<" "<<rows<<endl;
777  os <<"; Internal parameters:"<<endl;
778  os <<"; fx = "<< fx <<" fy = "<< fy <<" skew = "<< skew << endl;
779  os <<"; hx = "<< bxh<<" hy = "<< byh << endl;
780 
781  return -1;
782 }
783 
784 
785 
786 
787 // JW 06/2003
788 // unfortunately not const because missing consts in decompose etc...
789 float PMatrix::GetFieldOfView(const unsigned int dimX,
790  const unsigned int dimY,
791  const bool optmin)
792 {
793  BIAS::Vector3<double> nw, vec; // two oposing image corners
794  BIAS::HomgPoint2D p2d = BIAS::HomgPoint2D( 0.0, 0.0, 1.0); // NW corner
795  nw = this->GetNormRayWorldCoo( p2d ); // wcs vector
796 
797  if (!optmin) {
798  // max. angle
799  p2d[0]=(double)dimX; // SE corner
800  p2d[1]=(double)dimY; //w is still 1
801  } else if (dimX<dimY) {
802  // min angle X
803  // optmin and dimX is smaller dimY --> SW is min
804  p2d[0]=(double)dimX; // y,w are still 0,1
805  } else {
806  // min angle Y
807  // optmin and dimY is smaller
808  p2d[1]=dimY; // x,w are still 0,1
809  };
810 
811  // second vector (SE, SW or NE)
812  vec = this->GetNormRayWorldCoo( p2d ); // wcs vector
813  float cosAlpha = float(nw.ScalarProduct(vec));
814  float alpha = acos( cosAlpha );
815  // cout<<"DBG fov="<<alpha<<" rad. (= "<<alpha*180.0/M_PI<<" degree)."<<endl;
816  return alpha;
817 }
818 
819 
820 /** @return field of view in y-direction in rad
821  this routine is complexer than expected...
822  ... because the principal point may *not* be within camera center.
823  HACK/FIXME/TODO:
824  \todo not in general correct impl. !!!
825  the principal may converge the view -> what is the field of view?
826  (JW 09/2003)
827 */
828 float PMatrix::GetFieldOfViewY(const unsigned int dimX,
829  const unsigned int dimY,
830  const bool & compY) {
831  HomgPoint2D north2d, south2d;
832  // set the 2dimage coord used to determine angle:
833  if (compY) {
834  // vertical fov (north->south)
835  north2d = HomgPoint2D(0.5*(double)dimX, 0.0, 1.0); // N
836  south2d = HomgPoint2D(0.5*(double)dimX, (double)dimY, 1.0); // S
837  } else {
838  // horizontal fov (west -> east)
839  north2d = HomgPoint2D(0.0, 0.5*(double)dimY, 1.0); // W
840  south2d = HomgPoint2D((double)dimX, 0.5*(double)dimY, 1.0); //E
841  };
842  // get corresponding direction
843  Vector3<double> north3d = this->GetNormRayWorldCoo( north2d );
844  Vector3<double> south3d = this->GetNormRayWorldCoo( south2d );
845  north3d.Normalize();
846  south3d.Normalize();
847  // get angle between
848  float cosAlpha = float(north3d.ScalarProduct(south3d));
849  float alpha = acos( cosAlpha );
850  //cout<<"DBG fovY="<<alpha<<" rad. (= "<<alpha*180.0/M_PI<<" degree)."<<endl;
851  return alpha;
852 }
853 
855  Vector3<PMATRIX_TYPE> &a) const {
856  for(int i=0; i<3; i++)
857  for(int j=0; j<4; j++)
858  if ( j==3 )
859  a[i] = (*this)[i][j];
860  else
861  A[i][j] = (*this)[i][j];
862 }
863 
864 
866 {
868  GetCanonicalH(ProjH);
869  return ProjH;
870 }
871 
875  DecomposeAa(A,a);
876  SVD svd;// SVD svd((Matrix<PMATRIX_TYPE>)A);
877 
878  //Matrix3x3<PMATRIX_TYPE> PseudoInv(svd.Invert());
880  Vector<PMATRIX_TYPE> x;/* Vector3<PMATRIX_TYPE> x(svd.solve(a));*/
881  Matrix<PMATRIX_TYPE> A2(A);
882  Vector<PMATRIX_TYPE> a2(a);
883  svd.Solve(A2,a2, x);
884 
885  ProjH[0][0] = PseudoInv[0][0];
886  ProjH[0][1] = PseudoInv[0][1];
887  ProjH[0][2] = PseudoInv[0][2];
888  ProjH[1][0] = PseudoInv[1][0];
889  ProjH[1][1] = PseudoInv[1][1];
890  ProjH[1][2] = PseudoInv[1][2];
891  ProjH[2][0] = PseudoInv[2][0];
892  ProjH[2][1] = PseudoInv[2][1];
893  ProjH[2][2] = PseudoInv[2][2];
894 
895  ProjH[3][0] = 0;
896  ProjH[3][1] = 0;
897  ProjH[3][2] = 0;
898  ProjH[3][3] = 1;
899 
900  ProjH[0][3] = -x[0];
901  ProjH[1][3] = -x[1];
902  ProjH[2][3] = -x[2];
903 }
904 
905 int PMatrix::LoadBBC(const std::string &filename, const double& addppx,
906  const double& addppy) {
907  ifstream ifs(filename.c_str());
908  if (!ifs) {
909  perror(filename.c_str());
910  return -1;
911  }
912  int thereturn = BBCIn(ifs, addppx, addppy);
913  ifs.close();
914  return thereturn;
915 }
916 
917 int PMatrix::BBCIn(ifstream &ifs, const double& addppx,
918  const double& addppy) {
919  Vector3<double> BBCC(0.0), BBCA(0.0), BBCUp(0.0);
920  unsigned int BBCWidth=0, BBCHeight=0;
921  // Pixelsize and FocalLength are in [m] (meter)
922  double BBCPxSizeX=0, BBCPxSizeY=0, BBCCxShift=0,
923  BBCCyShift=0,BBCFocalLength=0;
924  string key;
925  istringstream iss;
926  char linebuf[200];
927  while (ifs.getline(linebuf,200)) {
928 // cout <<"read line: "<<linebuf<<endl;
929  iss.clear();
930  iss.str(linebuf);
931  iss >> key;
932  if (key == "CVec") iss >> BBCC[0]>> BBCC[1]>> BBCC[2];
933  if (key == "AVec") iss >> BBCA[0]>> BBCA[1]>> BBCA[2];
934  if (key == "UpVec") iss >> BBCUp[0]>> BBCUp[1]>> BBCUp[2];
935  if (key == "Width") iss >> BBCWidth;
936  if (key == "Height") iss >> BBCHeight;
937  if (key == "PixelSizeX") iss >> BBCPxSizeX;
938  if (key == "PixelSizeY") iss >> BBCPxSizeY;
939  if (key == "CenterPointShiftX") iss >> BBCCxShift;
940  if (key == "CenterPointShiftY") iss >> BBCCyShift;
941  if (key == "FocalLength") iss >> BBCFocalLength;
942  if (key == "}") break; // end of entry
943  }
944 
945  //cout <<"BBC CVec: "<<BBCC<<endl;
946  // cout <<"BBC AVec: "<<BBCA<<" with norm="<< BBCA.NormL2()<<endl;
947  // cout <<"BBC UpVec: "<<BBCUp<<" with norm="<< BBCUp.NormL2()<<endl;
948  // cout <<"BBC Width: "<<BBCWidth<<endl;
949  // cout <<"BBC Height: "<<BBCHeight<<endl;
950  // cout <<"BBC PixelSizeX: "<<BBCPxSizeX<<endl;
951  // cout <<"BBC PixelSizeY: "<<BBCPxSizeY<<endl;
952  // cout <<"BBC CenterPointShiftX: "<<BBCCxShift<<endl;
953  // cout <<"BBC CenterPointShiftY: "<<BBCCyShift<<endl;
954  // cout <<"BBC FocalLength: "<<BBCFocalLength<<endl;
955 
956  Matrix3x3<double> K,R;
957 
958  K.SetIdentity();
959  K[0][0] = BBCFocalLength / BBCPxSizeX; // fx
960  K[1][1] = BBCFocalLength / BBCPxSizeY; // fy
961 
962  // compute principle point, addppx and addppy are useful in case
963  // the centerpointshift is determined separately
964  K[0][2] = double(BBCWidth-1)/2.0 + (BBCCxShift+addppx) / BBCPxSizeX;
965  K[1][2] = double(BBCHeight-1)/2.0 + (BBCCyShift+addppy) / BBCPxSizeY;
966 
967  Vector3<double> V,C,A,H;
968  V = -1.0 * BBCUp;
969 
970  C[0] = BBCC[0];
971  C[1] = BBCC[1];
972  C[2] = BBCC[2];
973 
974  A[0] = BBCA[0];
975  A[1] = BBCA[1];
976  A[2] = BBCA[2];
977 
978 
979  H = V.CrossProduct(A);
980 
981  for (unsigned int i=0;i<3;i++){
982  R[i][0] = H[i];
983  R[i][1] = V[i];
984  R[i][2] = A[i];
985  }
986 
987  // cout <<"K: "<<K<<endl;
988  //cout <<"R: "<<R<<" with det "<<R.det()<<endl;
989  //cout<<"PMatrix compile time is "<<__TIME__<<endl;
990 
991  Compose(K,R,C);
992 
993  return 0;
994 }
995 
996 
997 #ifdef BIAS_HAVE_XML2
998 
999 int PMatrix::XMLGetClassName(std::string& TopLevelTag,
1000  double& Version) const {
1001  TopLevelTag = "PMatrix";
1002  Version = 0.1;
1003  return 0;
1004 }
1005 
1006 int PMatrix::XMLOut(const xmlNodePtr Node, XMLIO& XMLObject) const {
1007  if (IsMetric_) {
1008 #ifdef BIAS_DEBUG
1009  if (!IsDecomposed_) {
1010  BIASERR("Undecomposed PMatrix cannot be metric !!!");
1011  BIASABORT;
1012  }
1013 #endif
1014  xmlNodePtr childNode;
1015  //XMLObject.addAttribute(Node, "Metric", "true");
1016  XMLObject.addAttribute(Node, "Metric", true);
1017 
1018  // K
1019  childNode = XMLObject.addChildNode(Node,"Calibration");
1020  stringstream streamK, streamR;
1021  streamK << std::setprecision(STREAM_PRECISION);
1022  for (unsigned int i=0; i<9; i++) {
1023  streamK << (double) K_.GetData()[i] <<" ";
1024  }
1025  XMLObject.addContent(childNode, streamK.str());
1026 
1027  // R
1028  childNode = XMLObject.addChildNode(Node,"Rotation");
1029  streamR << std::setprecision(STREAM_PRECISION);
1030  for (unsigned int i=0; i<9; i++) {
1031  streamR << (double) R_.GetData()[i] <<" ";
1032  }
1033  XMLObject.addContent(childNode, streamR.str());
1034 
1035  // C
1036  childNode = XMLObject.addChildNode(Node,"Center");
1037  XMLObject.addAttribute(childNode, "x", C_[0]);
1038  XMLObject.addAttribute(childNode, "y", C_[1]);
1039  XMLObject.addAttribute(childNode, "z", C_[2]);
1040  } else {
1041  // not metric
1042  xmlNodePtr theNode;
1043  //XMLObject.addAttribute(Node, "Metric", "false");
1044  XMLObject.addAttribute(Node, "Metric", false);
1045  theNode = XMLObject.addChildNode(Node,"DataFields");
1046  stringstream datastream;
1047  datastream << std::setprecision(STREAM_PRECISION);
1048  for (unsigned int i=0; i<12; i++) {
1049  datastream << (double) GetData()[i] <<" ";
1050  }
1051  XMLObject.addContent(theNode, datastream.str());
1052  }
1053  return 0;
1054 }
1055 
1056 int PMatrix::XMLIn(const xmlNodePtr Node, XMLIO& XMLObject) {
1057  xmlNodePtr childNode;
1058  string sMetric = XMLObject.getAttributeValueString(Node, "Metric");
1059  IsMetric_ = sMetric == "true";
1060  if (IsMetric_) {
1061  // K
1062  if ((childNode = XMLObject.getChild(Node, "Calibration"))==NULL) {
1063  BIASERR("error in xml structure");
1064  return -1;
1065  }
1066  // get data fields
1067  stringstream ssCalibration(XMLObject.getNodeContentString(childNode));
1068  unsigned int CurrentData = 0;
1069  double* pData = K_.GetData();
1070  while (ssCalibration.good() && CurrentData<9) {
1071  ssCalibration >> (pData[CurrentData++]);
1072  }
1073  if (CurrentData<9) {
1074  // reached end of stream before expected end of data
1075  BIASERR("Error parsing XML code ...");
1076  return -1;
1077  }
1078  //cout <<"K is "<<K_<<endl;
1079 
1080  // R
1081  if ((childNode = XMLObject.getChild(Node, "Rotation"))==NULL) {
1082  BIASERR("error in xml structure");
1083  return -1;
1084  }
1085  // get data fields
1086  stringstream ssRotation(XMLObject.getNodeContentString(childNode));
1087  CurrentData = 0;
1088  pData = R_.GetData();
1089  while (ssRotation.good() && CurrentData<9) {
1090  ssRotation >> (pData[CurrentData++]);
1091  }
1092  if (CurrentData<9) {
1093  // reached end of stream before expected end of data
1094  BIASERR("Error parsing XML code ...");
1095  return -1;
1096  }
1097  //cout <<"R is "<<R_<<endl;
1098 
1099  // C
1100  if ((childNode = XMLObject.getChild(Node, "Center"))==NULL) {
1101  // reached end of stream before expected end of data
1102  BIASERR("Error parsing XML code ...");
1103  return -1;
1104  }
1105  C_[0] = XMLObject.getAttributeValueDouble(childNode, "x");
1106  C_[1] = XMLObject.getAttributeValueDouble(childNode, "y");
1107  C_[2] = XMLObject.getAttributeValueDouble(childNode, "z");
1108  //cout <<"C is "<<C_<<endl;
1109 
1110  // Recompose P
1111  Compose(K_, R_, C_);
1112  //cout <<"R after Compose is "<<R_<<endl;
1113  IsMetric_ = true;
1114  } else {
1115  // in the non-metric case we just have 12 values to construct P
1116  if ((childNode = XMLObject.getChild(Node, "DataFields"))==NULL) {
1117  BIASERR("error in xml structure");
1118  return -1;
1119  }
1120 
1121  // get data fields
1122  stringstream ssData(XMLObject.getNodeContentString(childNode));
1123  unsigned int CurrentData=0;
1124  double* pData = GetData();
1125 
1126  while (ssData.good() && CurrentData<12) {
1127  ssData >> (pData[CurrentData++]);
1128  }
1129  if (CurrentData<12) {
1130  // reached end of stream before expected end of data
1131  BIASERR("Error parsing XML code ...");
1132  return -1;
1133  }
1135  IsMetric_ = false;
1136  }
1137 
1138 
1139  return 0;
1140 }
1141 
1142 #endif // BIAS_HAVE_XML2
1143 
1144 
1145 
1146 bool PMatrix::Save(const std::string & filename)
1147 {
1148  std::ofstream fs( filename.c_str() );
1149  if (!fs) {
1150  return false; // error, could not open file.
1151  } else {
1152  fs<<(*this);
1153  fs<<"# Covariance [x y z r1 r2 r3] : "<<endl;
1154  fs<<Covariance_<<endl;
1155  if (IsMetric_) {
1156  fs<<"# R: "<<R_<<endl;
1157  fs<<"# C: "<<C_<<endl;
1158  fs<<"# K: "<<K_<<endl;
1159  }
1160  fs.close();
1161  };
1162  return true;
1163 }
1164 
1165 double PMatrix::GetProjectionError(const std::vector<BIAS::HomgPoint2D>& points2D, const std::vector<BIAS::HomgPoint3D>& points3D){
1166 
1167  if (points2D.size() != points3D.size()) {
1168  // Error: impossible sizes of correspondence
1169  BIASERR( "Vectors have different sizes " << points2D.size() <<" "<< points3D.size() << endl);
1170  return -1.0;
1171  }
1172  double projectionError = 0.0;
1173  HomgPoint2D temp, temp2;
1174  for(unsigned int i = 0; i < points2D.size(); i++){
1175  temp = HomgPoint2D((*this) * points3D[i]);
1176  temp.Homogenize();
1177  temp2 = points2D[i];
1178  projectionError += temp.DistanceSquared(temp2);
1179  }
1180  projectionError /= points2D.size();
1181 
1182  return projectionError;
1183 }
1184 
1185 } // end namespace BIAS
Matrix3x4< double > PConsistencyBackup_
backup of P at time of last decomposition to check whether decomposition is still valid ...
Definition: PMatrix.hh:472
Vector< double > GetNullvector(const int last_offset=0)
return one of the nullvectors.
Definition: SVD.hh:404
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
Definition: XMLIO.cpp:156
bool IsDecomposed_
tells us whether we have a chached decomposition with C,A,...
Definition: PMatrix.hh:479
Vector3< double > GetRayWorldCoo(const HomgPoint2D &point)
returns vector from C to point, w of point determines ray length analytical inverse of K is used ...
Definition: PMatrix.cpp:665
Matrix4x4< PMATRIX_TYPE > GetCanonicalH() const
Get the projective homography matrix so that P * H = [ I | 0 ].
Definition: PMatrix.cpp:865
PMatrixBase & operator=(const PMatrixBase &mat)
Definition: PMatrixBase.hh:233
KMatrix K_
camera calibration matrix (intrinsic parameter)
Definition: PMatrix.hh:466
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
void SetAsRotationMatrix(Matrix3x3< double > &R)
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
void TransposeIP()
tranpose this matrix &quot;in place&quot; example: 0 1 2 –&gt; 0 3 6 3 4 5 –&gt; 1 4 7 6 7 8 –&gt; 2 5 8 ...
Definition: Matrix3x3.hh:385
Subscript num_cols() const
Definition: cmat.h:320
Vector< double > Solve(const Vector< double > &y) const
Definition: SVD.cpp:135
virtual ~PMatrix()
destructor untested (04/17/2002)
Definition: PMatrix.cpp:45
int MakeSVD_()
Definition: PMatrix.hh:548
HomgPoint3D BackprojectPseudoinverse(const HomgPoint2D &x)
Returns a homogenized 3D point X on the viewray of x, which always lies in front of the camera(this i...
Definition: PMatrix.cpp:483
int Decompose_()
Computes K,R,C, assuming a metric PMatrix P = K[R^T | -R^T * C] with K[0][1]=0 (zero skew) and K[2][2...
Definition: PMatrix.cpp:318
void CheckSVD_()
check if SVD is still valid
Definition: PMatrix.hh:564
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 ScalarProduct(const Vector3< T > &argvec, T &result) const
scalar product (=inner product) of two vectors, storing the result in result
Definition: Vector3.hh:603
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
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
Definition: HomgPoint2D.hh:215
int WriteCAHV_10(int cols, int rows, std::ostream &os=std::cout)
write the CAHV decomposition of this P matrix in CAHV 1,0 format to stream os (see RK&#39;s/TNT CAHV1...
Definition: PMatrix.cpp:694
KMatrix GetK()
Definition: PMatrix.hh:168
Vector3< double > V0_
unit vector in wcs assigning the direction of the vertical axis of the image plane ...
Definition: PMatrix.hh:460
void Homogenize()
homogenize class data member elements to W==1 by divison by W
Definition: HomgPoint3D.hh:308
Matrix3x3< double > R_
rotation matrix (intrinsic parameter)
Definition: PMatrix.hh:465
Matrix< double > Covariance_
Definition: PMatrix.hh:476
float GetFieldOfViewY(const unsigned int dimX, const unsigned int dimY, const bool &compY=true)
Definition: PMatrix.cpp:828
E_ParametrizationType
description of supported parametrization types
Definition: PMatrixBase.hh:166
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
specialization of XML write function
Definition: PMatrix.cpp:1006
int BBCIn(std::ifstream &ifs, const double &AddCenterPointShiftX=0.0, const double &AddCenterPointShiftY=0.0)
Load next piece of calibration data from an open BBC-Free-D file.
Definition: PMatrix.cpp:917
double GetProjectionError(const std::vector< BIAS::HomgPoint2D > &points2D, const std::vector< BIAS::HomgPoint3D > &points3D)
returns average squared projection Error
Definition: PMatrix.cpp:1165
SVD * Svd_
(for decomposition, docu: JW 11/2002)
Definition: PMatrix.hh:467
BIAS::Vector3< double > GetH()
Definition: PMatrix.cpp:256
std::string getAttributeValueString(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:716
int LoadBBC(const std::string &filename, const double &AddCenterPointShiftX=0.0, const double &AddCenterPointShiftY=0.0)
Load calibration data file from BBC-Free-D system.
Definition: PMatrix.cpp:905
void Mult(Vector4< double > &argv, Vector4< double > &destv)
args must be of type Vector4&lt;double&gt; because this should work not only for HomgPoint3D but also for H...
Matrix3x3< double > GetR()
Definition: PMatrix.hh:161
void addContent(const xmlNodePtr Node, const std::string &Content)
Add content to a node.
Definition: XMLIO.cpp:254
void SetZero()
Sets all values to zero.
Definition: Matrix.hh:856
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
float GetFieldOfView(const unsigned int dimX, const unsigned int dimY, const bool optmin=true)
Definition: PMatrix.cpp:789
HomgPlane3D GetImagePlane()
calls the above
Definition: PMatrix.cpp:533
void Mult(const Vector3< T > &argvec, Vector3< T > &destvec) const
matrix - vector multiplicate this matrix with Vector3, storing the result in destvec calculates: dest...
Definition: Matrix3x3.hh:302
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
BIAS::Vector3< double > GetV()
Definition: PMatrix.cpp:281
Matrix< double > GetV() const
return V
Definition: SVD.hh:396
int GetInverse(Matrix3x3< T > &inv) const
Matrix inversion: inverts this and stores resulty in argument inv.
Definition: Matrix3x3.cpp:373
const Matrix< double > & GetVT() const
return VT (=transposed(V))
Definition: SVD.hh:177
virtual int XMLGetClassName(std::string &TopLevelTag, double &Version) const
specialization of XML block name function
Definition: PMatrix.cpp:999
void InvalidateDecomposition()
to re-Decompose_() after filling with data use this.
Definition: PMatrix.hh:499
int GetNullVector(HomgPoint3D &C)
this is another way of getting C, especially interesting for non-metric cameras
Definition: PMatrix.cpp:137
RMatrixBase Parametrization2R_(const Vector< double > &parametrization, const enum E_ParametrizationType param_type) const
Definition: PMatrixBase.cpp:97
const Vector< double > & GetS() const
return S which is a vector of the singular values of A in descending order.
Definition: SVD.hh:167
a line l = (a b c)^T is a form of the implicit straight line equation 0 = a*x + b*y + c if homogenize...
Definition: HomgLine2D.hh:48
PMATRIX_TYPE * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
Definition: Matrix.hh:185
bool IsAtInfinity() const
Definition: HomgPoint3D.hh:398
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrixBase.hh:74
int GetIntersectionOfImagePlanes(PMatrix &P, HomgLine2D &intersection)
return line resulting of intersection of the two image planes in pixel coordinates of this camera ret...
Definition: PMatrix.cpp:539
void ScalarProduct(const Vector4< T > &argvec, T &result) const
scalar product (=inner product) of two vectors, storing the result in result
Definition: Vector4.hh:475
bool Save(const std::string &filename)
Definition: PMatrix.cpp:1146
double getAttributeValueDouble(const xmlAttrPtr Attribute) const
Definition: XMLIO.cpp:736
const Matrix< double > & GetU() const
return U U is a m x m orthogonal matrix
Definition: SVD.hh:187
int GetHinf(BIAS::Matrix3x3< double > &Hinf)
Definition: PMatrix.cpp:151
Matrix< double > Invert()
returns pseudoinverse of A = U * S * V^T A^+ = V * S^+ * U^T
Definition: SVD.cpp:214
Vector3< double > GetNormRayWorldCoo(const HomgPoint2D &point)
returns normed vector from C to point analytical inverse of K is used
Definition: PMatrix.cpp:656
void DecomposeAa(BIAS::Matrix3x3< PMATRIX_TYPE > &A, BIAS::Vector3< PMATRIX_TYPE > &a) const
decompose the P-matrix to [ A | a ] where A is a 3x3-matrix and a is a 3-vector.
Definition: PMatrix.cpp:854
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
Vector3< double > C_
camera center in wcs (extrinsic parameter)
Definition: PMatrix.hh:448
BIAS::Vector3< double > GetA()
returns the unit vector A which is the normal vector to the image plane in world coordinates.
Definition: PMatrix.cpp:304
void BackprojectWorldCoo(const HomgPoint2D &point, double depth, HomgPoint3D &res)
returns a 3D point res which is located depth away from center of projection in direction given by po...
Definition: PMatrix.cpp:468
Matrix3x4< double > PConsistencyBackupSVD_
Definition: PMatrix.hh:473
Implements a 3D rotation matrix.
Definition: RMatrixBase.hh:44
void Compose(const Matrix3x3< PMATRIX_TYPE > &K, const Matrix3x3< PMATRIX_TYPE > &R, const Vector3< PMATRIX_TYPE > &C)
composes this from K, R and C using P = [ K R&#39; | -K R&#39; C ] with R&#39; = transpose(R) ...
Definition: PMatrixBase.cpp:34
Vector3< double > A_
unit vector in wcs assigning the direction of the optical axis
Definition: PMatrix.hh:452
int InvertIP()
In place matrix conversion.
Definition: Matrix3x3.cpp:420
Subscript num_rows() const
Definition: cmat.h:319
BIAS::Vector3< double > GetC()
computes translation vector origin world coo -&gt; origin camera coo (center), uses decomposition, which is cached
Definition: PMatrix.cpp:182
bool IsMetric_
tells us whether we have an arbitrary 3x4 matrix or a P which is exactly a composition of P = K * R [...
Definition: PMatrix.hh:484
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
void BackprojectByZDepth(const double &x, const double &y, const double &z_depth, HomgPoint3D &res)
Inverts the PMatrix application to a 3D point whose z-component in cameracoordinates and its imagepoi...
Definition: PMatrix.cpp:454
int GetPseudoInverse(BIAS::Matrix< double > &Pinv)
returns 4x3 pseudo inverse
Definition: PMatrix.cpp:113
void GetSVD(Matrix< double > &U, Vector< double > &S, Matrix< double > &VT)
Returns SVD of this.
Definition: PMatrix.cpp:310
virtual int XMLIn(const xmlNodePtr Node, XMLIO &XMLObject)
specialization of XML read function
Definition: PMatrix.cpp:1056
KMatrix Invert() const
returns analyticaly inverted matrix
Definition: KMatrix.cpp:31
void CheckDecomposition_()
check if Decomposition is still valid
Definition: PMatrix.hh:576
Vector3< T > & Normalize()
normalize this vector to length 1
Definition: Vector3.hh:663
HOMGPOINT2D_TYPE DistanceSquared(const HomgPoint2D &point) const
Definition: HomgPoint2D.hh:377
std::string getNodeContentString(const xmlNodePtr Node) const
Get the content of a given Node.
Definition: XMLIO.cpp:554
void GetImagePlane(HomgPlane3D &plane)
returns image plane in world coordinates
Definition: PMatrix.cpp:513
PMatrix & operator=(const PMatrix &mat)
assignment operator
Definition: PMatrix.cpp:84
Vector3< double > H0_
unit vector in wcs assigning the direction of the horizontal axis of the image plane ...
Definition: PMatrix.hh:456
double NormL2() const
the L2 norm sqrt(a^2 + b^2 + c^2)
Definition: Vector3.hh:633
class BIASGeometryBase_EXPORT HomgPoint2D
void Compose(const Matrix3x3< double > &K, const Matrix3x3< double > &R, const Vector3< double > &C)
composes this from K, R and C using P = [ K R&#39; | -K R&#39; C ] with R&#39; = transpose(R) ...
Definition: PMatrix.cpp:581
last line of an affine transformation in 3d space is always 0 0 0 1 and can therefor be droped from t...
Definition: AffineTransf.hh:44
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429
Matrix3x3< double > Hinf_
Hinfinity.
Definition: PMatrix.hh:463
PMatrix & newsize(int rows, int cols)
setting a new size different from 3x4 is not allowed for the fixed size P-Matrix overloads the genera...
Definition: PMatrix.cpp:61
A homogeneous plane (in P^3) All points X on the plane p fulfill p &#39; * X = 0.
Definition: HomgPlane3D.hh:46