Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleTriangulateOptimal.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  @example ExampleTriangulateOptimal.cpp
27  @relates Triangulation
28  @brief example demonstrating triangulation
29  @ingroup g_examples
30  @author woelk 08/2004
31 */
32 
33 #include <Geometry/Triangulation.hh>
34 #include <Base/Math/Random.hh>
35 #include <Base/Debug/TimeMeasure.hh>
36 #include <Base/Geometry/RMatrixBase.hh>
37 #include <Base/Geometry/KMatrix.hh>
38 #include <Geometry/PMatrix.hh>
39 
40 using namespace BIAS;
41 using namespace std;
42 
43 
44 int main(int argc, char *argv[])
45 {
46  Triangulation tri;
47  // tri.AddDebugLevel(D_TR_OPT);
48  Random ran;
49  KMatrix K;
50  RMatrixBase R0, R1;
51  PMatrix P0, P1;
52  Vector3<double> C0, C1, r0, r1;
53  Vector3<double> eucl3d;
54  HomgPoint3D p3d, tp3d;
55  HomgPoint2D p0, p1, gtp0, gtp1, np0, np1;
56  double sigma=2.5;
57  int num=100, nump=10; // test num times
58  bool read=false, finished=false;
59  double osum=0.0, ksum=0.0, ssum=0.0, osum2=0.0, ksum2=0.0, ssum2=0.0;
60  int onum=0, knum=0, snum=0;
61 
62  TimeMeasure ot, kt, st;
63 
64  if (argc==2) {
65  read=true;
66  }
67  if (read){
68  tri.AddDebugLevel("D_TR_OPT");
69  num=1;
70  }
71 
72  K.SetIdentity();
73  K[0][0]=K[1][1]=840.0;
74  K[0][2]=320.0;
75  K[1][2]=240.0;
76 
77  for (int p=0; p<nump; p++){
78  r0.Set(ran.GetNormalDistributed(0.0, 0.1),
79  ran.GetNormalDistributed(0.0, 0.1),
80  ran.GetNormalDistributed(0.0, 0.1));
81  r1.Set(ran.GetNormalDistributed(0.0, 0.5),
82  ran.GetNormalDistributed(0.0, 0.5),
83  ran.GetNormalDistributed(0.0, 0.5));
84 
85  R0.SetXYZ(r0);
86  R1.SetXYZ(r1);
87 
88  C0.Set(ran.GetNormalDistributed(0.0, 0.1),
89  ran.GetNormalDistributed(0.0, 0.1),
90  ran.GetNormalDistributed(0.0, 0.1));
91  C1.Set(ran.GetNormalDistributed(1.0, 0.1),
92  ran.GetNormalDistributed(0.0, 0.1),
93  ran.GetNormalDistributed(0.0, 0.1));
94 
95 
96  if (read){
97  ifstream is(argv[1]);
98  is >> K >> R0 >> R1 >> C0 >> C1 >> np0 >> np1 >> p3d >> gtp0 >> gtp1;
99  is.close();
100  cout << K << R0 << R1 << C0 << C1 << np0 << np1 << p3d<<gtp0<<gtp1<<endl;
101  }
102 
103  P0.Compose(K, R0, C0);
104  P1.Compose(K, R1, C1);
107 
108  for (int i=0; i<num; i++){
109  p3d.Set(ran.GetUniformDistributed(-5.0, 5.0),
110  ran.GetUniformDistributed(-5.0, 5.0),
111  ran.GetUniformDistributed(4.0, 10.0));
112  gtp0=P0*p3d;
113  gtp1=P1*p3d;
114 
115  gtp0.Homogenize();
116  gtp1.Homogenize();
117 
118  if (num<5){
119  cout << "\ntrue 3d point : "<<p3d<<endl;
120  cout << "true correspondences : "<<gtp0<<" <--> "<<gtp1<<endl;
121  }
122 
123  if (read){
124  p0=np0;
125  p1=np1;
126  } else {
127  p0=gtp0;
128  p1=gtp1;
129  p0[0]+=ran.GetNormalDistributed(0.0, sigma);
130  p0[1]+=ran.GetNormalDistributed(0.0, sigma);
131  p1[0]+=ran.GetNormalDistributed(0.0, sigma);
132  p1[1]+=ran.GetNormalDistributed(0.0, sigma);
133  np0=p0;
134  np1=p1;
135  }
136 
137  if (num<5){
138  cout << "noisy correspondences (sigma = "<<setw(5)<<sigma<<") : "<<p0<<" <--> "
139  <<p1<<endl;
140  }
141  ot.Start();
142  if (tri.Optimal(P0, P1, p0, p1, tp3d)==0){
143  ot.Stop();
144  if (num<5){
145  if (tri.DebugLevelIsSet("D_TR_OPT")){
146  cout << "true 3d point : "<<p3d<<endl;
147  cout << "true correspondences : "<<gtp0<<" <--> "<<gtp1<<endl;
148  cout << "noisy correspondences (sigma = "<<setw(5)<<sigma<<") : "<<np0<<" <--> "
149  <<np1<<endl;
150  }
151  cout << "corrected correspondences : "<<p0<<" <--> "<<p1<<endl;
152  p0=P0*tp3d; p0.Homogenize();
153  p1=P1*tp3d; p1.Homogenize();
154  cout << "projected triangulated point : "<<p0<<" <--> "<<p1<<endl;
155  cout << "optimal triangulated 3D point : "<<tp3d<<endl;
156 
157 
158  }
159  cout << "optimal euclidean dist. in 3D : "<<(tp3d-p3d).NormL2()
160  <<"\teucl. dist in images: "<<(np0-p0).NormL1()<<" "
161  <<(np1-p1).NormL1()<<endl;
162  osum+=(tp3d-p3d).NormL2();
163  osum2+=(tp3d-p3d).NormL2()*(tp3d-p3d).NormL2();
164  onum++;
165  if ((tp3d-p3d).NormL2()>1.0){
166  cout << K << R0 << R1 << C0 << C1 << np0 << np1<<p3d<<gtp0<<gtp1<<endl;
167  ofstream of("deb.txt");
168  of << K << R0 << R1 << C0 << C1 << np0 << np1 << p3d<<gtp0<<gtp1<<endl;
169  of.close();
170  // finished=true;
171  // /*
172  // ifstream is("deb.txt");
173  // is >> K >> R0 >> R1 >> C0 >> C1 >> np0 >> np1 >> p3d >> gtp0 >> gtp1;
174  // is.close();
175  // cout << K << R0 << R1 << C0 << C1 << np0<<np1<<p3d<<gtp0<<gtp1<<endl;
176  // */
177  }
178  } else {
179  ot.Stop();
180  cout << "optimal triangulation failed\n";
181  }
182 
183  p0=np0;
184  p1=np1;
185  kt.Start();
186  if (tri.Triangulate(P0, P1, p0, p1, eucl3d)>=0){
187  tp3d.Set(eucl3d);
188  kt.Stop();
189  if (num<5){
190  cout << "kanatani triangulated 3D point : "<<tp3d<<endl;
191  }
192  cout << "kanatani euclidean dist. in 3D: "<<(tp3d-p3d).NormL2()<<endl;
193  ksum+=(tp3d-p3d).NormL2();
194  ksum2+=(tp3d-p3d).NormL2()*(tp3d-p3d).NormL2();
195  knum++;
196  } else {
197  tp3d.Set(eucl3d);
198  kt.Stop();
199  cout << "kanatani triangulation failed\n";
200  }
201 
202  p0=np0;
203  p1=np1;
204  double dist, ang;
205  st.Start();
206  if (tri.Triangulate2D(P0, P1, p0, p1, tp3d, dist, ang)==0){
207  st.Stop();
208  if (num<5){
209  cout << "2D triangulated 3D point : "<<tp3d<<endl;
210  }
211  cout << "2D euclidean dist. in 3D : "<<(tp3d-p3d).NormL2()<<"\tdist: "
212  <<dist<<"\tang: "<<ang<<endl;
213  ssum+=(tp3d-p3d).NormL2();
214  ssum2+=(tp3d-p3d).NormL2()*(tp3d-p3d).NormL2();
215  snum++;
216  } else {
217  st.Stop();
218  cout << "2D triangulation failed\n";
219  }
220  if (finished) return -1;
221 
222  }
223  }
224  if (onum>1 && knum>1 && snum>1){
225  cout << "optimal calculated "<<onum<<" times with mean error "
226  <<osum/(double)onum<<" +- "
227  << (osum2-(osum*osum)/(double)onum)/(double)(onum-1.0)
228  << "\t"<< ot.GetRealTime()/(double)onum<<" us "<<endl;
229  cout << "kanatani calculated "<<knum<<" times with mean error "
230  <<ksum/(double)knum<<" +- "
231  << (ksum2-(ksum*ksum)/(double)knum)/(double)(knum-1.0)
232  << "\t"<< kt.GetRealTime()/(double)knum<<" us "<<endl;
233  cout << "2D calculated "<<snum<<" times with mean error "
234  <<ssum/(double)snum<<" +- "
235  << (ssum2-(ssum*ssum)/(double)snum)/(double)(snum-1.0)
236  <<"\t"<< st.GetRealTime()/(double)snum<<" us "<<endl;
237  }
238 
239 
240  return 0;
241 }
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
void AddDebugLevel(const long int lv)
Definition: Debug.hh:355
void SetXYZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order XYZ.
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 Triangulate2D(PMatrix &P1, PMatrix &P2, HomgPoint2D &p1, HomgPoint2D &p2, HomgPoint3D &point3d, double &dist, double &angle)
does not use BackprojectPseudoInverse but get NormRayWorldCoo
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
Definition: Random.hh:84
Class for triangulation of 3Dpoints from 2D matches. Covariance matrix (refering to an uncertainty el...
bool DebugLevelIsSet(const long int lv) const
Definition: Debug.hh:341
int Triangulate(PMatrix &P1, PMatrix &P2, const HomgPoint2D &p1, const HomgPoint2D &p2, BIAS::Vector3< double > &point3d)
Triangulation for metric PMatrices (using C and Hinf)
void InvalidateDecomposition()
to re-Decompose_() after filling with data use this.
Definition: PMatrix.hh:499
class HomgPoint3D describes a point with 3 degrees of freedom in projective coordinates.
Definition: HomgPoint3D.hh:61
int Optimal(PMatrix &P1, PMatrix &P2, HomgPoint2D &p1, HomgPoint2D &p2, HomgPoint3D &point3d)
method from Hartley Zisserman chapter 12.5 pp 315 first uses CorrectCorrespondences() and then calls ...
double GetRealTime() const
return real time (=wall time clock) in usec JW For Win32: real-time is measured differently from user...
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
Implements a 3D rotation matrix.
Definition: RMatrixBase.hh:44
double GetNormalDistributed(const double mean, const double sigma)
on succesive calls return normal distributed random variable with mean and standard deviation sigma ...
Definition: Random.hh:71
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
class for producing random numbers from different distributions
Definition: Random.hh:51
class TimeMeasure contains functions for timing real time and cpu time.
Definition: TimeMeasure.hh:111
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
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429