IVT
StereoCalibration.cpp
Go to the documentation of this file.
1 // ****************************************************************************
2 // This file is part of the Integrating Vision Toolkit (IVT).
3 //
4 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
5 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
6 //
7 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
8 // All rights reserved.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright
17 // notice, this list of conditions and the following disclaimer in the
18 // documentation and/or other materials provided with the distribution.
19 //
20 // 3. Neither the name of the KIT nor the names of its contributors may be
21 // used to endorse or promote products derived from this software
22 // without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
25 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
28 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // ****************************************************************************
35 // ****************************************************************************
36 // Filename: StereoCalibration.cpp
37 // Author: Pedram Azad
38 // Date: 2004
39 // ****************************************************************************
40 
41 
42 // ****************************************************************************
43 // Includes
44 // ****************************************************************************
45 
46 #include <new> // for explicitly using correct new/delete operators on VC DSPs
47 
48 #include "StereoCalibration.h"
49 
50 #include "Math/Math2d.h"
51 #include "Math/Math3d.h"
52 #include "Image/ByteImage.h"
53 #include "Image/ImageProcessor.h"
55 #include "Helpers/helpers.h"
56 
57 #include <math.h>
58 #include <stdio.h>
59 
60 
61 
62 // ****************************************************************************
63 // Constructor / Destructor
64 // ****************************************************************************
65 
67 {
68  m_pLeftCalibration = new CCalibration();
69  m_pRightCalibration = new CCalibration();
70 
71  width = m_pLeftCalibration->GetCameraParameters().width;
72  height = m_pLeftCalibration->GetCameraParameters().height;
73 
74  Vec3d t = { -100, 0, 0 };
76 }
77 
79 {
80  delete m_pLeftCalibration;
81  delete m_pRightCalibration;
82 }
83 
85 {
86  m_pLeftCalibration = new CCalibration();
87  m_pRightCalibration = new CCalibration();
88 
89  m_pLeftCalibration->Set(*stereoCalibration.GetLeftCalibration());
90  m_pRightCalibration->Set(*stereoCalibration.GetRightCalibration());
91 
92  width = stereoCalibration.width;
93  height = stereoCalibration.height;
94 
97  Math3d::SetMat(F, stereoCalibration.F);
98  Math3d::SetMat(FT, stereoCalibration.FT);
99 }
100 
101 
102 // ****************************************************************************
103 // Methods
104 // ****************************************************************************
105 
106 void CStereoCalibration::Set(const CStereoCalibration &stereoCalibration)
107 {
108  width = stereoCalibration.width;
109  height = stereoCalibration.height;
110 
111  Math3d::SetMat(F, stereoCalibration.F);
112  Math3d::SetMat(FT, stereoCalibration.FT);
113 
116 
117  m_pLeftCalibration->Set(*stereoCalibration.GetLeftCalibration());
118  m_pRightCalibration->Set(*stereoCalibration.GetRightCalibration());
119 }
120 
121 void CStereoCalibration::SetDistortionParameters(float d1_left, float d2_left, float d3_left, float d4_left, float d1_right, float d2_right, float d3_right, float d4_right)
122 {
123  m_pLeftCalibration->SetDistortion(d1_left, d2_left, d3_left, d4_left);
124  m_pRightCalibration->SetDistortion(d1_right, d2_right, d3_right, d4_right);
125 }
126 
127 void CStereoCalibration::SetSingleCalibrations(const CCalibration &leftCalibration, const CCalibration &rightCalibration, bool bTransformLeftCameraToIdentity)
128 {
129  m_pLeftCalibration->Set(leftCalibration);
130  m_pRightCalibration->Set(rightCalibration);
131 
132  width = leftCalibration.GetCameraParameters().width;
133  height = leftCalibration.GetCameraParameters().height;
134 
135  if (bTransformLeftCameraToIdentity)
136  {
137  TransformLeftCameraToIdentity();
138  CalculateFundamentalMatrix();
139  }
140  else
141  {
142  Mat3d left_rotation, right_rotation;
143  Vec3d left_translation, right_translation;
144 
145  // store original transformations
146  Math3d::SetMat(left_rotation, leftCalibration.GetCameraParameters().rotation);
147  Math3d::SetMat(right_rotation, rightCalibration.GetCameraParameters().rotation);
148 
149  Math3d::SetVec(left_translation, leftCalibration.GetCameraParameters().translation);
150  Math3d::SetVec(right_translation, rightCalibration.GetCameraParameters().translation);
151 
152  // calculate epipolar geometry
153  TransformLeftCameraToIdentity();
154  CalculateFundamentalMatrix();
155 
156  // reset transformations
157  m_pLeftCalibration->SetRotation(left_rotation);
158  m_pLeftCalibration->SetTranslation(left_translation);
159 
160  m_pRightCalibration->SetRotation(right_rotation);
161  m_pRightCalibration->SetTranslation(right_translation);
162  }
163 }
164 
165 void CStereoCalibration::SetExtrinsicParameters(const Mat3d& left_rotation, const Vec3d& left_translation, const Mat3d& right_rotation, const Vec3d& right_translation, bool bTransformToIdentity)
166 {
167  // set rotation of left and right calibration
168  m_pLeftCalibration->SetRotation(left_rotation);
169  m_pLeftCalibration->SetTranslation(left_translation);
170 
171  m_pRightCalibration->SetRotation(right_rotation);
172  m_pRightCalibration->SetTranslation(right_translation);
173 
174  // transform to identy for fundemantal matrix calculation
175  TransformLeftCameraToIdentity();
176 
177  // update fundametal matrix
178  CalculateFundamentalMatrix();
179 
180  if(!bTransformToIdentity)
181  {
182  // reset transformation of left and right calibration
183  m_pLeftCalibration->SetRotation(left_rotation);
184  m_pLeftCalibration->SetTranslation(left_translation);
185 
186  m_pRightCalibration->SetRotation(right_rotation);
187  m_pRightCalibration->SetTranslation(right_translation);
188  }
189 }
190 
191 
192 void CStereoCalibration::TransformLeftCameraToIdentity()
193 {
194  Mat3d tempMat;
195  Vec3d tempVec;
196 
197  const CCalibration::CCameraParameters &cameraParametersLeft = m_pLeftCalibration->GetCameraParameters();
198  const CCalibration::CCameraParameters &cameraParametersRight = m_pRightCalibration->GetCameraParameters();
199 
200  Math3d::MulMatMat(cameraParametersRight.rotation, m_pLeftCalibration->m_rotation_inverse, tempMat);
201  Math3d::MulMatVec(tempMat, cameraParametersLeft.translation, tempVec);
202  Math3d::SubtractVecVec(cameraParametersRight.translation, tempVec, tempVec);
203 
204  m_pLeftCalibration->SetRotation(Math3d::unit_mat);
205  m_pLeftCalibration->SetTranslation(Math3d::zero_vec);
206 
207  m_pRightCalibration->SetRotation(tempMat);
208  m_pRightCalibration->SetTranslation(tempVec);
209 }
210 
211 void CStereoCalibration::CalculateFundamentalMatrix()
212 {
213  const CCalibration::CCameraParameters &left = m_pLeftCalibration->GetCameraParameters();
214  const CCalibration::CCameraParameters &right = m_pRightCalibration->GetCameraParameters();
215  const Mat3d &R = right.rotation;
216  const Vec3d &t = right.translation;
217 
218  Mat3d E = { 0, -t.z, t.y, t.z, 0, -t.x, -t.y, t.x, 0 };
219  Math3d::MulMatMat(E, R, E);
220 
221  Mat3d K1 = { left.focalLength.x, 0, left.principalPoint.x, 0, left.focalLength.y, left.principalPoint.y, 0, 0, 1 };
222  Math3d::Invert(K1, K1);
223 
224  Mat3d K2 = { right.focalLength.x, 0, right.principalPoint.x, 0, right.focalLength.y, right.principalPoint.y, 0, 0, 1 };
225  Math3d::Invert(K2, K2);
226  Math3d::Transpose(K2, K2);
227 
228  Math3d::MulMatMat(K2, E, F);
229  Math3d::MulMatMat(F, K1, F);
230 
231  Math3d::Transpose(F, FT);
232 }
233 
234 
235 void CStereoCalibration::Calculate3DPoint(const Vec2d &cameraPointLeft, const Vec2d &cameraPointRight, Vec3d &worldPoint, bool bInputImagesAreRectified, bool bUseDistortionParameters, PointPair3d *pConnectionLine)
236 {
237  Vec2d pointLeft, pointRight;
238 
239  if (bInputImagesAreRectified)
240  {
241  Math2d::ApplyHomography(rectificationHomographyLeft, cameraPointLeft, pointLeft);
242  Math2d::ApplyHomography(rectificationHomographyRight, cameraPointRight, pointRight);
243  }
244  else
245  {
246  Math2d::SetVec(pointLeft, cameraPointLeft);
247  Math2d::SetVec(pointRight, cameraPointRight);
248  }
249 
250  // calculate world coordinates of some reference point on the view line (not origin of the camera coordinate system)
251  Vec3d u, v, a, b;
252  m_pLeftCalibration->ImageToWorldCoordinates(pointLeft, u, 1, bUseDistortionParameters);
253  m_pRightCalibration->ImageToWorldCoordinates(pointRight, v, 1, bUseDistortionParameters);
254 
255  // get "starting vector" of straight line
256  Math3d::SetVec(a, m_pLeftCalibration->m_translation_inverse);
257  Math3d::SetVec(b, m_pRightCalibration->m_translation_inverse);
258 
259  // calculate direction vector of straight line
262 
263  // left straight line: x = r * u + a
264  // right straight line: x = s * v + b
265  // A x = b
266  float A00 = -u.x; float A01 = v.x;
267  float A10 = -u.y; float A11 = v.y;
268  float A20 = -u.z; float A21 = v.z;
269  float b0 = a.x - b.x;
270  float b1 = a.y - b.y;
271  float b2 = a.z - b.z;
272 
273  float ATA00 = A00 * A00 + A10 * A10 + A20 * A20;
274  float ATA10 = A01 * A00 + A11 * A10 + A21 * A20;
275  float ATA11 = A01 * A01 + A11 * A11 + A21 * A21;
276  float ATb0 = A00 * b0 + A10 * b1 + A20 * b2;
277  float ATb1 = A01 * b0 + A11 * b1 + A21 * b2;
278 
279  float L00 = sqrtf(ATA00);
280  float L10 = ATA10 / L00;
281  float L11 = sqrtf(ATA11 - L10 * L10);
282 
283  float yy0 = ATb0 / L00;
284  float yy1 = (ATb1 - L10 * yy0) / L11;
285 
286  float s = yy1 / L11;
287  float r = (yy0 - L10 * s) / L00;
288 
289  // p = (r * u + a + s * v + b) / 2
290  Math3d::SetVec(worldPoint,
291  (r * u.x + a.x + s * v.x + b.x) * 0.5f,
292  (r * u.y + a.y + s * v.y + b.y) * 0.5f,
293  (r * u.z + a.z + s * v.z + b.z) * 0.5f
294  );
295 
296  if (pConnectionLine)
297  {
298  Math3d::SetVec(pConnectionLine->p1, r * u.x + a.x, r * u.y + a.y, r * u.z + a.z);
299  Math3d::SetVec(pConnectionLine->p2, s * v.x + b.x, s * v.y + b.y, s * v.z + b.z);
300  }
301 }
302 
303 
305 {
306  Vec3d x = { pointInRightImage.x, pointInRightImage.y, 1 };
307  Math3d::MulMatVec(FT, x, l);
308 }
309 
310 void CStereoCalibration::CalculateEpipolarLineInLeftImage(const Vec2d &pointInRightImage, float &m, float &c)
311 {
312  Vec3d l;
313  CalculateEpipolarLineInLeftImage(pointInRightImage, l);
314 
315  m = -l.x / l.y;
316  c = -l.z / l.y;
317 }
318 
319 void CStereoCalibration::CalculateEpipolarLineInLeftImage(const Vec2d &pointInRightImage, PointPair2d &epipolarLine)
320 {
321  Vec3d l;
322  CalculateEpipolarLineInLeftImage(pointInRightImage, l);
323 
324  const float v1 = l.y != 0.0f ? -l.z / l.y : -1.0f;
325  const float v2 = l.y != 0.0f ? (-l.z - l.x * float(width - 1)) / l.y : -1.0f;
326  const float u1 = l.x != 0.0f ? -l.z / l.x : -1.0f;
327  const float u2 = l.x != 0.0f ? (-l.z - l.y * float(height - 1)) / l.x : -1.0f;
328 
329  if (v1 >= 0.0f && v1 <= float(height - 1))
330  Math2d::SetVec(epipolarLine.p1, 0.0f, v1);
331  else if (v2 >= 0.0f && v2 <= float(height - 1))
332  Math2d::SetVec(epipolarLine.p1, float(width - 1), v2);
333  else if (u1 >= 0.0f && u1 <= float(width - 1))
334  Math2d::SetVec(epipolarLine.p1, u1, 0.0f);
335  else if (u2 >= 0.0f && u2 <= float(width - 1))
336  Math2d::SetVec(epipolarLine.p1, u2, float(height - 1));
337 
338  if (v1 >= 0.0f && v1 <= float(height - 1) && (epipolarLine.p1.x != 0.0f || epipolarLine.p1.y != v1))
339  Math2d::SetVec(epipolarLine.p2, 0.0f, v1);
340  else if (v2 >= 0.0f && v2 <= float(height - 1) && (epipolarLine.p1.x != float(width - 1) || epipolarLine.p1.y != v2))
341  Math2d::SetVec(epipolarLine.p2, float(width - 1), v2);
342  else if (u1 >= 0.0f && u1 <= float(width - 1) && (epipolarLine.p1.x != u1 || epipolarLine.p1.y != 0.0f))
343  Math2d::SetVec(epipolarLine.p2, u1, 0.0f);
344  else if (u2 >= 0.0f && u2 <= float(width - 1) && (epipolarLine.p1.x != u2 || epipolarLine.p1.y != float(height - 1)))
345  Math2d::SetVec(epipolarLine.p2, u2, float(height - 1));
346 }
347 
348 
350 {
351  Vec3d x = { pointInLeftImage.x, pointInLeftImage.y, 1 };
352  Math3d::MulMatVec(F, x, l);
353 }
354 
355 void CStereoCalibration::CalculateEpipolarLineInRightImage(const Vec2d &pointInLeftImage, float &m, float &c)
356 {
357  Vec3d l;
358  CalculateEpipolarLineInRightImage(pointInLeftImage, l);
359 
360  m = -l.x / l.y;
361  c = -l.z / l.y;
362 }
363 
364 void CStereoCalibration::CalculateEpipolarLineInRightImage(const Vec2d &pointInLeftImage, PointPair2d &epipolarLine)
365 {
366  Vec3d l;
367  CalculateEpipolarLineInRightImage(pointInLeftImage, l);
368 
369  const float v1 = l.y != 0.0f ? -l.z / l.y : -1.0f;
370  const float v2 = l.y != 0.0f ? (-l.z - l.x * float(width - 1)) / l.y : -1.0f;
371  const float u1 = l.x != 0.0f ? -l.z / l.x : -1.0f;
372  const float u2 = l.x != 0.0f ? (-l.z - l.y * float(height - 1)) / l.x : -1.0f;
373 
374  if (v1 >= 0.0f && v1 <= float(height - 1))
375  Math2d::SetVec(epipolarLine.p1, 0.0f, v1);
376  else if (v2 >= 0.0f && v2 <= float(height - 1))
377  Math2d::SetVec(epipolarLine.p1, float(width - 1), v2);
378  else if (u1 >= 0.0f && u1 <= float(width - 1))
379  Math2d::SetVec(epipolarLine.p1, u1, 0.0f);
380  else if (u2 >= 0.0f && u2 <= float(width - 1))
381  Math2d::SetVec(epipolarLine.p1, u2, float(height - 1));
382 
383  if (v1 >= 0.0f && v1 <= float(height - 1) && (epipolarLine.p1.x != 0.0f || epipolarLine.p1.y != v1))
384  Math2d::SetVec(epipolarLine.p2, 0.0f, v1);
385  else if (v2 >= 0.0f && v2 <= float(height - 1) && (epipolarLine.p1.x != float(width - 1) || epipolarLine.p1.y != v2))
386  Math2d::SetVec(epipolarLine.p2, float(width - 1), v2);
387  else if (u1 >= 0.0f && u1 <= float(width - 1) && (epipolarLine.p1.x != u1 || epipolarLine.p1.y != 0.0f))
388  Math2d::SetVec(epipolarLine.p2, u1, 0.0f);
389  else if (u2 >= 0.0f && u2 <= float(width - 1) && (epipolarLine.p1.x != u2 || epipolarLine.p1.y != float(height - 1)))
390  Math2d::SetVec(epipolarLine.p2, u2, float(height - 1));
391 }
392 
393 
394 float CStereoCalibration::CalculateEpipolarLineInLeftImageDistance(const Vec2d &pointInLeftImage, const Vec2d &pointInRightImage)
395 {
396  Vec3d l;
397  CalculateEpipolarLineInLeftImage(pointInRightImage, l);
398 
399  const float length = sqrtf(l.x * l.x + l.y * l.y);
400  const float l1 = l.x / length;
401  const float l2 = l.y / length;
402  const float l3 = l.z / length;
403 
404  return l1 * pointInLeftImage.x + l2 * pointInLeftImage.y + l3;
405 }
406 
407 float CStereoCalibration::CalculateEpipolarLineInRightImageDistance(const Vec2d &pointInLeftImage, const Vec2d &pointInRightImage)
408 {
409  Vec3d l;
410  CalculateEpipolarLineInRightImage(pointInLeftImage, l);
411 
412  const float length = sqrtf(l.x * l.x + l.y * l.y);
413  const float l1 = l.x / length;
414  const float l2 = l.y / length;
415  const float l3 = l.z / length;
416 
417  return l1 * pointInRightImage.x + l2 * pointInRightImage.y + l3;
418 }
419 
420 
421 bool CStereoCalibration::LoadCameraParameters(const char *pCameraParameterFileName, bool bTransformLeftCameraToIdentity)
422 {
423  if (!m_pLeftCalibration->LoadCameraParameters(pCameraParameterFileName, 0))
424  return false;
425 
426  if (!m_pRightCalibration->LoadCameraParameters(pCameraParameterFileName, 1))
427  return false;
428 
429  if (bTransformLeftCameraToIdentity)
430  {
431  TransformLeftCameraToIdentity();
432  CalculateFundamentalMatrix();
433  }
434  else
435  {
436  Mat3d left_rotation, right_rotation;
437  Vec3d left_translation, right_translation;
438 
439  // store original transformations
440  Math3d::SetMat(left_rotation, m_pLeftCalibration->GetCameraParameters().rotation);
441  Math3d::SetMat(right_rotation, m_pRightCalibration->GetCameraParameters().rotation);
442 
443  Math3d::SetVec(left_translation, m_pLeftCalibration->GetCameraParameters().translation);
444  Math3d::SetVec(right_translation, m_pRightCalibration->GetCameraParameters().translation);
445 
446  // calculate epipolar geometry
447  TransformLeftCameraToIdentity();
448  CalculateFundamentalMatrix();
449 
450  // reset transformations
451  m_pLeftCalibration->SetRotation(left_rotation);
452  m_pLeftCalibration->SetTranslation(left_translation);
453 
454  m_pRightCalibration->SetRotation(right_rotation);
455  m_pRightCalibration->SetTranslation(right_translation);
456  }
457 
458  int nCameraCount = 0;
459 
460  FILE* f = fopen(pCameraParameterFileName, "r");
461  if(!f)
462  return false;
463 
464  if (fscanf(f, "%d", &nCameraCount) != 1 || nCameraCount != 2)
465  {
466  fclose(f);
467  return false;
468  }
469 
470  float skip_value;
471 
472  // skip values (27 for each camera, 2 * 8 for stereo quads)
473  for (int i = 0; i < 2 * 27 + 16; i++)
474  if (fscanf(f, "%f", &skip_value) != 1)
475  {
476  fclose(f);
477  return false;
478  }
479 
480  // read rectification parameters
481  if (fscanf(f, "%f", &rectificationHomographyLeft.r1) != 1) { fclose(f); return false; }
482  if (fscanf(f, "%f", &rectificationHomographyLeft.r2) != 1) { fclose(f); return false; }
483  if (fscanf(f, "%f", &rectificationHomographyLeft.r3) != 1) { fclose(f); return false; }
484  if (fscanf(f, "%f", &rectificationHomographyLeft.r4) != 1) { fclose(f); return false; }
485  if (fscanf(f, "%f", &rectificationHomographyLeft.r5) != 1) { fclose(f); return false; }
486  if (fscanf(f, "%f", &rectificationHomographyLeft.r6) != 1) { fclose(f); return false; }
487  if (fscanf(f, "%f", &rectificationHomographyLeft.r7) != 1) { fclose(f); return false; }
488  if (fscanf(f, "%f", &rectificationHomographyLeft.r8) != 1) { fclose(f); return false; }
489  if (fscanf(f, "%f", &rectificationHomographyLeft.r9) != 1) { fclose(f); return false; }
490 
491  if (fscanf(f, "%f", &rectificationHomographyRight.r1) != 1) { fclose(f); return false; }
492  if (fscanf(f, "%f", &rectificationHomographyRight.r2) != 1) { fclose(f); return false; }
493  if (fscanf(f, "%f", &rectificationHomographyRight.r3) != 1) { fclose(f); return false; }
494  if (fscanf(f, "%f", &rectificationHomographyRight.r4) != 1) { fclose(f); return false; }
495  if (fscanf(f, "%f", &rectificationHomographyRight.r5) != 1) { fclose(f); return false; }
496  if (fscanf(f, "%f", &rectificationHomographyRight.r6) != 1) { fclose(f); return false; }
497  if (fscanf(f, "%f", &rectificationHomographyRight.r7) != 1) { fclose(f); return false; }
498  if (fscanf(f, "%f", &rectificationHomographyRight.r8) != 1) { fclose(f); return false; }
499  if (fscanf(f, "%f", &rectificationHomographyRight.r9) != 1) { fclose(f); return false; }
500 
501  fclose(f);
502 
503  width = m_pLeftCalibration->GetCameraParameters().width;
504  height = m_pLeftCalibration->GetCameraParameters().height;
505 
506  return true;
507 }
508 
509 bool CStereoCalibration::SaveCameraParameters(const char *pFileName) const
510 {
511  FILE *f = fopen(pFileName, "w");
512  if (!f)
513  return false;
514 
515  fprintf(f, "2\n\n");
516 
517  const CCalibration::CCameraParameters &cameraParametersLeft = m_pLeftCalibration->GetCameraParameters();
518  const CCalibration::CCameraParameters &cameraParametersRight = m_pRightCalibration->GetCameraParameters();
519 
520  // write camera parameters of left camera
521  float cx = cameraParametersLeft.principalPoint.x;
522  float cy = cameraParametersLeft.principalPoint.y;
523  float fx = cameraParametersLeft.focalLength.x;
524  float fy = cameraParametersLeft.focalLength.y;
525  float d1 = cameraParametersLeft.distortion[0];
526  float d2 = cameraParametersLeft.distortion[1];
527  float d3 = cameraParametersLeft.distortion[2];
528  float d4 = cameraParametersLeft.distortion[3];
529 
530  fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f ", float(cameraParametersLeft.width), float(cameraParametersLeft.height), fx, 0.0f, cx, 0.0f, fy, cy, 0.0f, 0.0f, 1.0f);
531  fprintf(f, "%.10f %.10f %.10f %.10f ", d1, d2, d3, d4);
532  fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f ", cameraParametersLeft.rotation.r1, cameraParametersLeft.rotation.r2, cameraParametersLeft.rotation.r3, cameraParametersLeft.rotation.r4, cameraParametersLeft.rotation.r5, cameraParametersLeft.rotation.r6, cameraParametersLeft.rotation.r7, cameraParametersLeft.rotation.r8, cameraParametersLeft.rotation.r9);
533  fprintf(f, "%.10f %.10f %.10f\n\n", cameraParametersLeft.translation.x, cameraParametersLeft.translation.y, cameraParametersLeft.translation.z);
534 
535  // write camera parameters of right camera
536  cx = cameraParametersRight.principalPoint.x;
537  cy = cameraParametersRight.principalPoint.y;
538  fx = cameraParametersRight.focalLength.x;
539  fy = cameraParametersRight.focalLength.y;
540  d1 = cameraParametersRight.distortion[0];
541  d2 = cameraParametersRight.distortion[1];
542  d3 = cameraParametersRight.distortion[2];
543  d4 = cameraParametersRight.distortion[3];
544 
545  fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f ", float(cameraParametersLeft.width), float(cameraParametersLeft.height), fx, 0.0f, cx, 0.0f, fy, cy, 0.0f, 0.0f, 1.0f);
546  fprintf(f, "%.10f %.10f %.10f %.10f ", d1, d2, d3, d4);
547  fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f ", cameraParametersRight.rotation.r1, cameraParametersRight.rotation.r2, cameraParametersRight.rotation.r3, cameraParametersRight.rotation.r4, cameraParametersRight.rotation.r5, cameraParametersRight.rotation.r6, cameraParametersRight.rotation.r7, cameraParametersRight.rotation.r8, cameraParametersRight.rotation.r9);
548  fprintf(f, "%.10f %.10f %.10f\n\n", cameraParametersRight.translation.x, cameraParametersRight.translation.y, cameraParametersRight.translation.z);
549 
550  // skipped values of OpenCV format
551  fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f\n", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
552  fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f\n", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
553 
554  // write rectification homography of left camera
555  fprintf(f, "%.10f ", rectificationHomographyLeft.r1);
556  fprintf(f, "%.10f ", rectificationHomographyLeft.r2);
557  fprintf(f, "%.10f ", rectificationHomographyLeft.r3);
558  fprintf(f, "%.10f ", rectificationHomographyLeft.r4);
559  fprintf(f, "%.10f ", rectificationHomographyLeft.r5);
560  fprintf(f, "%.10f ", rectificationHomographyLeft.r6);
561  fprintf(f, "%.10f ", rectificationHomographyLeft.r7);
562  fprintf(f, "%.10f ", rectificationHomographyLeft.r8);
563  fprintf(f, "%.10f ", rectificationHomographyLeft.r9);
564  fprintf(f, "\n");
565 
566  // write rectification homography of right camera
567  fprintf(f, "%.10f ", rectificationHomographyRight.r1);
568  fprintf(f, "%.10f ", rectificationHomographyRight.r2);
569  fprintf(f, "%.10f ", rectificationHomographyRight.r3);
570  fprintf(f, "%.10f ", rectificationHomographyRight.r4);
571  fprintf(f, "%.10f ", rectificationHomographyRight.r5);
572  fprintf(f, "%.10f ", rectificationHomographyRight.r6);
573  fprintf(f, "%.10f ", rectificationHomographyRight.r7);
574  fprintf(f, "%.10f ", rectificationHomographyRight.r8);
575  fprintf(f, "%.10f ", rectificationHomographyRight.r9);
576  fprintf(f, "\n");
577 
578  fclose(f);
579 
580  return true;
581 }
582 
584 {
585  Mat3d K, H;
586 
587  // left camera
589  m_pLeftCalibration->GetCalibrationMatrix(K);
590  Math3d::MulMatMat(H, K, K);
591  Math3d::MulMatMat(K, m_pLeftCalibration->GetCameraParameters().rotation, P1Left);
592  Math3d::MulMatVec(K, m_pLeftCalibration->GetCameraParameters().translation, p2Left);
593 
594  // right camera
596  m_pRightCalibration->GetCalibrationMatrix(K);
597  Math3d::MulMatMat(H, K, K);
598  Math3d::MulMatMat(K, m_pRightCalibration->GetCameraParameters().rotation, P1Right);
599  Math3d::MulMatVec(K, m_pRightCalibration->GetCameraParameters().translation, p2Right);
600 }
~CStereoCalibration()
The destructor.
void Invert(const Mat3d &matrix, Mat3d &result)
Definition: Math3d.cpp:657
const CCalibration * GetRightCalibration() const
Access to the instance of CCalibration for the camera model of the right camera.
void ApplyHomography(const Mat3d &A, const Vec2d &p, Vec2d &result)
Definition: Math2d.cpp:253
bool SaveCameraParameters(const char *pCameraParameterFileName) const
Writes the parameters of the camera model to camera parameter file.
Data structure for the representation of a 2D vector.
Definition: Math2d.h:82
void CalculateEpipolarLineInRightImage(const Vec2d &pointInLeftImage, Vec3d &l)
Given an image point in the left image, computes the corresponding epipolar line in the right image...
float y
Definition: Math3d.h:75
void Calculate3DPoint(const Vec2d &cameraPointLeft, const Vec2d &cameraPointRight, Vec3d &worldPoint, bool bInputImagesAreRectified, bool bUseDistortionParameters=true, PointPair3d *pConnectionLine=0)
Computes a 3D point, given a point correspondence in both images, by performing stereo triangulation...
float r4
Definition: Math3d.h:95
float r3
Definition: Math3d.h:95
Vec3d m_translation_inverse
Translation vector of the inverted extrinsic transformation.
Definition: Calibration.h:454
bool LoadCameraParameters(const char *pCameraParameterFileName, bool bTransformLeftCameraToIdentity=true)
Initializes the stereo camera model, given a file path to a stereo camera parameter file...
void ImageToWorldCoordinates(const Vec2d &imagePoint, Vec3d &worldPoint, float zc=1.0f, bool bUseDistortionParameters=true) const
Transforms 2D image coordinates to 3D world coordinates.
float x
Definition: Math2d.h:84
float r1
Definition: Math3d.h:95
float CalculateEpipolarLineInLeftImageDistance(const Vec2d &pointInLeftImage, const Vec2d &pointInRightImage)
Given a point correspondence, computes the distance from the epipolar line in the left image...
float r7
Definition: Math3d.h:95
void SetSingleCalibrations(const CCalibration &leftCalibration, const CCalibration &rightCalibration, bool bTransformLeftCameraToIdentity=false)
Initializes the stereo camera model, given two instances of CCalibration.
float x
Definition: Math3d.h:75
float r2
Definition: Math3d.h:95
void SetDistortionParameters(float d1_left, float d2_left, float d3_left, float d4_left, float d1_right, float d2_right, float d3_right, float d4_right)
Sets the distortion parameters of the distortion models of both cameras.
Vec3d p1
Definition: Structs.h:79
const Mat3d unit_mat
Definition: Math3d.cpp:60
const CCameraParameters & GetCameraParameters() const
Gives access to the camera parameters.
Definition: Calibration.h:268
float r8
Definition: Math3d.h:95
CStereoCalibration()
The default constructor.
bool LoadCameraParameters(const char *pCameraParameterFileName, int nCamera=0, bool bSetExtrinsicToIdentity=false)
Initializes the camera model, given a file path to a camera parameter file.
void SetExtrinsicParameters(const Mat3d &left_rotation, const Vec3d &left_translation, const Mat3d &right_rotation, const Vec3d &right_translation, bool bTransformLeftCameraToIdentity=false)
Sets the extrinsic parameters of both cameras.
void SubtractVecVec(const Vec3d &vector1, const Vec3d &vector2, Vec3d &result)
Definition: Math3d.cpp:522
float y
Definition: Math2d.h:84
void MulMatMat(const Mat3d &matrix1, const Mat3d &matrix2, Mat3d &result)
Definition: Math3d.cpp:444
const CCalibration * GetLeftCalibration() const
Access to the instance of CCalibration for the camera model of the left camera.
const Vec3d zero_vec
Definition: Math3d.cpp:59
void Set(const CStereoCalibration &stereoCalibration)
Initializes the stereo camera model, given an instance of CStereoCalibration.
void CalculateEpipolarLineInLeftImage(const Vec2d &pointInRightImage, Vec3d &l)
Given an image point in the right image, computes the corresponding epipolar line in the left image...
Data structure for the representation of a 3D vector.
Definition: Math3d.h:73
void Transpose(const Mat3d &matrix, Mat3d &result)
Definition: Math3d.cpp:635
void MulMatVec(const Mat3d &matrix, const Vec3d &vec, Vec3d &result)
Definition: Math3d.cpp:422
void Set(const CCalibration &calibration)
Initializes the camera model, given an instance of CCalibration.
void SetDistortion(float d1, float d2, float d3, float d4)
Sets the distortion parameters of the distortion model.
void SetMat(Mat3d &matrix, float r1, float r2, float r3, float r4, float r5, float r6, float r7, float r8, float r9)
Definition: Math3d.cpp:257
Vec2d p1
Definition: Structs.h:73
Camera model parameters and functions for a single camera.
Definition: Calibration.h:125
Vec3d p2
Definition: Structs.h:80
float z
Definition: Math3d.h:75
float CalculateEpipolarLineInRightImageDistance(const Vec2d &pointInLeftImage, const Vec2d &pointInRightImage)
Given a point correspondence, computes the distance from the epipolar line in the right image...
Mat3d rectificationHomographyRight
The homography for the rectification mapping of the right image.
float r6
Definition: Math3d.h:95
void SubtractFromVec(Vec3d &vec, const Vec3d &vectorToSubtract)
Definition: Math3d.cpp:488
void SetRotation(const Mat3d &R)
Sets the extrinsic parameter R (rotation matrix).
Mat3d m_rotation_inverse
Rotation matrix of the inverted extrinsic transformation.
Definition: Calibration.h:443
int height
The height of the images of the stereo camera system in pixels.
Data structure for the representation of a 3x3 matrix.
Definition: Math3d.h:93
void SetTranslation(const Vec3d &t)
Sets the extrinsic parameter t (translation vector).
void SetVec(Vec2d &vec, float x, float y)
Definition: Math2d.cpp:68
float r9
Definition: Math3d.h:95
void GetProjectionMatricesForRectifiedImages(Mat3d &P1Left, Vec3d &p2Left, Mat3d &P1Right, Vec3d &p2Right) const
Sets up the projection matrix P for the rectified images.
Camera model and functions for a stereo camera system.
void GetCalibrationMatrix(Mat3d &K) const
Sets up the calibration matrix K.
Definition: Calibration.cpp:91
float r5
Definition: Math3d.h:95
void SetVec(Vec3d &vec, float x, float y, float z)
Definition: Math3d.cpp:243
Vec2d p2
Definition: Structs.h:74
Mat3d rectificationHomographyLeft
The homography for the rectification mapping of the right image.
int width
The width of the images of the stereo camera system in pixels.
Struct containing all parameters of the camera model.
Definition: Calibration.h:133