Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleAutoCalib.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 /**
27  @example ExampleAutoCalib.cpp
28  @relates FMatrix, RMatrix , EMatrix, FMatrixEstimation, PMatrixEstimation
29  @brief Example for self calibration
30  @ingroup g_examples
31  @author MIP
32 */
33 
34 
35 #include "Geometry/FMatrix.hh"
36 #include "Geometry/RMatrix.hh"
37 #include "Geometry/EMatrix.hh"
38 #include "Base/Geometry/KMatrix.hh"
39 #include "../FMatrixEstimation.hh"
40 #include "../PMatrixEstimation.hh"
41 #include "../PMatrixLinear.hh"
42 #include "../Triangulation.hh"
43 #include "../../Base/Math/Random.hh"
44 #include "Utils/ThreeDOut.hh"
45 #include "Utils/Param.hh"
46 
47 using namespace BIAS;
48 using namespace std;
49 
50 // ---------------------------------------------------------------------------
51 int main(int argc, char *argv[]) {
52 
53  Param *p = new Param();
54  p->AddParamInt("imgWidth", "image width", 400);
55  p->AddParamInt("imgHeight", "image height", 400);
56  p->AddParamDouble("focalLength", "Focal length of camera", 400.0);
57  p->AddParamDouble("princPointX", "x-coordinate of principle point", 199.5);
58  p->AddParamDouble("princPointY", "y_coordinate of principle point", 199.5);
59 
60  p->AddParamDouble("rotationX", "Rotation of second cam in x-direction", 12.0);
61  p->AddParamDouble("rotationY", "Rotation of second cam in y-direction", 20.0);
62  p->AddParamDouble("rotationZ", "Rotation of second cam in z-direction", -2.0);
63  p->AddParamDouble("transX", "Translation of second cam in x-direction", -1.0/sqrt(2.0));
64  p->AddParamDouble("transY", "Translation of second cam in y-direction", 1.0 /sqrt(2.0));
65  p->AddParamDouble("transZ", "Translation of second cam in z-direction", 0.0);
66 
67  p->AddParamDouble("noiseUpper", "Upper bound for noise on points in pixels", 0.0);
68  p->AddParamDouble("noiseLower", "Lower bound for noise on points in pixels", -0.0);
69 
70  if (argc == 2) {
71  int res = p->ReadParameter(string(argv[1]));
72  if (res != 0) {
73  cout << "Could not read parameter file, using default parameters instead " <<res << endl;
74  }
75  }
76 
77  if (argc == 2) {
78  int res = p->WriteParameter(string(argv[1]));
79  if (res != 0) {
80  BIASERR("Error could not write parameter file to: " << argv[1] << res);
81  }
82  } else {
83  int res = p->WriteParameter("autoCalib.param");
84  if (res != 0) {
85  BIASERR("Error could not write parameter file to: " << "autoCalib.param" << res);
86  }
87  }
88  // write the parameters used to console
89  p->ShowData();
90 
91  BIAS::FMatrix F, TheoF;
92  std::vector<FMatrix> vecF;
93  BIAS::PMatrix P1, P2, P1Comp, P2Comp;
94  BIAS::Random Randomizer;
95 
96  BIAS::RMatrix R1, R2;
98  BIAS::Vector3<double> C1, C2;
99 
100  // set rotation matrices
101  R1.SetIdentity();
102  R2.SetXYZ((*p->GetParamDouble("rotationX"))*M_PI/180.0, (*p->GetParamDouble("rotationY"))*M_PI
103  /180.0, (*p->GetParamDouble("rotationZ"))*M_PI/180.0);
104 
105  // set image size
106  int width = *p->GetParamInt("imgWidth");
107  int height =*p->GetParamInt("imgHeight") ;
108  double focalLength = *p->GetParamDouble("focalLength");
109 
110  // camera center coordiantes
111  C1[0] = 0.0;
112  C1[1] = 0.0;
113  C1[2] = 0.0;
114 
115  C2[0] = *p->GetParamDouble("transX");
116  C2[1] = *p->GetParamDouble("transY");
117  // C2[0] = -1.0;
118  // C2[1] = 0.0;
119  C2[2] = *p->GetParamDouble("transZ");
120 
121  // camera matrix for both cameras
122  K.SetFx(focalLength);
123  K.SetFy(focalLength);
124  // in image coordinates
125  K.SetHx(*p->GetParamDouble("princPointX"));
126  K.SetHy(*p->GetParamDouble("princPointY"));
127  K.SetSkew(0.0);
128 
129  K[2][2] = 1;
130 
131  // combine camera matrix, rotation matrix and camera center to projection matrices
132  P1.Compose(K, R1, C1);
133  P2.Compose(K, R2, C2);
134 
135  cout << "R1 " << R1 << endl;
136  cout << "R2 " << R2 << endl;
137  cout << "C1 " << C1 << endl;
138  cout << "C2 " << C2 << endl;
139  cout << "K " << K << endl;
140  cout << "P1 " << P1 << endl;
141  cout << "P2 " << P2 << endl;
142 
143  // compute randomized correspondences
144  // later compute more and put them on planes, check angle of reconstruction
145  vector<HomgPoint3D> points, pointsComp;
146  vector<HomgPoint2D> p1, p2;
147 
148  int numPoints = 50;
149 
150  for (int p=0; p<numPoints; p++) {
151  points.push_back(HomgPoint3D(Randomizer.GetUniformDistributed(-1.0, 1.0),
152  Randomizer.GetUniformDistributed(-1.0, 1.0), Randomizer.GetUniformDistributed(3.0, 5.0)));
153  cout << "NO. " << points[p] << endl;
154  p1.push_back(P1 * points[p]);
155  p1[p].Homogenize();
156  // cout << "No. " << p << " : "<< p1[p][0] << " " << p1[p][1] << endl;
157  p2.push_back(P2 * points[p]);
158  p2[p].Homogenize();
159  }
160 
161  // add noise to points
162  for (int i = 0; i < numPoints; i++) {
163  (p1[i])[0] += Randomizer.GetUniformDistributed( *p->GetParamDouble("noiseLower"),
164  *p->GetParamDouble("noiseUpper"));
165  (p1[i])[1] += Randomizer.GetUniformDistributed( *p->GetParamDouble("noiseLower"),
166  *p->GetParamDouble("noiseUpper"));
167  (p2[i])[0] += Randomizer.GetUniformDistributed( *p->GetParamDouble("noiseLower"),
168  *p->GetParamDouble("noiseUpper"));
169  (p2[i])[1] += Randomizer.GetUniformDistributed( *p->GetParamDouble("noiseLower"),
170  *p->GetParamDouble("noiseUpper"));
171  }
172 
173  // compute points on line with right angle - are not used for eight point algorithm
174  // int numPointsOnLines = 100;
175  // vector<HomgPoint3D> line1, line2, line3, line1Comp, line2Comp, line3Comp;
176  // vector<HomgPoint2D> l1P1, l1P2, l2P1, l2P2, l3P1, l3P2;
177  // double randLambda = 0.0;
178  // for (int i = 0; i < numPointsOnLines; i++) {
179  // randLambda = Randomizer.GetUniformDistributed(-2.0, 2.0);
180  // line1.push_back(HomgPoint3D(-1.0 * randLambda, 0.0 * randLambda, 8.0,
181  // 1.0));
182  // l1P1.push_back(P1 * line1[i]);
183  // l1P1[i].Homogenize();
184  // l1P2.push_back(P2 * line1[i]);
185  // l1P2[i].Homogenize();
186  // randLambda = Randomizer.GetUniformDistributed(-2.0, 2.0);
187  // line2.push_back(HomgPoint3D(0.0 * randLambda, -1.0 * randLambda, 8.0,
188  // 1.0));
189  // l2P1.push_back(P1 * line2[i]);
190  // l2P1[i].Homogenize();
191  // l2P2.push_back(P2 * line2[i]);
192  // l2P2[i].Homogenize();
193  //
194  // randLambda = Randomizer.GetUniformDistributed(0.0, 8.0);
195  // line3.push_back(HomgPoint3D(0.0 * randLambda, 0.0 * randLambda, randLambda * 1.0,
196  // 1.0));
197  // l3P1.push_back(P1 * line3[i]);
198  // l3P1[i].Homogenize();
199  // l3P2.push_back(P2 * line3[i]);
200  // l3P2[i].Homogenize();
201  // }
202 
203  // Compute FMatrix from correspondences
204  bool NormalizeHartley = true;
205  FMatrixEstimation FEstimator(NormalizeHartley);
206  // vector containing FMatrices
207  vecF.resize(1);
208  vecF.clear();
209  FEstimator.EightPoint(F, p1, p2);
210 
211  // true fmatrix
212  FMatrix F_gt;
213  F_gt.ComputeFromPMatrices(P1, P2);
214  cout << "True F matrix ----------- residual error " << F_gt.GetResidualError(p1, p2) << endl;
215  cout << "Estimated F matrix ------ residual error " << F.GetResidualError(p1, p2) << endl;
216 
217  // use AutoCalib function to determine focal length and both projection matrices
218  PMatrixEstimation pEstimator;
219  int res = pEstimator.AutoCalib(F, width, height, p1, p2, P1Comp, P2Comp);
220  if (res != 0) {
221  BIASERR("Couldn't determine f, P1 and P2" << res);
222  return -1;
223  }
224 
225  // cout results
226  cout << "Results of AutoCalib: (true angle of view " << atan(width/(2.0*focalLength)) *180.0/M_PI
227  << ")" << endl;
228  cout << "P1 " << P1Comp << endl;
229  cout << "P2 " << P2Comp << endl;
230  cout << "Resuting Kmatrix " << P2Comp.GetK() << endl;
231  cout << "Resulting C vectors " << P1Comp.GetC() <<" "<< P2Comp.GetC() <<endl;
232  cout << "Resulting Rmatrix " << P2Comp.GetR() << endl;
233 
234  RMatrix REst;
235  REst = (RMatrix) P2Comp.GetR();
236  double phiX, phiY, phiZ;
237  REst.GetRotationAnglesXYZ(phiX, phiY, phiZ);
238  cout << "Rotation angles " << phiX*180.0/M_PI << " " << phiY*180.0/M_PI << " " << phiZ*180.0/M_PI
239  << endl;
240 
241  cout << "ERRORS " << endl;
242  cout << "Focal length " << (P2Comp.GetK()).GetFx() << endl;
243  cout << "Diff P2 " << P2Comp - P2 << endl;
244 
245  // triangulate using the new projection matrices - are for example lines still lines?
246  Triangulation triangulator;
247  Vector3<double> tempPoint;
248  for (int i = 0; i < numPoints; i++) {
249  triangulator.Triangulate(P1Comp, P2Comp, p1[i], p2[i], tempPoint);
250  pointsComp.push_back(HomgPoint3D(tempPoint));
251  }
252  // triangulate lines
253 /*
254  for (int i = 0; i < numPointsOnLines; i++) {
255  triangulator.Triangulate(P1Comp, P2Comp, l1P1[i], l1P2[i], tempPoint);
256  line1Comp.push_back(HomgPoint3D(tempPoint));
257  triangulator.Triangulate(P1Comp, P2Comp, l2P1[i], l2P2[i], tempPoint);
258  line2Comp.push_back(HomgPoint3D(tempPoint));
259  triangulator.Triangulate(P1Comp, P2Comp, l3P1[i], l3P2[i], tempPoint);
260  line3Comp.push_back(HomgPoint3D(tempPoint));
261  }
262 */
263  ThreeDOutParameters param3DO;
264  param3DO.CameraStyle = PyramidMesh;
265  param3DO.PointStyle = Box;
266  param3DO.PointSize = 0.1;
267  param3DO.LineStyle = Solid;
268  param3DO.DrawUncertaintyEllipsoids = false;
269  ThreeDOut threeDOut(param3DO);
270 
271  for (int i = 0; i < numPoints; i++) {
272  threeDOut.AddPoint(points[i], RGBAuc(0, 0, 255, 127));
273  }
274 
275  for (int i = 0; i < numPoints; i++) {
276  threeDOut.AddPoint(pointsComp[i], RGBAuc(255, 0, 0, 127));
277  }
278  // for (int i = 0; i < numPointsOnLines; i++) {
279  // threeDOut.AddPoint(line1[i], RGBAuc(0, 255, 255, 127));
280  // threeDOut.AddPoint(line2[i], RGBAuc(255, 255, 255, 127));
281  // threeDOut.AddPoint(line3[i], RGBAuc(255, 255, 255, 127));
282  // }
283  //
284  // for (int i = 0; i < numPointsOnLines; i++) {
285  // threeDOut.AddPoint(line1Comp[i], RGBAuc(255, 255, 0, 127));
286  // threeDOut.AddPoint(line2Comp[i], RGBAuc(255, 0, 255, 127));
287  // threeDOut.AddPoint(line3Comp[i], RGBAuc(255, 0, 255, 127));
288  // }
289 
290  threeDOut.AddPMatrix(P1, 400, 400, RGBAuc_WHITE_OPAQUE, 0.1);
291  threeDOut.AddPMatrix(P2, 400, 400, RGBAuc(255, 0, 0, 127), 0.1);
292  threeDOut.AddPMatrix(P1Comp, 400, 400, RGBAuc(0, 255, 255, 127), 0.1);
293  threeDOut.AddPMatrix(P2Comp, 400, 400, RGBAuc(255, 0, 255, 127), 0.1);
294  Vector3<double> start(0.0, 0.0, 0.0);
295  Vector3<double> end(1.0, 0.0, 0.0);
296 
297  threeDOut.AddLine(start, end, RGBAuc(255, 0, 0, 127));
298  end.Set(0.0, 1.0, 0.0);
299  threeDOut.AddLine(start, end, RGBAuc(0, 255, 0, 127));
300  end.Set(0.0, 0.0, 1.0);
301  threeDOut.AddLine(start, end, RGBAuc(0, 0, 255, 127));
302  threeDOut.VRMLOut("test.wrl");
303  // threeDOut.Dump();
304 
305  return 0;
306 }
double * GetParamDouble(const std::string &name) const
Definition: Param.cpp:665
void SetXYZ(ROTATION_MATRIX_TYPE PhiX, ROTATION_MATRIX_TYPE PhiY, ROTATION_MATRIX_TYPE PhiZ)
Set Euler angles (in rad) in order XYZ.
int AutoCalib(const BIAS::FMatrix &F, const int width, const int height, const std::vector< BIAS::HomgPoint2D > &p1, const std::vector< BIAS::HomgPoint2D > &p2, BIAS::PMatrix &P1, BIAS::PMatrix &P2)
given an FMatrix, width and height of the images, and the 2D-correspondences of two images...
Unified output of 3D entities via OpenGL or VRML.
Definition: ThreeDOut.hh:349
double * AddParamDouble(const std::string &name, const std::string &help, double deflt=0.0, double min=-DBL_MAX, double max=DBL_MAX, char cmdshort=0, int Group=GRP_NOSHOW)
Definition: Param.cpp:351
int ReadParameter(const std::string &filename)
read values for parameters from file
Definition: Param.cpp:1219
configuration struct for drawing styles of various 3d objects
Definition: ThreeDOut.hh:309
void SetSkew(const KMATRIX_TYPE &val)
Definition: KMatrix.cpp:81
int GetR(Matrix3x3< double > &R)
Definition: PMatrix.cpp:204
double GetUniformDistributed(const double min, const double max)
on succesive calls return uniform distributed random variable between min and max ...
Definition: Random.hh:84
CameraDrawingStyle CameraStyle
Definition: ThreeDOut.hh:313
Class for triangulation of 3Dpoints from 2D matches. Covariance matrix (refering to an uncertainty el...
3D rotation matrix
Definition: RMatrix.hh:49
double GetResidualError(const std::vector< BIAS::HomgPoint2D > &p1, const std::vector< BIAS::HomgPoint2D > &p2)
returns residual error as in Zisserman p.
Definition: FMatrix.cpp:148
int WriteParameter(const std::string &filename)
store complete set of parameter in file if write_comments is set, alo the help strings are written to...
Definition: Param.cpp:1531
class representing a Fundamental matrix
Definition: FMatrix.hh:46
int Triangulate(PMatrix &P1, PMatrix &P2, const HomgPoint2D &p1, const HomgPoint2D &p2, BIAS::Vector3< double > &point3d)
Triangulation for metric PMatrices (using C and Hinf)
int * GetParamInt(const std::string &name) const
Definition: Param.cpp:618
functions for estimating a fundamental matrix (FMatrix) given a set of 2d-2d correspondences (no outl...
LineDrawingStyle LineStyle
Definition: ThreeDOut.hh:314
void ComputeFromPMatrices(BIAS::PMatrix &P1, BIAS::PMatrix &P2)
computes an F matrix from two cameras (defined by arbitrary P matrices, not only metric ones) ...
Definition: FMatrix.cpp:38
BIAS::Vector4< unsigned char > RGBAuc
Definition: RGBA.hh:47
compute standard P1/P2 from F.
void SetFx(const KMATRIX_TYPE &val)
Definition: KMatrix.cpp:75
int GetC(Vector3< double > &C)
computes translation vector origin world coo -&gt; origin camera coo (center), uses decomposition, which is cached
Definition: PMatrix.cpp:165
This class Param provides generic support for parameters.
Definition: Param.hh:231
int GetRotationAnglesXYZ(double &PhiX, double &PhiY, double &PhiZ) const
Get Euler angles for this rotation matrix in order XYZ.
void SetHy(const KMATRIX_TYPE &val)
Definition: KMatrix.cpp:87
void SetFy(const KMATRIX_TYPE &val)
Definition: KMatrix.cpp:78
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
Definition: KMatrix.hh:48
int * AddParamInt(const std::string &name, const std::string &help, int deflt=0, int min=std::numeric_limits< int >::min(), int max=std::numeric_limits< int >::max(), char cmdshort=0, int Group=GRP_NOSHOW)
For all adding routines:
Definition: Param.cpp:276
void ShowData(std::ostream &os=std::cout, int grp=GRP_ALL, bool showenhanced=true)
print all data in group grp including current values to os if grp = GRP_ALL, print all values if show...
Definition: Param.cpp:121
describes a projective 3D -&gt; 2D mapping in homogenous coordinates
Definition: PMatrix.hh:88
PointDrawingStyle PointStyle
Definition: ThreeDOut.hh:312
void SetHx(const KMATRIX_TYPE &val)
Definition: KMatrix.cpp:84
class for producing random numbers from different distributions
Definition: Random.hh:51
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
class BIASGeometryBase_EXPORT HomgPoint3D
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...
Definition: Matrix3x3.hh:429
int GetK(KMatrix &K)
calibration matrix
Definition: PMatrix.cpp:220